xref: /openbmc/phosphor-ipmi-blobs/README.md (revision 8848c4384c639696a0a2c3f30badb545b364acec)
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