1baa73da1SPatrick Venture# Phosphor Blob Transfer Interface 2baa73da1SPatrick Venture 3baa73da1SPatrick VentureThis document describes the commands implementing a generic blob transfer 4baa73da1SPatrick Ventureinterface. This document does not specify how blobs are stored; that is left up 5baa73da1SPatrick Ventureto blob-specific implementations. Introduction This mechanism supports reading 6baa73da1SPatrick Ventureand writing from a generic blob store. This mechanism can be leveraged to 7baa73da1SPatrick Venturesupport firmware upgrades, 8baa73da1SPatrick Venture 9baa73da1SPatrick VentureThe interface defined in this document supports: 10baa73da1SPatrick Venture 11885cbfe3SPatrick Williams- Enumerating blobs 12885cbfe3SPatrick Williams- Opening a blob for reading or writing 13885cbfe3SPatrick Williams- Writing blob content 14885cbfe3SPatrick Williams- Committing a blob 15885cbfe3SPatrick Williams- Polling until the blob has been committed 16885cbfe3SPatrick Williams- Closing a blob 17885cbfe3SPatrick Williams- Reading blob content 18885cbfe3SPatrick Williams- Deleting a blob 19baa73da1SPatrick Venture 20baa73da1SPatrick VentureSome blobs will only support a subset of these operations. For example, firmware 21baa73da1SPatrick Venturecannot generally be read, as the firmware file is not persisted on the BMC after 22baa73da1SPatrick Ventureit has been activated. 23baa73da1SPatrick Venture 24baa73da1SPatrick VentureThis specification supports IPMI as a transport layer. This can be quite slow, 25baa73da1SPatrick Venturehowever; IPMI transport speeds range from 23 kbps to 256 kbps. LPC/P2A ("PCI to 26baa73da1SPatrick VentureAspeed") MMIO bridges are currently unsupported. Blob Identifiers Blobs are 27baa73da1SPatrick Ventureidentified by NULL-terminated C strings. This protocol supports 28baa73da1SPatrick Ventureimplementation-specific blob identifiers; some blobs may have single well-known 29baa73da1SPatrick Venturenames, while others may be defined only by a prefix, with the client specifying 30baa73da1SPatrick Venturethe rest of the blob name. For example, "/g/bmc_firmware" may represent a single 31baa73da1SPatrick Venturewell-known blob that supports BMC firmware updates, whereas "/g/skm/[N]" may 32baa73da1SPatrick Venturerepresent an arbitrary number of SKM keys, with the index specified on the host 33baa73da1SPatrick Venturewhen opening the blob. 34baa73da1SPatrick Venture 35baa73da1SPatrick VentureBlob identifiers are limited based on the maximum size of the IPMI packet. This 36baa73da1SPatrick Venturemaximum size is platform-dependent; theoretically a packet could be up to 256 37baa73da1SPatrick Venturebytes, but some hardware only supports packets up to 64 bytes. 38baa73da1SPatrick Venture 39baa73da1SPatrick VentureIf an identifier is malformed, e.g. does not have a trailing NUL-byte or is 40baa73da1SPatrick Ventureotherwise unrecognizable by the BMC, an error is returned. 41baa73da1SPatrick Venture 42826e1735SPatrick VentureThe OEM Number to use with these commands is 43885cbfe3SPatrick Williams[openbmc oen](https://github.com/openbmc/phosphor-host-ipmid/blob/194375f2676715a0e0697bab63234a4efe39fb96/include/ipmid/iana.hpp#L12) 49871. 4441ccacd9SPatrick Venture 45baa73da1SPatrick Venture## Commands 46baa73da1SPatrick Venture 47baa73da1SPatrick VentureThe following details each subcommand in the blob spec. In the following, any 48baa73da1SPatrick Venturereference to the command body starts after the 3 bytes of OEM header, the 1-byte 49baa73da1SPatrick Venturesubcommand code, and (in the cases where the command body is non-empty) a 50baa73da1SPatrick Venturetwo-byte CRC over all data that follows in the body. 51baa73da1SPatrick Venture 52baa73da1SPatrick VentureAll non-empty responses should lead with a two-byte CRC. The CRC algorithm is 53baa73da1SPatrick VentureCRC-16-CCITT (poly 0x1021). 54baa73da1SPatrick Venture 55baa73da1SPatrick VentureAll multi-byte values are encoded as little-endian. All structs are assumed 56baa73da1SPatrick Venturepacked. Success codes are returned via the "completion code" field from the IPMI 57baa73da1SPatrick Venturespec. 58baa73da1SPatrick Venture 59baa73da1SPatrick Venture### BmcBlobGetCount (0) 60baa73da1SPatrick Venture 61baa73da1SPatrick VentureThe `BmcBlobGetCount` command expects to receive an empty body. The BMC will 62baa73da1SPatrick Venturereturn the number of enumerable blobs: 63baa73da1SPatrick Venture 64*8848c438SPatrick Williams```cpp 65baa73da1SPatrick Venturestruct BmcBlobCountRx { 66baa73da1SPatrick Venture uint16_t crc16; 67baa73da1SPatrick Venture uint32_t blob_count; 68baa73da1SPatrick Venture}; 69baa73da1SPatrick Venture``` 70baa73da1SPatrick Venture 71baa73da1SPatrick Venture### BmcBlobEnumerate (1) 72baa73da1SPatrick Venture 73baa73da1SPatrick VentureThe `BmcBlobEnumerate` command expects to receive a body of: 74baa73da1SPatrick Venture 75*8848c438SPatrick Williams```cpp 76baa73da1SPatrick Venturestruct BmcBlobEnumerateTx { 77baa73da1SPatrick Venture uint16_t crc16; 78baa73da1SPatrick Venture uint32_t blob_idx; /* 0-based index of blob to retrieve. */ 79baa73da1SPatrick Venture}; 80baa73da1SPatrick Venture``` 81baa73da1SPatrick Venture 82baa73da1SPatrick VentureThe BMC will return the corresponding blob identifier: 83baa73da1SPatrick Venture 84*8848c438SPatrick Williams```cpp 85baa73da1SPatrick Venturestruct BmcBlobEnumerateRx { 86baa73da1SPatrick Venture uint16_t crc16; 87baa73da1SPatrick Venture char blob_id[]; 88baa73da1SPatrick Venture}; 89baa73da1SPatrick Venture``` 90baa73da1SPatrick Venture 91baa73da1SPatrick VentureNote that the index for a given blob ID is not expected to be stable across a 92baa73da1SPatrick Venturelong term. Callers are expected to call `BmcBlobGetCount`, followed by N calls 93baa73da1SPatrick Ventureto `BmcBlobEnumerate`, to collect all blob IDs. Callers can then call 94baa73da1SPatrick Venture`BmcBlobStat` with each blob ID. If this process is interleaved with Open or 95baa73da1SPatrick VentureDelete calls that modify the number of enumerable blobs, this operation will be 96baa73da1SPatrick Venturesubject to concurrent modification issues. 97baa73da1SPatrick Venture 98baa73da1SPatrick Venture### BmcBlobOpen (2) 99baa73da1SPatrick Venture 100baa73da1SPatrick VentureThe BmcBlobOpen command expects to receive a body of: 101baa73da1SPatrick Venture 102*8848c438SPatrick Williams```cpp 103baa73da1SPatrick Venturestruct BmcBlobOpenTx { 104baa73da1SPatrick Venture uint16_t crc16; 105baa73da1SPatrick Venture uint16_t flags; 106baa73da1SPatrick Venture char blob_id[]; /* Must correspond to a valid blob. */ 107baa73da1SPatrick Venture}; 108baa73da1SPatrick Venture``` 109baa73da1SPatrick Venture 110baa73da1SPatrick VentureThe flags field allows the caller to specify whether the blob is being opened 111baa73da1SPatrick Venturefor reading or writing: 112baa73da1SPatrick Venture 113*8848c438SPatrick Williams```cpp 114baa73da1SPatrick Ventureenum BmcBlobOpenFlagBits { 115baa73da1SPatrick Venture READ = 0, 116baa73da1SPatrick Venture WRITE = 1, 117baa73da1SPatrick Venture <bits 2-7 reserved> 118baa73da1SPatrick Venture <bits 8-15 given blob-specific definitions> 119baa73da1SPatrick Venture}; 120baa73da1SPatrick Venture``` 121baa73da1SPatrick Venture 122baa73da1SPatrick VentureIf the `WRITE` flag is specified, the BMC will mark the specified blob as "open 123baa73da1SPatrick Venturefor writing". Optional blob-specific behavior: if the blob has been open for 124baa73da1SPatrick Venturemore than one minute without any activity, the existing session will be torn 125baa73da1SPatrick Venturedown and the open will succeed. Alternatively, blobs may allow multiple write 126baa73da1SPatrick Venturesessions to be active at once. 127baa73da1SPatrick Venture 128baa73da1SPatrick VentureThe BMC allocates a unique session identifier, and internally maps it to the 129baa73da1SPatrick Ventureblob identifier. 130baa73da1SPatrick Venture 131*8848c438SPatrick Williams```cpp 132baa73da1SPatrick Venturestruct BmcBlobOpenRx { 133baa73da1SPatrick Venture uint16_t crc16; 134baa73da1SPatrick Venture uint16_t session_id; 135baa73da1SPatrick Venture}; 136baa73da1SPatrick Venture``` 137baa73da1SPatrick Venture 138baa73da1SPatrick Venture### BmcBlobRead (3) 139baa73da1SPatrick Venture 140baa73da1SPatrick VentureThe BmcBlobRead command is used to read blob data. It expects to receive a body 141baa73da1SPatrick Ventureof: 142baa73da1SPatrick Venture 143*8848c438SPatrick Williams```cpp 144baa73da1SPatrick Venturestruct BmcBlobReadTx { 145baa73da1SPatrick Venture uint16_t crc16; 146baa73da1SPatrick Venture uint16_t session_id; /* Returned from BmcBlobOpen. */ 147baa73da1SPatrick Venture uint32_t offset; /* The byte sequence start, 0-based. */ 148baa73da1SPatrick Venture uint32_t requested_size; /* The number of bytes requested for reading. */ 149baa73da1SPatrick Venture}; 150baa73da1SPatrick Venture``` 151baa73da1SPatrick Venture 152baa73da1SPatrick VentureBlob handlers may require the blob’s "state" to equal `OPEN_R` before reading is 153baa73da1SPatrick Venturesuccessful. 154baa73da1SPatrick Venture 155*8848c438SPatrick Williams```cpp 156baa73da1SPatrick Venturestruct BmcBlobReadRx { 157baa73da1SPatrick Venture uint16_t crc16; 158baa73da1SPatrick Venture uint8_t data[]; 159baa73da1SPatrick Venture}; 160baa73da1SPatrick Venture``` 161baa73da1SPatrick Venture 162baa73da1SPatrick VentureImmediately following this structure are the bytes being read. The number of 163baa73da1SPatrick Venturebytes transferred is the size of the response body less the OEN ("OEM number") 164baa73da1SPatrick Venture(3 bytes), sub-command (1 byte), and the structure size (4 bytes). If no bytes 165baa73da1SPatrick Ventureare transferred, the CRC is still sent. 166baa73da1SPatrick Venture 167baa73da1SPatrick VentureIf the BMC cannot return the number of requested bytes, it simply returns the 168baa73da1SPatrick Venturenumber of bytes available for reading. If the host tries to read at an invalid 169baa73da1SPatrick Ventureoffset or if the host tries to read at the end of the blob, an empty successful 170baa73da1SPatrick Ventureresponse is returned; e.g., data is empty. 171baa73da1SPatrick Venture 172baa73da1SPatrick Venture### BmcBlobWrite (4) 173baa73da1SPatrick Venture 174baa73da1SPatrick VentureThe `BmcBlobWrite` command expects to receive a body of: 175baa73da1SPatrick Venture 176*8848c438SPatrick Williams```cpp 177baa73da1SPatrick Venturestruct BmcBlobWriteTx { 178baa73da1SPatrick Venture uint16_t crc16; 179baa73da1SPatrick Venture uint16_t session_id; /* Returned from BmcBlobOpen. */ 180baa73da1SPatrick Venture uint32_t offset; /* The byte sequence start, 0-based. */ 181baa73da1SPatrick Venture uint8_t data[]; 182baa73da1SPatrick Venture}; 183baa73da1SPatrick Venture``` 184baa73da1SPatrick Venture 185baa73da1SPatrick VentureImmediately following this structure are the bytes to write. The length of the 186baa73da1SPatrick Ventureentire packet is variable and handled at a higher level, therefore the number of 187baa73da1SPatrick Venturebytes to write is the size of the command body less the OEN and sub-command (4 188baa73da1SPatrick Venturebytes) and less the structure size (10 bytes). It is assumed that all writes are 189baa73da1SPatrick Venturesequential, and begin at offset zero. 190baa73da1SPatrick Venture 191baa73da1SPatrick VentureOn success it will return a success completion code. 192baa73da1SPatrick Venture 193baa73da1SPatrick Venture### BmcBlobCommit (5) 194baa73da1SPatrick Venture 195baa73da1SPatrick VentureThe `BmcBlobCommit` command expects to receive a body of: 196baa73da1SPatrick Venture 197*8848c438SPatrick Williams```cpp 198baa73da1SPatrick Venturestruct BmcBlobCommitTx { 199baa73da1SPatrick Venture uint16_t crc16; 200baa73da1SPatrick Venture uint16_t session_id; /* Returned from BmcBlobOpen. */ 201baa73da1SPatrick Venture uint8_t commit_data_len; 202baa73da1SPatrick Venture uint8_t commit_data[]; /* Optional blob-specific commit data. */ 203baa73da1SPatrick Venture}; 204baa73da1SPatrick Venture``` 205baa73da1SPatrick Venture 206baa73da1SPatrick VentureEach blob defines its own commit behavior. A BMC firmware blob may be verified 207826e1735SPatrick Ventureand saved to the filesystem. Commit operations may require additional data, 208826e1735SPatrick Venturewhich would be provided following the structure in the IPMI packet. 209baa73da1SPatrick Venture 210baa73da1SPatrick VentureThe commit operation may exceed the IPMI timeout duration of ~5 seconds 211baa73da1SPatrick Venture(implementation dependant). Callers are expected to poll on `BmcBlobSessionStat` 212baa73da1SPatrick Ventureor `BmcBlobStat` (as appropriate) until committing has finished. To address race 213baa73da1SPatrick Ventureconditions, blobs should not allow concurrent sessions that modify state. 214baa73da1SPatrick Venture 215baa73da1SPatrick VentureOn success, the BMC returns success completion code. 216baa73da1SPatrick Venture 217baa73da1SPatrick Venture### BmcBlobClose (6) 218baa73da1SPatrick Venture 219baa73da1SPatrick VentureThe `BmcBlobClose` command must be called after commit-polling has finished, 220baa73da1SPatrick Ventureregardless of the result. It expects to receive a body of: 221baa73da1SPatrick Venture 222*8848c438SPatrick Williams```cpp 223baa73da1SPatrick Venturestruct BmcBlobCloseTx { 224baa73da1SPatrick Venture uint16_t crc16; 225baa73da1SPatrick Venture uint16_t session_id; /* Returned from BmcBlobOpen. */ 226baa73da1SPatrick Venture}; 227baa73da1SPatrick Venture``` 228baa73da1SPatrick Venture 229baa73da1SPatrick VentureThe BMC marks the specified blob as closed. On success, the BMC returns a 230baa73da1SPatrick Venturesuccess completion code. 231baa73da1SPatrick Venture 232baa73da1SPatrick Venture### BmcBlobDelete (7) 233baa73da1SPatrick Venture 234baa73da1SPatrick VentureThe `BmcBlobDelete` command is used to delete a blob. Not all blobs will support 235baa73da1SPatrick Venturedeletion. This command expects to receive a body of: 236baa73da1SPatrick Venture 237*8848c438SPatrick Williams```cpp 238baa73da1SPatrick Venturestruct BmcBlobDeleteTx { 239baa73da1SPatrick Venture uint16_t crc16; 240baa73da1SPatrick Venture char blob_id[]; /* Must correspond to a valid blob. */ 241baa73da1SPatrick Venture}; 242baa73da1SPatrick Venture``` 243baa73da1SPatrick Venture 244baa73da1SPatrick VentureIf the operation is supported, the blob is deleted. On success, the BMC returns 245baa73da1SPatrick Venturea success completion code. This command will fail if there are open sessions for 246baa73da1SPatrick Venturethe blob. 247baa73da1SPatrick Venture 248baa73da1SPatrick Venture### BmcBlobStat (8) 249baa73da1SPatrick Venture 250baa73da1SPatrick VentureThe `BmcBlobStat` command is used to retrieve statistics about a blob. Not all 251baa73da1SPatrick Ventureblobs must support this command; this is only useful when blob_id semantics are 252baa73da1SPatrick Venturemore useful than session IDs. This command expects to receive a body of: 253baa73da1SPatrick Venture 254*8848c438SPatrick Williams```cpp 255baa73da1SPatrick Venturestruct BmcBlobStatTx { 256baa73da1SPatrick Venture uint16_t crc16; 257baa73da1SPatrick Venture char blob_id[]; /* Must correspond to a valid blob. */ 258baa73da1SPatrick Venture}; 259baa73da1SPatrick Venture``` 260baa73da1SPatrick Venture 261baa73da1SPatrick VentureThe BMC returns the following data: 262baa73da1SPatrick Venture 263*8848c438SPatrick Williams```cpp 264baa73da1SPatrick Venturestruct BmcBlobStatRx { 265baa73da1SPatrick Venture uint16_t crc16; 266baa73da1SPatrick Venture uint16_t blob_state; 267baa73da1SPatrick Venture uint32_t size; /* Size in bytes of the blob. */ 268baa73da1SPatrick Venture uint8_t metadata_len; 269baa73da1SPatrick Venture uint8_t metadata[]; /* Optional blob-specific metadata. */ 270baa73da1SPatrick Venture}; 271baa73da1SPatrick Venture``` 272baa73da1SPatrick Venture 273baa73da1SPatrick VentureThe blob_state field is a bit field with the following flags: 274baa73da1SPatrick Venture 275*8848c438SPatrick Williams```cpp 276baa73da1SPatrick Ventureenum BmcBlobStateFlagBits { 277baa73da1SPatrick Venture OPEN_R = 0, 278baa73da1SPatrick Venture OPEN_W = 1, 279baa73da1SPatrick Venture COMMITTING = 2, 280baa73da1SPatrick Venture COMMITTED = 3, 281baa73da1SPatrick Venture COMMIT_ERROR = 4, 282baa73da1SPatrick Venture <bits 5-7 reserved> 283baa73da1SPatrick Venture <bits 8-15 given blob-specific definitions> 284baa73da1SPatrick Venture}; 285baa73da1SPatrick Venture``` 286baa73da1SPatrick Venture 287baa73da1SPatrick VentureIf the state is `COMMITTING`, the blob is not currently available for reading or 288baa73da1SPatrick Venturewriting. If the state is `COMMITTED`, the blob may be available for reading. 289baa73da1SPatrick Venture 290baa73da1SPatrick VentureThe size field may be zero if the blob does not support reading. 291baa73da1SPatrick Venture 292baa73da1SPatrick VentureImmediately following this structure are optional blob-specific bytes. The 293baa73da1SPatrick Venturenumber of bytes transferred is the size of the response body less the OEN and 294baa73da1SPatrick Venturesub-command and less the structure size. The metadata must fit in a single IPMI 295baa73da1SPatrick Venturepacket, which has a platform-dependent maximum size. (For reference, Aspeed 296baa73da1SPatrick Venturesupports 64 bytes max.) 297baa73da1SPatrick Venture 298baa73da1SPatrick VentureIf the blob is open or committed but has been inactive for longer than the 299baa73da1SPatrick Venturespecified activity timeout, the blob is closed, and blob_status is set to 300baa73da1SPatrick Venture`CLOSED` in the response. 301baa73da1SPatrick Venture 302baa73da1SPatrick Venture### BmcBlobSessionStat (9) 303baa73da1SPatrick Venture 304baa73da1SPatrick VentureThe `BmcBlobSessionStat` command returns the same data as `BmcBlobStat`. 305baa73da1SPatrick VentureHowever, this command operates on sessions, rather than blob IDs. Not all blobs 306baa73da1SPatrick Venturemust support this command; this is only useful when session semantics are more 307baa73da1SPatrick Ventureuseful than raw blob IDs. 308baa73da1SPatrick Venture 309*8848c438SPatrick Williams```cpp 310baa73da1SPatrick Venturestruct BmcBlobSessionStatTx { 311baa73da1SPatrick Venture uint16_t crc16; 312baa73da1SPatrick Venture uint16_t session_id; /* Returned from BmcBlobOpen. */ 313baa73da1SPatrick Venture}; 314baa73da1SPatrick Venture``` 315baa73da1SPatrick Venture 316*8848c438SPatrick Williams```cpp 317baa73da1SPatrick Venturestruct BmcBlobSessionStatRx { 318baa73da1SPatrick Venture uint16_t crc16; 319baa73da1SPatrick Venture uint16_t blob_state; 320baa73da1SPatrick Venture uint32_t size; /* Size in bytes of the blob. */ 321baa73da1SPatrick Venture uint8_t metadata_size; 322baa73da1SPatrick Venture uint8_t metadata[]; /* Optional blob-specific metadata. */ 323baa73da1SPatrick Venture}; 324baa73da1SPatrick Venture``` 325baa73da1SPatrick Venture 3268ee139d5SPatrick Venture### BmcBlobWriteMeta (10) 3278ee139d5SPatrick Venture 3288ee139d5SPatrick VentureThe `BmcBlobWriteMeta` command behaves like `BmcBlobWrite`. Its purpose is 3298ee139d5SPatrick Ventureblob-specific, and not all blobs must support it. 3308ee139d5SPatrick Venture 3318ee139d5SPatrick VentureThe `BmcBlobWriteMeta` command expects to receive a body of: 3328ee139d5SPatrick Venture 333*8848c438SPatrick Williams```cpp 3348ee139d5SPatrick Venturestruct BmcBlobWriteMetaTx 3358ee139d5SPatrick Venture{ 3368ee139d5SPatrick Venture uint16_t crc16; 3378ee139d5SPatrick Venture uint16_t session_id; /* Returned from BmcBlobOpen. */ 3388ee139d5SPatrick Venture uint32_t offset; /* The byte sequence start, 0-based. */ 3398ee139d5SPatrick Venture uint8_t data[]; 3408ee139d5SPatrick Venture}; 3418ee139d5SPatrick Venture``` 3428ee139d5SPatrick Venture 3438ee139d5SPatrick VentureImmediately following this structure are the bytes to write. The length of the 344826e1735SPatrick Ventureentire packet is variable and handled at a higher level, therefore the number of 345826e1735SPatrick Venturebytes to write is the size of the command body less the OEN and sub-command (4 346826e1735SPatrick Venturebytes) and less the structure size. 3478ee139d5SPatrick Venture 3488ee139d5SPatrick VentureOn success it will return a success completion code. 3498ee139d5SPatrick Venture 350baa73da1SPatrick Venture## Idempotent Commands 351baa73da1SPatrick Venture 352baa73da1SPatrick VentureThe IPMI transport layer is somewhat flaky. Client code must rely on a 353baa73da1SPatrick Venture"send-with-retries" strategy to ensure that commands make their way from the 354baa73da1SPatrick Venturehost to the BMC. Commands can fail if the BMC is busy with other commands. 355baa73da1SPatrick Venture 356baa73da1SPatrick VentureIt is possible that an IPMI command successfully invokes the BMC-side handler, 357baa73da1SPatrick Venturebut that the response does not successfully make its way back to the host. In 358baa73da1SPatrick Venturethis case, the host may decide to retry the command. Thus, command handlers 359baa73da1SPatrick Ventureshould be idempotent where possible; duplicate calls should return the same 360baa73da1SPatrick Venturevalue if repeated, while avoiding potentially destructive side-effects. 361baa73da1SPatrick Venture 362baa73da1SPatrick Venture## Stale Sessions 363baa73da1SPatrick Venture 364baa73da1SPatrick VentureEach blob type will define an operation for cleansing stale sessions. This could 365baa73da1SPatrick Ventureinvolve scrubbing secrets or freeing buffers. A function will be provided that 366baa73da1SPatrick Venturewill scan over each open session, to determine which if any sessions have been 367baa73da1SPatrick Ventureopen for longer than 10 minutes with no activity. For each session, the 368baa73da1SPatrick Ventureassociated blob type’s cleansing routine will be invoked, and the associated 369baa73da1SPatrick Venturesession ID will be freed. This function will be invoked from the `BmcBlobOpen` 370baa73da1SPatrick Venturecommand handler, though not more than once every minute. 371826e1735SPatrick Venture 372826e1735SPatrick Venture## Handler Calling Contract 373826e1735SPatrick Venture 374826e1735SPatrick VentureThe blob manager provides the following calling contract guarantees: 375826e1735SPatrick Venture 376885cbfe3SPatrick Williams- The blob manager will only call `open()` on your handler if the handler 377826e1735SPatrick Venture responds that they can handle the path. 378885cbfe3SPatrick Williams- The blob manager will only call a session-based command against your handler 379826e1735SPatrick Venture if that session is already open (e.g. `stat()` or `commit()`). 380885cbfe3SPatrick Williams - The caveat is the open command where the session is provided to the handler 381885cbfe3SPatrick Williams within the call. 382885cbfe3SPatrick Williams- The blob manager will only call `delete()` on a blob if there are no open 383a67323a8SPatrick Venture sessions to that blob id. 384