diff options
Diffstat (limited to 'blobs-ipmid')
-rw-r--r-- | blobs-ipmid/blobs.hpp | 143 | ||||
-rw-r--r-- | blobs-ipmid/manager.hpp | 253 |
2 files changed, 396 insertions, 0 deletions
diff --git a/blobs-ipmid/blobs.hpp b/blobs-ipmid/blobs.hpp new file mode 100644 index 0000000..b6672b7 --- /dev/null +++ b/blobs-ipmid/blobs.hpp @@ -0,0 +1,143 @@ +#pragma once + +#include <string> +#include <vector> + +namespace blobs +{ + +enum OpenFlags +{ + read = (1 << 0), + write = (1 << 1), + /* bits 3-7 reserved. */ + /* bits 8-15 given blob-specific definitions */ +}; + +enum StateFlags +{ + open_read = (1 << 0), + open_write = (1 << 1), + committing = (1 << 2), + committed = (1 << 3), + commit_error = (1 << 4), +}; + +struct BlobMeta +{ + uint16_t blobState; + uint32_t size; + std::vector<uint8_t> metadata; +}; + +/* + * All blob specific objects implement this interface. + */ +class GenericBlobInterface +{ + public: + virtual ~GenericBlobInterface() = default; + + /** + * Checks if the handler will manage this file path. + * + * @param[in] blobId. + * @return bool whether it will manage the file path. + */ + virtual bool canHandleBlob(const std::string& path) = 0; + + /** + * Return the name(s) of the blob(s). Used during GetCount. + * + * @return List of blobIds this handler manages. + */ + virtual std::vector<std::string> getBlobIds() = 0; + + /** + * Attempt to delete the blob specified by the path. + * + * @param[in] path - the blobId to try and delete. + * @return bool - whether it was able to delete the blob. + */ + virtual bool deleteBlob(const std::string& path) = 0; + + /** + * Return metadata about the blob. + * + * @param[in] path - the blobId for metadata. + * @param[in,out] meta - a pointer to a blobmeta. + * @return bool - true if it was successful. + */ + virtual bool stat(const std::string& path, struct BlobMeta* meta) = 0; + + /* The methods below are per session. */ + + /** + * Attempt to open a session from this path. + * + * @param[in] session - the session id. + * @param[in] flags - the open flags. + * @param[in] path - the blob path. + * @return bool - was able to open the session. + */ + virtual bool open(uint16_t session, uint16_t flags, + const std::string& path) = 0; + + /** + * Attempt to read from a blob. + * + * @param[in] session - the session id. + * @param[in] offset - offset into the blob. + * @param[in] requestedSize - number of bytes to read. + * @return Bytes read back (0 length on error). + */ + virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset, + uint32_t requestedSize) = 0; + + /** + * Attempt to write to a blob. + * + * @param[in] session - the session id. + * @param[in] offset - offset into the blob. + * @param[in] data - the data to write. + * @return bool - was able to write. + */ + virtual bool write(uint16_t session, uint32_t offset, + const std::vector<uint8_t>& data) = 0; + + /** + * Attempt to commit to a blob. + * + * @param[in] session - the session id. + * @param[in] data - optional commit data. + * @return bool - was able to start commit. + */ + virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0; + + /** + * Attempt to close your session. + * + * @param[in] session - the session id. + * @return bool - was able to close session. + */ + virtual bool close(uint16_t session) = 0; + + /** + * Attempt to return metadata for the session's view of the blob. + * + * @param[in] session - the session id. + * @param[in,out] meta - pointer to update with the BlobMeta. + * @return bool - wether it was successful. + */ + virtual bool stat(uint16_t session, struct BlobMeta* meta) = 0; + + /** + * Attempt to expire a session. This is called when a session has been + * inactive for at least 10 minutes. + * + * @param[in] session - the session id. + * @return bool - whether the session was able to be closed. + */ + virtual bool expire(uint16_t session) = 0; +}; +} // namespace blobs diff --git a/blobs-ipmid/manager.hpp b/blobs-ipmid/manager.hpp new file mode 100644 index 0000000..8220e0e --- /dev/null +++ b/blobs-ipmid/manager.hpp @@ -0,0 +1,253 @@ +#pragma once + +#include <blobs-ipmid/blobs.hpp> +#include <ctime> +#include <memory> +#include <string> +#include <unordered_map> +#include <vector> + +namespace blobs +{ + +struct SessionInfo +{ + SessionInfo() = default; + SessionInfo(const std::string& path, GenericBlobInterface* handler, + uint16_t flags) : + blobId(path), + handler(handler), flags(flags) + { + } + ~SessionInfo() = default; + + std::string blobId; + GenericBlobInterface* handler; + uint16_t flags; +}; + +class ManagerInterface +{ + public: + virtual ~ManagerInterface() = default; + + virtual bool + registerHandler(std::unique_ptr<GenericBlobInterface> handler) = 0; + + virtual uint32_t buildBlobList() = 0; + + virtual std::string getBlobId(uint32_t index) = 0; + + virtual bool open(uint16_t flags, const std::string& path, + uint16_t* session) = 0; + + virtual bool stat(const std::string& path, struct BlobMeta* meta) = 0; + + virtual bool stat(uint16_t session, struct BlobMeta* meta) = 0; + + virtual bool commit(uint16_t session, const std::vector<uint8_t>& data) = 0; + + virtual bool close(uint16_t session) = 0; + + virtual std::vector<uint8_t> read(uint16_t session, uint32_t offset, + uint32_t requestedSize) = 0; + + virtual bool write(uint16_t session, uint32_t offset, + const std::vector<uint8_t>& data) = 0; + + virtual bool deleteBlob(const std::string& path) = 0; +}; + +/** + * Blob Manager used to store handlers and sessions. + */ +class BlobManager : public ManagerInterface +{ + public: + BlobManager() + { + next = static_cast<uint16_t>(std::time(nullptr)); + }; + + ~BlobManager() = default; + /* delete copy constructor & assignment operator, only support move + * operations. + */ + BlobManager(const BlobManager&) = delete; + BlobManager& operator=(const BlobManager&) = delete; + BlobManager(BlobManager&&) = default; + BlobManager& operator=(BlobManager&&) = default; + + /** + * Register a handler. We own the pointer. + * + * @param[in] handler - a pointer to a blob handler. + * @return bool - true if registered. + */ + bool + registerHandler(std::unique_ptr<GenericBlobInterface> handler) override; + + /** + * Builds the blobId list for enumeration. + * + * @return lowest value returned is 0, otherwise the number of + * blobIds. + */ + uint32_t buildBlobList() override; + + /** + * Grabs the blobId for the indexed blobId. + * + * @param[in] index - the index into the blobId cache. + * @return string - the blobId or empty string on failure. + */ + std::string getBlobId(uint32_t index) override; + + /** + * Attempts to open the file specified and associates with a session. + * + * @param[in] flags - the flags to pass to open. + * @param[in] path - the file path to open. + * @param[in,out] session - pointer to store the session on success. + * @return bool - true if able to open. + */ + bool open(uint16_t flags, const std::string& path, + uint16_t* session) override; + + /** + * Attempts to retrieve a BlobMeta for the specified path. + * + * @param[in] path - the file path for stat(). + * @param[in,out] meta - a pointer to store the metadata. + * @return bool - true if able to retrieve the information. + */ + bool stat(const std::string& path, struct BlobMeta* meta) override; + + /** + * Attempts to retrieve a BlobMeta for a given session. + * + * @param[in] session - the session for this command. + * @param[in,out] meta - a pointer to store the metadata. + * @return bool - true if able to retrieve the information. + */ + bool stat(uint16_t session, struct BlobMeta* meta) override; + + /** + * Attempt to commit a blob for a given session. + * + * @param[in] session - the session for this command. + * @param[in] data - an optional commit blob. + * @return bool - true if the commit succeeds. + */ + bool commit(uint16_t session, const std::vector<uint8_t>& data) override; + + /** + * Attempt to close a session. If the handler returns a failure + * in closing, the session is kept open. + * + * @param[in] session - the session for this command. + * @return bool - true if the session was closed. + */ + bool close(uint16_t session) override; + + /** + * Attempt to read bytes from the blob. If there's a failure, such as + * an invalid offset it'll just return 0 bytes. + * + * @param[in] session - the session for this command. + * @param[in] offset - the offset from which to read. + * @param[in] requestedSize - the number of bytes to try and read. + * @return the bytes read. + */ + std::vector<uint8_t> read(uint16_t session, uint32_t offset, + uint32_t requestedSize) override; + + /** + * Attempt to write to a blob. The manager does not track whether + * the session opened the file for writing. + * + * @param[in] session - the session for this command. + * @param[in] offset - the offset into the blob to write. + * @param[in] data - the bytes to write to the blob. + * @return bool - true if the write succeeded. + */ + bool write(uint16_t session, uint32_t offset, + const std::vector<uint8_t>& data) override; + + /** + * Attempt to delete a blobId. This method will just call the + * handler, which will return failure if the blob doesn't support + * deletion. This command will also fail if there are any open + * sessions against the specific blob. + * + * In the case where they specify a folder, such as /blob/skm where + * the "real" blobIds are /blob/skm/1, or /blob/skm/2, the manager + * may see there are on open sessions to that specific path and will + * call the handler. In this case, the handler is responsible for + * handling any checks or logic. + * + * @param[in] path - the blobId path. + * @return bool - true if delete was successful. + */ + bool deleteBlob(const std::string& path) override; + + /** + * Attempts to return a valid unique session id. + * + * @param[in,out] - pointer to the session. + * @return bool - true if able to allocate. + */ + bool getSession(uint16_t* session); + + /** + * Given a file path will return first handler to answer that it owns + * it. + * + * @param[in] path - the file path. + * @return pointer to the handler or nullptr if not found. + */ + GenericBlobInterface* getHandler(const std::string& path); + + /** + * Given a session id will return associated handler. + * + * @param[in] session - the session. + * @return pointer to the handler or nullptr if not found. + */ + GenericBlobInterface* getHandler(uint16_t session); + + /** + * Given a session id will return associated metadata, including + * the handler and the flags passed into open. + * + * @param[in] session - the session. + * @return pointer to the information or nullptr if not found. + */ + SessionInfo* getSessionInfo(uint16_t session); + + /** + * Given a session id will return associated path. + * + * @param[in] session - the session. + * @return the path or "" on failure. + */ + std::string getPath(uint16_t session) const; + + private: + void incrementOpen(const std::string& path); + void decrementOpen(const std::string& path); + int getOpen(const std::string& path) const; + + /* The next session ID to use */ + uint16_t next; + /* Temporary list of blobIds used for enumeration. */ + std::vector<std::string> ids; + /* List of Blob handler. */ + std::vector<std::unique_ptr<GenericBlobInterface>> handlers; + /* Mapping of session ids to blob handlers and the path used with open. + */ + std::unordered_map<uint16_t, SessionInfo> sessions; + /* Mapping of open blobIds */ + std::unordered_map<std::string, int> openFiles; +}; +} // namespace blobs |