xref: /openbmc/phosphor-ipmi-blobs/manager.hpp (revision e0c41de4cc07a3e72046c658a9b8da9410f9a8fa)
1cd8dab49SPatrick Venture #pragma once
2cd8dab49SPatrick Venture 
3cd8dab49SPatrick Venture #include <blobs-ipmid/blobs.hpp>
452509572SPatrick Williams #include <ipmid/oemrouter.hpp>
552509572SPatrick Williams 
67fc52c8fSKun Yi #include <chrono>
7cd8dab49SPatrick Venture #include <ctime>
8cd8dab49SPatrick Venture #include <memory>
9b61a88baSKun Yi #include <set>
10cd8dab49SPatrick Venture #include <string>
11cd8dab49SPatrick Venture #include <unordered_map>
12cd8dab49SPatrick Venture #include <vector>
13cd8dab49SPatrick Venture 
14cd8dab49SPatrick Venture namespace blobs
15cd8dab49SPatrick Venture {
16cd8dab49SPatrick Venture 
17b61a88baSKun Yi using namespace std::chrono_literals;
18b61a88baSKun Yi constexpr auto defaultSessionTimeout = 10min;
1986c87f55SPatrick Venture 
20cd8dab49SPatrick Venture struct SessionInfo
21cd8dab49SPatrick Venture {
22cd8dab49SPatrick Venture     SessionInfo() = default;
SessionInfoblobs::SessionInfo23cd8dab49SPatrick Venture     SessionInfo(const std::string& path, GenericBlobInterface* handler,
2497e69ca1SPatrick Williams                 uint16_t flags) : blobId(path), handler(handler), flags(flags)
2552509572SPatrick Williams     {}
26cd8dab49SPatrick Venture     ~SessionInfo() = default;
27cd8dab49SPatrick Venture 
28cd8dab49SPatrick Venture     std::string blobId;
29cd8dab49SPatrick Venture     GenericBlobInterface* handler;
30cd8dab49SPatrick Venture     uint16_t flags;
317fc52c8fSKun Yi 
327fc52c8fSKun Yi     /* Initially set during open(). read/write/writeMeta/commit/stat operations
337fc52c8fSKun Yi      * would update it.
347fc52c8fSKun Yi      */
357fc52c8fSKun Yi     std::chrono::time_point<std::chrono::steady_clock> lastActionTime =
367fc52c8fSKun Yi         std::chrono::steady_clock::now();
37cd8dab49SPatrick Venture };
38cd8dab49SPatrick Venture 
39cd8dab49SPatrick Venture class ManagerInterface
40cd8dab49SPatrick Venture {
41cd8dab49SPatrick Venture   public:
42cd8dab49SPatrick Venture     virtual ~ManagerInterface() = default;
43cd8dab49SPatrick Venture 
44*e0c41de4SPatrick Williams     virtual bool registerHandler(
45*e0c41de4SPatrick Williams         std::unique_ptr<GenericBlobInterface> handler) = 0;
46cd8dab49SPatrick Venture 
47cd8dab49SPatrick Venture     virtual uint32_t buildBlobList() = 0;
48cd8dab49SPatrick Venture 
49cd8dab49SPatrick Venture     virtual std::string getBlobId(uint32_t index) = 0;
50cd8dab49SPatrick Venture 
51cd8dab49SPatrick Venture     virtual bool open(uint16_t flags, const std::string& path,
52cd8dab49SPatrick Venture                       uint16_t* session) = 0;
53cd8dab49SPatrick Venture 
548bc11779SPatrick Venture     virtual bool stat(const std::string& path, BlobMeta* meta) = 0;
55cd8dab49SPatrick Venture 
568bc11779SPatrick Venture     virtual bool stat(uint16_t session, BlobMeta* meta) = 0;
57cd8dab49SPatrick Venture 
58cd8dab49SPatrick Venture     virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0;
59cd8dab49SPatrick Venture 
60cd8dab49SPatrick Venture     virtual bool close(uint16_t session) = 0;
61cd8dab49SPatrick Venture 
62cd8dab49SPatrick Venture     virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset,
63cd8dab49SPatrick Venture                                       uint32_t requestedSize) = 0;
64cd8dab49SPatrick Venture 
65cd8dab49SPatrick Venture     virtual bool write(uint16_t session, uint32_t offset,
66cd8dab49SPatrick Venture                        const std::vector<uint8_t>& data) = 0;
67cd8dab49SPatrick Venture 
68cd8dab49SPatrick Venture     virtual bool deleteBlob(const std::string& path) = 0;
69cd8dab49SPatrick Venture 
70cd8dab49SPatrick Venture     virtual bool writeMeta(uint16_t session, uint32_t offset,
71cd8dab49SPatrick Venture                            const std::vector<uint8_t>& data) = 0;
72cd8dab49SPatrick Venture };
73cd8dab49SPatrick Venture 
74cd8dab49SPatrick Venture /**
75cd8dab49SPatrick Venture  * Blob Manager used to store handlers and sessions.
76cd8dab49SPatrick Venture  */
77cd8dab49SPatrick Venture class BlobManager : public ManagerInterface
78cd8dab49SPatrick Venture {
79cd8dab49SPatrick Venture   public:
BlobManager(std::chrono::seconds sessionTimeout=defaultSessionTimeout)80b61a88baSKun Yi     BlobManager(std::chrono::seconds sessionTimeout = defaultSessionTimeout) :
81b61a88baSKun Yi         sessionTimeout(sessionTimeout)
82cd8dab49SPatrick Venture     {
83cd8dab49SPatrick Venture         next = static_cast<uint16_t>(std::time(nullptr));
84cd8dab49SPatrick Venture     };
85cd8dab49SPatrick Venture 
86cd8dab49SPatrick Venture     ~BlobManager() = default;
87cd8dab49SPatrick Venture     /* delete copy constructor & assignment operator, only support move
88cd8dab49SPatrick Venture      * operations.
89cd8dab49SPatrick Venture      */
90cd8dab49SPatrick Venture     BlobManager(const BlobManager&) = delete;
91cd8dab49SPatrick Venture     BlobManager& operator=(const BlobManager&) = delete;
92cd8dab49SPatrick Venture     BlobManager(BlobManager&&) = default;
93cd8dab49SPatrick Venture     BlobManager& operator=(BlobManager&&) = default;
94cd8dab49SPatrick Venture 
95cd8dab49SPatrick Venture     /**
96cd8dab49SPatrick Venture      * Register a handler.  We own the pointer.
97cd8dab49SPatrick Venture      *
98cd8dab49SPatrick Venture      * @param[in] handler - a pointer to a blob handler.
99cd8dab49SPatrick Venture      * @return bool - true if registered.
100cd8dab49SPatrick Venture      */
101*e0c41de4SPatrick Williams     bool registerHandler(
102*e0c41de4SPatrick Williams         std::unique_ptr<GenericBlobInterface> handler) override;
103cd8dab49SPatrick Venture 
104cd8dab49SPatrick Venture     /**
105cd8dab49SPatrick Venture      * Builds the blobId list for enumeration.
106cd8dab49SPatrick Venture      *
107cd8dab49SPatrick Venture      * @return lowest value returned is 0, otherwise the number of
108cd8dab49SPatrick Venture      * blobIds.
109cd8dab49SPatrick Venture      */
110cd8dab49SPatrick Venture     uint32_t buildBlobList() override;
111cd8dab49SPatrick Venture 
112cd8dab49SPatrick Venture     /**
113cd8dab49SPatrick Venture      * Grabs the blobId for the indexed blobId.
114cd8dab49SPatrick Venture      *
115cd8dab49SPatrick Venture      * @param[in] index - the index into the blobId cache.
116cd8dab49SPatrick Venture      * @return string - the blobId or empty string on failure.
117cd8dab49SPatrick Venture      */
118cd8dab49SPatrick Venture     std::string getBlobId(uint32_t index) override;
119cd8dab49SPatrick Venture 
120cd8dab49SPatrick Venture     /**
121cd8dab49SPatrick Venture      * Attempts to open the file specified and associates with a session.
122cd8dab49SPatrick Venture      *
123cd8dab49SPatrick Venture      * @param[in] flags - the flags to pass to open.
124cd8dab49SPatrick Venture      * @param[in] path - the file path to open.
125cd8dab49SPatrick Venture      * @param[in,out] session - pointer to store the session on success.
126cd8dab49SPatrick Venture      * @return bool - true if able to open.
127cd8dab49SPatrick Venture      */
128cd8dab49SPatrick Venture     bool open(uint16_t flags, const std::string& path,
129cd8dab49SPatrick Venture               uint16_t* session) override;
130cd8dab49SPatrick Venture 
131cd8dab49SPatrick Venture     /**
132cd8dab49SPatrick Venture      * Attempts to retrieve a BlobMeta for the specified path.
133cd8dab49SPatrick Venture      *
134cd8dab49SPatrick Venture      * @param[in] path - the file path for stat().
135cd8dab49SPatrick Venture      * @param[in,out] meta - a pointer to store the metadata.
136cd8dab49SPatrick Venture      * @return bool - true if able to retrieve the information.
137cd8dab49SPatrick Venture      */
1388bc11779SPatrick Venture     bool stat(const std::string& path, BlobMeta* meta) override;
139cd8dab49SPatrick Venture 
140cd8dab49SPatrick Venture     /**
141cd8dab49SPatrick Venture      * Attempts to retrieve a BlobMeta for a given session.
142cd8dab49SPatrick Venture      *
143cd8dab49SPatrick Venture      * @param[in] session - the session for this command.
144cd8dab49SPatrick Venture      * @param[in,out] meta - a pointer to store the metadata.
145cd8dab49SPatrick Venture      * @return bool - true if able to retrieve the information.
146cd8dab49SPatrick Venture      */
1478bc11779SPatrick Venture     bool stat(uint16_t session, BlobMeta* meta) override;
148cd8dab49SPatrick Venture 
149cd8dab49SPatrick Venture     /**
150cd8dab49SPatrick Venture      * Attempt to commit a blob for a given session.
151cd8dab49SPatrick Venture      *
152cd8dab49SPatrick Venture      * @param[in] session - the session for this command.
153cd8dab49SPatrick Venture      * @param[in] data - an optional commit blob.
154cd8dab49SPatrick Venture      * @return bool - true if the commit succeeds.
155cd8dab49SPatrick Venture      */
156cd8dab49SPatrick Venture     bool commit(uint16_t session, const std::vector<uint8_t>& data) override;
157cd8dab49SPatrick Venture 
158cd8dab49SPatrick Venture     /**
159cd8dab49SPatrick Venture      * Attempt to close a session.  If the handler returns a failure
160cd8dab49SPatrick Venture      * in closing, the session is kept open.
161cd8dab49SPatrick Venture      *
162cd8dab49SPatrick Venture      * @param[in] session - the session for this command.
163cd8dab49SPatrick Venture      * @return bool - true if the session was closed.
164cd8dab49SPatrick Venture      */
165cd8dab49SPatrick Venture     bool close(uint16_t session) override;
166cd8dab49SPatrick Venture 
167cd8dab49SPatrick Venture     /**
168cd8dab49SPatrick Venture      * Attempt to read bytes from the blob.  If there's a failure, such as
169cd8dab49SPatrick Venture      * an invalid offset it'll just return 0 bytes.
170cd8dab49SPatrick Venture      *
171cd8dab49SPatrick Venture      * @param[in] session - the session for this command.
172cd8dab49SPatrick Venture      * @param[in] offset - the offset from which to read.
173cd8dab49SPatrick Venture      * @param[in] requestedSize - the number of bytes to try and read.
174cd8dab49SPatrick Venture      * @return the bytes read.
175cd8dab49SPatrick Venture      */
176cd8dab49SPatrick Venture     std::vector<uint8_t> read(uint16_t session, uint32_t offset,
177cd8dab49SPatrick Venture                               uint32_t requestedSize) override;
178cd8dab49SPatrick Venture 
179cd8dab49SPatrick Venture     /**
180cd8dab49SPatrick Venture      * Attempt to write to a blob.  The manager does not track whether
181cd8dab49SPatrick Venture      * the session opened the file for writing.
182cd8dab49SPatrick Venture      *
183cd8dab49SPatrick Venture      * @param[in] session - the session for this command.
184cd8dab49SPatrick Venture      * @param[in] offset - the offset into the blob to write.
185cd8dab49SPatrick Venture      * @param[in] data - the bytes to write to the blob.
186cd8dab49SPatrick Venture      * @return bool - true if the write succeeded.
187cd8dab49SPatrick Venture      */
188cd8dab49SPatrick Venture     bool write(uint16_t session, uint32_t offset,
189cd8dab49SPatrick Venture                const std::vector<uint8_t>& data) override;
190cd8dab49SPatrick Venture 
191cd8dab49SPatrick Venture     /**
192cd8dab49SPatrick Venture      * Attempt to delete a blobId.  This method will just call the
193cd8dab49SPatrick Venture      * handler, which will return failure if the blob doesn't support
194cd8dab49SPatrick Venture      * deletion.  This command will also fail if there are any open
195cd8dab49SPatrick Venture      * sessions against the specific blob.
196cd8dab49SPatrick Venture      *
197cd8dab49SPatrick Venture      * In the case where they specify a folder, such as /blob/skm where
198cd8dab49SPatrick Venture      * the "real" blobIds are /blob/skm/1, or /blob/skm/2, the manager
199cd8dab49SPatrick Venture      * may see there are on open sessions to that specific path and will
200cd8dab49SPatrick Venture      * call the handler.  In this case, the handler is responsible for
201cd8dab49SPatrick Venture      * handling any checks or logic.
202cd8dab49SPatrick Venture      *
203cd8dab49SPatrick Venture      * @param[in] path - the blobId path.
204cd8dab49SPatrick Venture      * @return bool - true if delete was successful.
205cd8dab49SPatrick Venture      */
206cd8dab49SPatrick Venture     bool deleteBlob(const std::string& path) override;
207cd8dab49SPatrick Venture 
208cd8dab49SPatrick Venture     /**
209cd8dab49SPatrick Venture      * Attempt to write Metadata to a blob.
210cd8dab49SPatrick Venture      *
211cd8dab49SPatrick Venture      * @param[in] session - the session for this command.
212cd8dab49SPatrick Venture      * @param[in] offset - the offset into the blob to write.
213cd8dab49SPatrick Venture      * @param[in] data - the bytes to write to the blob.
214cd8dab49SPatrick Venture      * @return bool - true if the write succeeded.
215cd8dab49SPatrick Venture      */
216cd8dab49SPatrick Venture     bool writeMeta(uint16_t session, uint32_t offset,
217cd8dab49SPatrick Venture                    const std::vector<uint8_t>& data) override;
218cd8dab49SPatrick Venture 
219cd8dab49SPatrick Venture     /**
220cd8dab49SPatrick Venture      * Attempts to return a valid unique session id.
221cd8dab49SPatrick Venture      *
222cd8dab49SPatrick Venture      * @param[in,out] - pointer to the session.
223cd8dab49SPatrick Venture      * @return bool - true if able to allocate.
224cd8dab49SPatrick Venture      */
225cd8dab49SPatrick Venture     bool getSession(uint16_t* session);
226cd8dab49SPatrick Venture 
2279cd8f76dSKun Yi   private:
228cd8dab49SPatrick Venture     /**
229cd8dab49SPatrick Venture      * Given a file path will return first handler to answer that it owns
230cd8dab49SPatrick Venture      * it.
231cd8dab49SPatrick Venture      *
232cd8dab49SPatrick Venture      * @param[in] path - the file path.
233cd8dab49SPatrick Venture      * @return pointer to the handler or nullptr if not found.
234cd8dab49SPatrick Venture      */
235cd8dab49SPatrick Venture     GenericBlobInterface* getHandler(const std::string& path);
236cd8dab49SPatrick Venture 
237cd8dab49SPatrick Venture     /**
2389cd8f76dSKun Yi      * Given a session id, update session time and return a handler to take
239c892f4a0SKun Yi      * action
240cd8dab49SPatrick Venture      *
241c892f4a0SKun Yi      * @param[in] session - session ID
2429cd8f76dSKun Yi      * @param[in] requiredFlags - only return handler if the flags for this
243c892f4a0SKun Yi      *            session contain these flags; defaults to any flag
244c892f4a0SKun Yi      * @return session handler, nullptr if cannot get handler
245cd8dab49SPatrick Venture      */
2469cd8f76dSKun Yi     GenericBlobInterface* getActionHandler(
247c892f4a0SKun Yi         uint16_t session,
248fea1d811SKun Yi         uint16_t requiredFlags = std::numeric_limits<uint16_t>::max());
249cd8dab49SPatrick Venture 
2509cd8f76dSKun Yi     /**
2519cd8f76dSKun Yi      * Helper method to erase a session from all maps
2529cd8f76dSKun Yi      *
2539cd8f76dSKun Yi      * @param[in] handler - handler pointer for lookup
2549cd8f76dSKun Yi      * @param[in] session - session ID for lookup
2559cd8f76dSKun Yi      * @return None
2569cd8f76dSKun Yi      */
2579cd8f76dSKun Yi     void eraseSession(GenericBlobInterface* const handler, uint16_t session);
2589cd8f76dSKun Yi 
2599cd8f76dSKun Yi     /**
2609cd8f76dSKun Yi      * For each session owned by this handler, call expire if it is stale
2619cd8f76dSKun Yi      *
2629cd8f76dSKun Yi      * @param[in] handler - handler pointer for lookup
2639cd8f76dSKun Yi      * @return None
2649cd8f76dSKun Yi      */
2659cd8f76dSKun Yi     void cleanUpStaleSessions(GenericBlobInterface* const handler);
266b61a88baSKun Yi 
267b61a88baSKun Yi     /* How long a session has to be inactive to be considered stale */
268b61a88baSKun Yi     std::chrono::seconds sessionTimeout;
269cd8dab49SPatrick Venture     /* The next session ID to use */
270cd8dab49SPatrick Venture     uint16_t next;
271cd8dab49SPatrick Venture     /* Temporary list of blobIds used for enumeration. */
272cd8dab49SPatrick Venture     std::vector<std::string> ids;
273cd8dab49SPatrick Venture     /* List of Blob handler. */
274cd8dab49SPatrick Venture     std::vector<std::unique_ptr<GenericBlobInterface>> handlers;
275cd8dab49SPatrick Venture     /* Mapping of session ids to blob handlers and the path used with open.
276cd8dab49SPatrick Venture      */
277cd8dab49SPatrick Venture     std::unordered_map<uint16_t, SessionInfo> sessions;
278cd8dab49SPatrick Venture     /* Mapping of open blobIds */
279cd8dab49SPatrick Venture     std::unordered_map<std::string, int> openFiles;
280b61a88baSKun Yi     /* Map of handlers to their open sessions */
281b61a88baSKun Yi     std::unordered_map<GenericBlobInterface*, std::set<uint16_t>> openSessions;
282cd8dab49SPatrick Venture };
283cd8dab49SPatrick Venture 
284cd8dab49SPatrick Venture /**
285cd8dab49SPatrick Venture  * @brief Gets a handle to the BlobManager.
286cd8dab49SPatrick Venture  *
287cd8dab49SPatrick Venture  * @return a pointer to the BlobManager instance.
288cd8dab49SPatrick Venture  */
289cd8dab49SPatrick Venture ManagerInterface* getBlobManager();
290cd8dab49SPatrick Venture 
291cd8dab49SPatrick Venture } // namespace blobs
292