blob: 4caf4eab6bd96e7d9d12f95e54633136f12552c8 [file] [log] [blame]
Patrick Ventureef3aead2018-09-12 08:53:29 -07001#pragma once
2
Patrick Ventureaceb4ba2018-09-27 14:50:37 -07003#include <blobs-ipmid/blobs.hpp>
Patrick Ventureef3aead2018-09-12 08:53:29 -07004#include <ctime>
William A. Kennington IIIacebece2019-02-07 15:15:44 -08005#include <ipmid/oemrouter.hpp>
Patrick Ventureef3aead2018-09-12 08:53:29 -07006#include <memory>
7#include <string>
8#include <unordered_map>
9#include <vector>
10
11namespace blobs
12{
13
Patrick Venture86c87f52019-02-01 14:44:15 -080014/* The maximum read size.
15 * NOTE: Once this can be dynamically determined, we'll switch to that method.
16 * Having this in a header allows it to used cleanly for now.
17 */
18const int crcSize = sizeof(uint16_t);
19const int btReplyHdrLen = 5;
20const int btTransportLength = 64;
21const uint32_t maximumReadSize =
22 btTransportLength - (btReplyHdrLen + oem::groupMagicSize + crcSize);
23
Patrick Ventureef3aead2018-09-12 08:53:29 -070024struct SessionInfo
25{
26 SessionInfo() = default;
27 SessionInfo(const std::string& path, GenericBlobInterface* handler,
28 uint16_t flags) :
29 blobId(path),
30 handler(handler), flags(flags)
31 {
32 }
33 ~SessionInfo() = default;
34
35 std::string blobId;
36 GenericBlobInterface* handler;
37 uint16_t flags;
38};
39
40class ManagerInterface
41{
42 public:
43 virtual ~ManagerInterface() = default;
44
45 virtual bool
46 registerHandler(std::unique_ptr<GenericBlobInterface> handler) = 0;
47
48 virtual uint32_t buildBlobList() = 0;
49
50 virtual std::string getBlobId(uint32_t index) = 0;
51
52 virtual bool open(uint16_t flags, const std::string& path,
53 uint16_t* session) = 0;
54
55 virtual bool stat(const std::string& path, struct BlobMeta* meta) = 0;
56
57 virtual bool stat(uint16_t session, struct BlobMeta* meta) = 0;
58
59 virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0;
60
61 virtual bool close(uint16_t session) = 0;
62
63 virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset,
64 uint32_t requestedSize) = 0;
65
66 virtual bool write(uint16_t session, uint32_t offset,
67 const std::vector<uint8_t>& data) = 0;
68
69 virtual bool deleteBlob(const std::string& path) = 0;
Patrick Venture5c4b17b2018-10-04 10:32:22 -070070
71 virtual bool writeMeta(uint16_t session, uint32_t offset,
72 const std::vector<uint8_t>& data) = 0;
Patrick Ventureef3aead2018-09-12 08:53:29 -070073};
74
75/**
76 * Blob Manager used to store handlers and sessions.
77 */
78class BlobManager : public ManagerInterface
79{
80 public:
81 BlobManager()
82 {
83 next = static_cast<uint16_t>(std::time(nullptr));
84 };
85
86 ~BlobManager() = default;
87 /* delete copy constructor & assignment operator, only support move
88 * operations.
89 */
90 BlobManager(const BlobManager&) = delete;
91 BlobManager& operator=(const BlobManager&) = delete;
92 BlobManager(BlobManager&&) = default;
93 BlobManager& operator=(BlobManager&&) = default;
94
95 /**
96 * Register a handler. We own the pointer.
97 *
98 * @param[in] handler - a pointer to a blob handler.
99 * @return bool - true if registered.
100 */
101 bool
102 registerHandler(std::unique_ptr<GenericBlobInterface> handler) override;
103
104 /**
105 * Builds the blobId list for enumeration.
106 *
107 * @return lowest value returned is 0, otherwise the number of
108 * blobIds.
109 */
110 uint32_t buildBlobList() override;
111
112 /**
113 * Grabs the blobId for the indexed blobId.
114 *
115 * @param[in] index - the index into the blobId cache.
116 * @return string - the blobId or empty string on failure.
117 */
118 std::string getBlobId(uint32_t index) override;
119
120 /**
121 * Attempts to open the file specified and associates with a session.
122 *
123 * @param[in] flags - the flags to pass to open.
124 * @param[in] path - the file path to open.
125 * @param[in,out] session - pointer to store the session on success.
126 * @return bool - true if able to open.
127 */
128 bool open(uint16_t flags, const std::string& path,
129 uint16_t* session) override;
130
131 /**
132 * Attempts to retrieve a BlobMeta for the specified path.
133 *
134 * @param[in] path - the file path for stat().
135 * @param[in,out] meta - a pointer to store the metadata.
136 * @return bool - true if able to retrieve the information.
137 */
138 bool stat(const std::string& path, struct BlobMeta* meta) override;
139
140 /**
141 * Attempts to retrieve a BlobMeta for a given session.
142 *
143 * @param[in] session - the session for this command.
144 * @param[in,out] meta - a pointer to store the metadata.
145 * @return bool - true if able to retrieve the information.
146 */
147 bool stat(uint16_t session, struct BlobMeta* meta) override;
148
149 /**
150 * Attempt to commit a blob for a given session.
151 *
152 * @param[in] session - the session for this command.
153 * @param[in] data - an optional commit blob.
154 * @return bool - true if the commit succeeds.
155 */
156 bool commit(uint16_t session, const std::vector<uint8_t>& data) override;
157
158 /**
159 * Attempt to close a session. If the handler returns a failure
160 * in closing, the session is kept open.
161 *
162 * @param[in] session - the session for this command.
163 * @return bool - true if the session was closed.
164 */
165 bool close(uint16_t session) override;
166
167 /**
168 * Attempt to read bytes from the blob. If there's a failure, such as
169 * an invalid offset it'll just return 0 bytes.
170 *
171 * @param[in] session - the session for this command.
172 * @param[in] offset - the offset from which to read.
173 * @param[in] requestedSize - the number of bytes to try and read.
174 * @return the bytes read.
175 */
176 std::vector<uint8_t> read(uint16_t session, uint32_t offset,
177 uint32_t requestedSize) override;
178
179 /**
180 * Attempt to write to a blob. The manager does not track whether
181 * the session opened the file for writing.
182 *
183 * @param[in] session - the session for this command.
184 * @param[in] offset - the offset into the blob to write.
185 * @param[in] data - the bytes to write to the blob.
186 * @return bool - true if the write succeeded.
187 */
188 bool write(uint16_t session, uint32_t offset,
189 const std::vector<uint8_t>& data) override;
190
191 /**
192 * Attempt to delete a blobId. This method will just call the
193 * handler, which will return failure if the blob doesn't support
194 * deletion. This command will also fail if there are any open
195 * sessions against the specific blob.
196 *
197 * In the case where they specify a folder, such as /blob/skm where
198 * the "real" blobIds are /blob/skm/1, or /blob/skm/2, the manager
199 * may see there are on open sessions to that specific path and will
200 * call the handler. In this case, the handler is responsible for
201 * handling any checks or logic.
202 *
203 * @param[in] path - the blobId path.
204 * @return bool - true if delete was successful.
205 */
206 bool deleteBlob(const std::string& path) override;
207
208 /**
Patrick Venture5c4b17b2018-10-04 10:32:22 -0700209 * Attempt to write Metadata to a blob.
210 *
211 * @param[in] session - the session for this command.
212 * @param[in] offset - the offset into the blob to write.
213 * @param[in] data - the bytes to write to the blob.
214 * @return bool - true if the write succeeded.
215 */
216 bool writeMeta(uint16_t session, uint32_t offset,
217 const std::vector<uint8_t>& data) override;
218
219 /**
Patrick Ventureef3aead2018-09-12 08:53:29 -0700220 * Attempts to return a valid unique session id.
221 *
222 * @param[in,out] - pointer to the session.
223 * @return bool - true if able to allocate.
224 */
225 bool getSession(uint16_t* session);
226
227 /**
228 * Given a file path will return first handler to answer that it owns
229 * it.
230 *
231 * @param[in] path - the file path.
232 * @return pointer to the handler or nullptr if not found.
233 */
234 GenericBlobInterface* getHandler(const std::string& path);
235
236 /**
237 * Given a session id will return associated handler.
238 *
239 * @param[in] session - the session.
240 * @return pointer to the handler or nullptr if not found.
241 */
242 GenericBlobInterface* getHandler(uint16_t session);
243
244 /**
245 * Given a session id will return associated metadata, including
246 * the handler and the flags passed into open.
247 *
248 * @param[in] session - the session.
249 * @return pointer to the information or nullptr if not found.
250 */
251 SessionInfo* getSessionInfo(uint16_t session);
252
253 /**
254 * Given a session id will return associated path.
255 *
256 * @param[in] session - the session.
257 * @return the path or "" on failure.
258 */
259 std::string getPath(uint16_t session) const;
260
261 private:
262 void incrementOpen(const std::string& path);
263 void decrementOpen(const std::string& path);
264 int getOpen(const std::string& path) const;
265
266 /* The next session ID to use */
267 uint16_t next;
268 /* Temporary list of blobIds used for enumeration. */
269 std::vector<std::string> ids;
270 /* List of Blob handler. */
271 std::vector<std::unique_ptr<GenericBlobInterface>> handlers;
272 /* Mapping of session ids to blob handlers and the path used with open.
273 */
274 std::unordered_map<uint16_t, SessionInfo> sessions;
275 /* Mapping of open blobIds */
276 std::unordered_map<std::string, int> openFiles;
277};
Patrick Ventureb3e07e22018-09-27 15:11:57 -0700278
279/**
280 * @brief Gets a handle to the BlobManager.
281 *
282 * @return a pointer to the BlobManager instance.
283 */
Patrick Venture73eb6872018-10-01 18:37:34 -0700284ManagerInterface* getBlobManager();
Patrick Ventureb3e07e22018-09-27 15:11:57 -0700285
Patrick Ventureef3aead2018-09-12 08:53:29 -0700286} // namespace blobs