commit | 64dc05cfedd24385165322804dccab9b8838bfbd | [log] [tgz] |
---|---|---|
author | Kun Yi <kunyi731@gmail.com> | Wed Dec 19 13:19:03 2018 -0800 |
committer | Kun Yi <kunyi731@gmail.com> | Mon Feb 25 10:36:03 2019 -0800 |
tree | fee5d78465861d06212d11bb8326fd7e37e826c9 | |
parent | a4ba88604c8c5f6012e3a219137a71ec9a5ab1c8 [diff] |
binarystore: Initial implementation Dummy BinaryStore class implementation where most functions just return. Implement getBaseBlobId/getBlobIds/canHandleBlobId and add unit tests using real objects. Signed-off-by: Kun Yi <kunyi@google.com> Change-Id: Iaf8c59f3c4b1bab9de186333074a9cd0160a5764
The BMC generic IPMI blobs binary store, or "binary store" in short, serves a simple purpose: provide a read/write/serialize abstraction layer through IPMI blobs transport layer to allow users to store binary data on persistent locations accessible to the BMC.
Despite its name, the binary blob store cannot be used for everything.
Please read the IPMI Blob protocol design as primer here.
Under the hood, the binary blobs are stored as a binary protocol buffer, or "protobuf" in short.
phosphor-ipmi-blobs
installed.This section describes how the handler phosphor-ipmi-blobs-binarystore
defines each handler of the IPMI Blob protocol.
A "blob id" is a unique string that identifies a blob. Binary Store handler may show two kinds of blob ids: "base id" and "file id". They should only contain ASCII alphanumerical characters and forward slashes ('/').
A "base id" begins and ends with a forward slash. It is analagous to a unix directory path. The binary store handler will assign each storage location a unique base id (See next section for details).
A "file id" begins with a forward slash but must not have a slash at the end, and is analagous to a unix file path. Any file id with a valid base id as its longest matching prefix is considered reserved as a binary blob in the storage space.
For example, if /test/
and /test/blob0
are the initial blob ids, we know there is one binary store location with one blob already created. To create a new blob named /test/blob1
, one simply calls open with the id and write/commit with the returned session id. Opening invalid ids such as /foo/bar
or /test/nested/dir
will fail.
For the binary store handler, a configuration file provides the base id, which file and which offset in the file to store the data. Optionally a "max_size" param can be specified to indicate the total size of such binary storage should not exceed the limitation. If "max_size" is specified as -1 or not specified, the storage could grow up to what the physical media allows.
base_id: /bmc_store/ sysfile_path: /sys/class/i2c-dev/i2c-1/device/1-0050/eeprom offset: 256 max_size: 1024
[1] Example Configuration
The data is stored as a binary protobuf containing a variable number of binary blobs, each having a unique blob_id string with the base id as a common prefix.
message BinaryBlob { optional string blob_id = 1; optional bytes data = 2; } message BinaryBlobStore { optional string blob_base_id = 1; repeated BinaryBlob blob = 2; optional uint32 max_size = 3; optional string sysfile_path = 4; optional uint32 offset = 5; }
Storing data as a protobuf makes the format more flexible and expandable, and allows future modifications to the storage format.
The binary store handler will implement the following primitives:
Initially only the base id will appear when enumerating the existing blobs. Once a valid binary blob has been created, its blob id will appear in the list.
flags
can be READ
for read-only access or READ|WRITE
. blob_id
can be any string with a matching prefix. If there is not already a valid binary stored with supplied blob_id
, the handler treats it as a request to create such a blob.
The session_id
returned should be used by the rest of the session based commands to operate on the blob. If there is already an open session, this call will fail.
NOTE: the newly created blob is not serialized and stored until BmcBlobCommit
is called.
Returns bytes with the requested offset and size. If there are not enough bytes the handler will return the bytes that are available.
Note this operation reads from memory. Make sure the stat is 'COMMITTED' which indicates that the memory content matches the data serialized to storage.
Writes bytes to the requested offset. Return number of bytes written if success, zero if failed. If not all of the bytes can be written, this operation will fail.
Store the serialized BinaryBlobStore to the associated system file.
Mark the session as closed. Any uncommitted changes to the blob state is lost.
Delete the binary data associated with blob_id
. Must operate on an open blob. Deleting the base_id (the 'directory' level) will fail harmlessly.
size
returned equals to length of the data
bytes in the protobuf. blob_state
will be set with OPEN_R
, OPEN_W
, and/or COMMITTED
as appropriate.
Not supported.
BmcBlobGetCount
followed by BmcBlobEnumerate
. Since there is no valid blob with binary data stored, BMC handler only populates the base_id
per platform configuration. e.g. /bmc_store/
.BmcBlobOpen
with blob_id = /bmc_store/blob0
, BMC honors the request and returns session_id = 0
.BmcBlobWrite
multiple times to write the data into the blob.BmcBlobCommit
. BMC writes data into configured path, e.g. to EEPROM.BmcBlobClose
BmcBlobGetCount
followed by BmcBlobEnumrate
shows /bmc_store/
and /bmc_store/blob0
.BmcBlobStat
on /bmc_store/blob0
shows non-zero size and COMMITTED
state.BmcBlobOpen
with blob_id = /bmc_store/blob0
.BmcBlobRead
multiple times to read the data.BmcBlobClose
.The first alternative considered was to store the data via IPMI FRU commands; as mentioned in the problem description, it is not always viable.
There is a Google OEM I2C-over-IPMI driver that allows the host to read/write I2C devices attached to the BMC. In comparison, the blob store approach proposed offer more abstraction and is more flexible in where to store the data.