blob: 9f955394bd10cc4807f4d52b987a1c90402e8536 [file] [log] [blame]
Kun Yi68c81142018-12-18 11:17:14 -08001#pragma once
2
Kun Yi2765b642019-01-16 11:11:24 -08003#include "sys_file.hpp"
4
Kun Yi64dc05c2018-12-19 13:19:03 -08005#include <unistd.h>
6
Kun Yi1a25e0d2020-05-11 12:28:53 -07007#include <blobs-ipmid/blobs.hpp>
Kun Yi68c81142018-12-18 11:17:14 -08008#include <cstdint>
Kun Yi64dc05c2018-12-19 13:19:03 -08009#include <memory>
Kun Yi68c81142018-12-18 11:17:14 -080010#include <string>
11#include <vector>
12
Kun Yi0a940b92019-01-07 16:33:11 -080013#include "binaryblob.pb.h"
14
Kun Yi68c81142018-12-18 11:17:14 -080015using std::size_t;
16using std::uint16_t;
17using std::uint32_t;
18using std::uint64_t;
19using std::uint8_t;
20
21namespace binstore
22{
23
24/**
25 * @class BinaryStoreInterface is an abstraction for a storage location.
Kun Yi64dc05c2018-12-19 13:19:03 -080026 * Each instance would be uniquely identified by a baseId string.
Kun Yi68c81142018-12-18 11:17:14 -080027 */
28class BinaryStoreInterface
29{
30 public:
31 virtual ~BinaryStoreInterface() = default;
32
Kun Yi64dc05c2018-12-19 13:19:03 -080033 /**
34 * @returns baseId string of the storage.
35 */
Kun Yi68c81142018-12-18 11:17:14 -080036 virtual std::string getBaseBlobId() const = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080037
38 /**
39 * @returns List of all open blob IDs, plus the base.
40 */
Kun Yi68c81142018-12-18 11:17:14 -080041 virtual std::vector<std::string> getBlobIds() const = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080042
43 /**
44 * Opens a blob given its name. If there is no one, create one.
45 * @param blobId: The blob id to operate on.
46 * @param flags: Either read flag or r/w flag has to be specified.
47 * @returns True if open/create successfully.
48 */
Kun Yi38146a02018-12-18 21:54:26 -080049 virtual bool openOrCreateBlob(const std::string& blobId,
50 uint16_t flags) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080051
52 /**
53 * Deletes a blob given its name. If there is no one,
54 * @param blobId: The blob id to operate on.
55 * @returns True if deleted.
56 */
Kun Yic0adbc32018-12-18 22:35:29 -080057 virtual bool deleteBlob(const std::string& blobId) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080058
59 /**
60 * Reads data from the currently opened blob.
61 * @param offset: offset into the blob to read
62 * @param requestedSize: how many bytes to read
63 * @returns Bytes able to read. Returns empty if nothing can be read or
64 * if there is no open blob.
65 */
Kun Yi68c81142018-12-18 11:17:14 -080066 virtual std::vector<uint8_t> read(uint32_t offset,
67 uint32_t requestedSize) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080068
69 /**
70 * Writes data to the currently openend blob.
71 * @param offset: offset into the blob to write
72 * @param data: bytes to write
73 * @returns True if able to write the entire data successfully
74 */
Kun Yi68c81142018-12-18 11:17:14 -080075 virtual bool write(uint32_t offset, const std::vector<uint8_t>& data) = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080076
77 /**
Kun Yid297c9f2019-01-09 13:52:30 -080078 * Commits data to the persistent storage specified during blob init.
79 * @returns True if able to write data to sysfile successfully
Kun Yi64dc05c2018-12-19 13:19:03 -080080 */
Kun Yi68c81142018-12-18 11:17:14 -080081 virtual bool commit() = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080082
83 /**
Kun Yid297c9f2019-01-09 13:52:30 -080084 * Closes blob, which prevents further modifications. Uncommitted data will
85 * be lost.
86 * @returns True if able to close the blob successfully
Kun Yi64dc05c2018-12-19 13:19:03 -080087 */
Kun Yi68c81142018-12-18 11:17:14 -080088 virtual bool close() = 0;
Kun Yi64dc05c2018-12-19 13:19:03 -080089
90 /**
Kun Yi1a25e0d2020-05-11 12:28:53 -070091 * Returns blob stat flags.
92 * @param meta: output stat flags.
93 * @returns True if able to get the stat flags and write to *meta
Kun Yi64dc05c2018-12-19 13:19:03 -080094 */
Kun Yi1a25e0d2020-05-11 12:28:53 -070095 virtual bool stat(blobs::BlobMeta* meta) = 0;
Kun Yi68c81142018-12-18 11:17:14 -080096};
97
Kun Yi64dc05c2018-12-19 13:19:03 -080098/**
99 * @class BinaryStore instantiates a concrete implementation of
100 * BinaryStoreInterface. The dependency on file is injected through its
101 * constructor.
102 */
103class BinaryStore : public BinaryStoreInterface
104{
105 public:
Kun Yi1a25e0d2020-05-11 12:28:53 -0700106 /* |CommitState| differs slightly with |StateFlags| in blob.hpp,
107 * and thus is defined in the OEM space (bit 8 - 15). User can call stat()
108 * to query the |CommitState| of the blob path. */
109 enum CommitState
110 {
111 Dirty = (1 << 8), // In-memory data might not match persisted data
112 Clean = (1 << 9), // In-memory data matches persisted data
113 Uninitialized = (1 << 10), // Cannot find persisted data
114 CommitError = (1 << 11) // Error happened during committing
115 };
116
Kun Yi2765b642019-01-16 11:11:24 -0800117 BinaryStore() = delete;
118 BinaryStore(const std::string& baseBlobId, std::unique_ptr<SysFile> file,
Kun Yi64dc05c2018-12-19 13:19:03 -0800119 uint32_t maxSize) :
120 baseBlobId_(baseBlobId),
Kun Yi2765b642019-01-16 11:11:24 -0800121 file_(std::move(file)), maxSize_(maxSize)
Kun Yi64dc05c2018-12-19 13:19:03 -0800122 {
Kun Yi97be3af2019-03-05 22:43:41 -0800123 blob_.set_blob_base_id(baseBlobId_);
Kun Yi64dc05c2018-12-19 13:19:03 -0800124 }
125
Kun Yi64dc05c2018-12-19 13:19:03 -0800126 ~BinaryStore() = default;
Kun Yi2765b642019-01-16 11:11:24 -0800127
Kun Yi64dc05c2018-12-19 13:19:03 -0800128 BinaryStore(const BinaryStore&) = delete;
129 BinaryStore& operator=(const BinaryStore&) = delete;
130 BinaryStore(BinaryStore&&) = default;
131 BinaryStore& operator=(BinaryStore&&) = default;
132
133 std::string getBaseBlobId() const override;
134 std::vector<std::string> getBlobIds() const override;
135 bool openOrCreateBlob(const std::string& blobId, uint16_t flags) override;
136 bool deleteBlob(const std::string& blobId) override;
137 std::vector<uint8_t> read(uint32_t offset, uint32_t requestedSize) override;
138 bool write(uint32_t offset, const std::vector<uint8_t>& data) override;
139 bool commit() override;
140 bool close() override;
Kun Yi1a25e0d2020-05-11 12:28:53 -0700141 bool stat(blobs::BlobMeta* meta) override;
Kun Yi64dc05c2018-12-19 13:19:03 -0800142
143 /**
144 * Helper factory method to create a BinaryStore instance
145 * @param baseBlobId: base id for the created instance
Kun Yi2765b642019-01-16 11:11:24 -0800146 * @param sysFile: system file object for storing binary
Kun Yi64dc05c2018-12-19 13:19:03 -0800147 * @param maxSize: max size in bytes that this BinaryStore can expand to.
148 * Writing data more than allowed size will return failure.
149 * @returns unique_ptr to constructed BinaryStore. Caller should take
150 * ownership of the instance.
151 */
152 static std::unique_ptr<BinaryStoreInterface>
153 createFromConfig(const std::string& baseBlobId,
Kun Yi2765b642019-01-16 11:11:24 -0800154 std::unique_ptr<SysFile> file, uint32_t maxSize);
Kun Yi64dc05c2018-12-19 13:19:03 -0800155
156 private:
Kun Yi97be3af2019-03-05 22:43:41 -0800157 /* Load the serialized data from sysfile if commit state is dirty.
158 * Returns False if encountered error when loading */
159 bool loadSerializedData();
160
Kun Yi64dc05c2018-12-19 13:19:03 -0800161 std::string baseBlobId_;
Kun Yi0a940b92019-01-07 16:33:11 -0800162 binaryblobproto::BinaryBlobBase blob_;
Kun Yi2765b642019-01-16 11:11:24 -0800163 binaryblobproto::BinaryBlob* currentBlob_ = nullptr;
Kun Yi6baa7132019-01-08 21:21:02 -0800164 bool writable_ = false;
Kun Yi2765b642019-01-16 11:11:24 -0800165 std::unique_ptr<SysFile> file_ = nullptr;
166 uint32_t maxSize_;
Kun Yid297c9f2019-01-09 13:52:30 -0800167 CommitState commitState_ = CommitState::Dirty;
Kun Yi64dc05c2018-12-19 13:19:03 -0800168};
169
Kun Yi68c81142018-12-18 11:17:14 -0800170} // namespace binstore