volumes::fuse_serve
Tag 8: a client names a volume from its listing and a cap for an ephemeral layer; the server holds the volume as a mount holds it, answers Serving once, and for as long as the scope lives answers on channels the client opens the nine asks a FUSE mount makes, from the volume as its mode allows, a piece at a time, and streams the tree of the volume as served; the client stops the scope.
A client opens the scope with a request whose payload is the tag byte
8 followed by the name of a volume and overlay_disk. The server
sends exactly one response, which is Serving, one of five
refusals, or an error.
After Serving the scope stays open: the client opens on it, as
channels, the nine asks a FUSE mount makes of a client — a stat, a
read of a piece, a write of a piece, a truncate, a setattr, a listing,
a removal, a rename and a mkdir — and the server answers each from
the volume, as the volume’s mode allows. The client’s stop ends the
scope: the response finish follows the last answer, and no frame
follows the finish. After a refusal or an error the response finish
follows it, and no channel is served.
- The request. The request carries the name of one volume and
overlay_disk, the cap of the layer an ephemeral volume is served on. Request states its form. - The volume named. The client names a volume by the
nameits volumes::list listing gave it. The server resolves the name against the identity under which the connection was authorized, as Authorization provides. A name that is not in the client’s listing is answered with an error. A client cannot name another client’s volume. - The response. Response states the one response and what follows it.
- The channels. The client opens the channels that Client Channels defines: the nine asks, the stop, and the filetree. The server opens no channel on a FUSE serve scope.
- The tree as served. A filetree
channel carries the tree of the volume as this FUSE serve sees it — for
an
ephemeralvolume, the volume under the layer of the FUSE serve — as a snapshot, followed by one channel response per change the asks of this FUSE serve make, until the scope ends. Aread_onlyvolume’s stream is the snapshot and nothing after it. Novolumes::filetreeof a served volume is answered while the FUSE serve holds it; the filetree channel is the one view of a served volume’s tree. - A served volume is a mounted volume. The server holds the volume
as a running container that mounts it holds it, from the moment it
sends
Servinguntil the response finish. While it holds it, avolumes::stat,volumes::read,volumes::write,volumes::filetree,volumes::editorvolumes::deletenaming the volume is answered with that endpoint’sFuseServed. A volume that is under one of those six at the time of the request is not served: the request is answered withHeld, the byte3. - Who may hold a served volume. The volume’s
mode, as the listing reports it, says at most: anephemeralor aread_onlyvolume may be held by any number of FUSE serves and any number of running containers at once, and apersistentvolume by one FUSE serve at a time, never beside a running container. What this server allows for each mode is the mode object it holds out:fuse_serve,fuse_serve_manyandmount_and_fuse_serve. A volume of a mode the server holds out no mode object for, or whose mode object hasfuse_servefalse, is not served: the request is answered withUnsupported, the byte5. A volume another FUSE serve holds, wherefuse_serve_manyisfalse, is answered withFuseServed, the byte2; a volume a running container holds, wheremount_and_fuse_serveisfalse, is answered withMounted, the byte1. The server decides the refusals in the order Capabilities states for a FUSE serve; a run naming a volume a FUSE serve holds is refused as containers::agents::run states. - No volume at all. A server that holds out none of the three
mode objects answers every request of this endpoint with
Unsupported, the byte5, before anything is looked up, as Capabilities provides. - The request states the mode. A FUSE serve names the
modeit means the volume to have. The server compares it with the volume’smodeafter it holds the volume: a volume in another mode is not served, the request is answered with the mode the volume is in, the hold is given back, and nothing changes. A FUSE serve never changes a volume’s mode; only volumes::edit does. - The asks are the mount’s. Each ask is, byte for byte, the ask a FUSE mount’s scope carries on the container proxy, with no id: the scope is the volume, as the mount scope is the mount. Each answer is the answer that ask defines. A client that bridges a FUSE mount on one provider to a volume on another relays each ask and each answer as it is.
- Every piece crosses as it is. A read is one piece at an offset,
a write lands one piece in place, and a stat is the entry’s kind,
size, mode, owner, group and times as the volume records them at the
time of the answer. The server buffers no content of the volume on
the client’s behalf: what a write asks for is in the volume, or in
the FUSE serve’s layer, when the answer is
ok. - Asks in flight at once. A client may have any number of asks open at once. The server answers each on its own channel, in whatever order it answers them.
- The three modes. A
persistentvolume is changed in place: every mutation the server answersokis in the volume. Anephemeralvolume is served on a layer of the FUSE serve’s own: the serve starts from the volume as it is, every mutation the server answersokis in the layer and is seen by every later ask of the same FUSE serve, nothing of the layer is in the volume, and the layer is discarded at the finish; the layer holds at mostoverlay_diskbytes, a mutation that would need room past that is answered with an error and the volume and the layer are as they were, and the serve continues. Aread_onlyvolume answers every stat, read and listing as any volume does, and answers every write, truncate, setattr, removal, rename and mkdir with the read-only byte: the change is refused, and the volume is as it was. - The stop. The client ends the scope by opening the stop channel. The server answers every ask still open, sends the response finish, and gives the volume back. The server sends nothing on the stop’s own channel. A connection that closes with a FUSE serve scope open ends the scope the same way: the server gives the volume back.
- The error. An error states that the volume is not served, and
that nothing was determined about the volume. A volume absent from
the client’s listing, an
ephemeralvolume whoseoverlay_diskthe server cannot set aside, and a volume the server could not open are each answered with an error. A volume that something holds, a volume not in the mode the request means, and a volume of a mode the server does not FUSE serve are each answered with the refusal the response states for it, which is not an error.