Mercurial > nomad
view docs/fs-protocol.md @ 878:fe84110a0b10
common: extend LINK to include more args and a return value
These should have been part of the RPC from the beginning. Since nothing
implements LINK yet, we can modify it without dealing with protocol version
issues.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Sat, 17 Dec 2022 16:32:57 -0500 |
parents | 7f967ffda1ac |
children |
line wrap: on
line source
This document describes the RPC protocol between the client daemon and the fs component. It is still a work-in-progress. Currently, we use `rpcgen(1)` created XDR encoding. Before RPC requests are accepted the initiator sends a handshake request using `struct rpc_handshake_req`. The response uses `struct rpc_header_res` with success (status code 0) if the version is supported, at which point the initiator may send RPC requests. On error the initiator must close the connection without sending more data. ```C struct rpc_handshake_req { uint32_t version; }; ``` Each RPC request begins with a `struct rpc_header_req`. It is then followed by a variable number of bytes representing the rest of the request. The exact layout of this additional payload depends on the `opcode` in the request header. ```C struct rpc_header_req { uint16_t opcode; }; ``` Each RPC reply starts with a `struct rpc_header_res` which contains a status code. In the case of success (status code is 0), more data may follow depending on the `opcode` in the request header. ```C struct rpc_header_res { uint32_t err; }; ``` The following list of RPC commands does not explicitly list the request and response headers since they are always present. It only lists the additional fields that follow. NOP (0x0000) ============ This is a simple no-operation. Inputs ------ None. Output ------ None. Limitations ----------- None. LOGIN (0x0001) ============== The first command sent to the client daemon by the fs component. It informs the daemon of a mount request. Eventually, this will also contain credentials checking, etc. (hence the name). Inputs ------ * conn name * volume id (uuid) Outputs ------- * oid of root Limitations ----------- At most one successful LOGIN is allowed per connection. All LOGIN attempts after a successful LOGIN will fail with `EALREADY`. GETATTR (0x0002) ================ Get attributes (`struct nattr`) for of an object identified an open file handle. Inputs ------ * open file handle Outputs ------- * attributes Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. LOOKUP (0x0003) =============== Given a directory open file handle and a path component (string), do a lookup of the path component in the directory. Inputs ------ * directory open file handle * path component name Outputs ------- * child oid Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. CREATE (0x0004) =============== Given a directory open file handle, a path component (string), and mode (both type and access bits) create the new path component returning the oid of the newly created file. Creating an already existing path component fails with `EEXIST`. Inputs ------ * directory open file handle * path component name * owner id (uid) * group id (gid) * mode (see `NATTR_*`) Outputs ------- * new file/dir/etc.'s oid Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. LINK (0x0005) ============= Given a directory open file handle, a path component (string), a target path (string), and a symlink bool add a link to the directory making the path component refer to the file at the target path as either a hardlink or a symlink. Hard-linking to a non-existent path fails with `ENOENT`. If a non-null desired oid is specified, only the dirent matching the oid is considered as a target. If a null oid is specificied and there is only one dirent under that name (in other words, there is no conflict), the dirent is use as the target. If a null oid is specified and there are multiple dirents with the same name, the operation fails with `ENOTUNIQ`. Symlinks have their own owner, group, and mode. The returned oid is used only for symlinks. Inputs ------ * directory open file handle * path component name * target path * desired target oid * symlink * symlink owner * symlink group * symlink mode Outputs ------- * new symlink oid Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. UNLINK (0x0006) =============== Given a directory open file handle, a path component (string), and an optional desired target oid, remove the corresponding path component from the directory. Removing a non-existent path component fails with `ENOENT`. If a non-null desired oid is specified, only the dirent matching the oid is considered for removal. If a null oid is specificied and there is only one dirent under that name (in other words, there is no conflict), the dirent is removed. If a null oid is specified and there are multiple dirents with the same name, the operation fails with `ENOTUNIQ`. The rmdir bool specifies whether the operation is a rmdir (true) or unlink (false). Inputs ------ * directory open file handle * path component name * desired target oid * rmdir semantics Outputs ------- None. Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. OPEN (0x0008) ============= Given a version of an object (oid and vector clock, or inode number and vector clock), open the specified object and return an open file handle. If a non-null vector clock is specified, only that version of the object is considered. If a null vector clock is specificied and there is only one version of the object, the attributes of that version are returned. If a null vector clock is specified and there are multiple version of the object, the operation fails with `ENOTUNIQ`. Inputs ------ * oid * inode number * vector clock Outputs ------- * open file handle Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. CLOSE (0x0009) ============== Close an open file handle. If the handle supplied has not be open via the OPEN RPC, this operation fails with `EINVAL`. Inputs ------ * open file handle Outputs ------- None. Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. READ (0x000A) ============= Read a portion of an open object. Trying to read from a directory fails with `EISDIR`. If the requested number of bytes would read beyond the end of the object, only the data between the requested offset and the end of the object is returned. (Therefore, reading with an offset that is greater than or equal to the object size will yield zero bytes.) Inputs ------ * open file handle * offset into the object version's data * length (in bytes) to read Outputs ------- * length of data * data Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. WRITE (0x000B) ============== Write a portion of an open object. Trying to write to a directory fails with `EISDIR`. Writing past the end of the object succeeds and the object length is updated automatically. The whole write is guaranteed to succeed. Inputs ------ * open file handle * offset into the object version's data * length (in bytes) to write * data Outputs ------- None. Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. SETATTR (0x000C) ================ Set selected attributes on an open object. Even though the entire attribute structure is sent, only the attributes marked as valid are set. Setting the file size either truncates the object to the specified size or extends it padding it with zero bytes. Inputs ------ * open file handle * new attributes (`struct nattr`) * mode is valid * size is valid * atime is valid * btime is valid * ctime is valid * mtime is valid * owner is valid * group is valid Outputs ------- * full set of attributes Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. GETDENT (0x000D) ================ Get the directory entry at a specific offset in a directory. Additionally, it returns the size of the current entry. Adding this size to the current offset will yield the offset of the next entry. Inputs ------ * directory open file handle * directory offset Outputs ------- * child oid * child name * entry size Limitations ----------- Fails with `EPROTO` if the client hasn't gotten a successful LOGIN. OBJ_INFO (0x000E) ================= Get information about an object. Inputs ------ * oid Outputs ------- For each version of the object: * vector clock VDEV_IMPORT (0x0100) ==================== Import or create a vdev. Inputs ------ * type of vdev (e.g., posix or mem) * path * create volume bool (true = create, false = import) Outputs ------- * vdev uuid VDEV_LIST (0x0101) ================== List currently imported vdevs. Inputs ------ None. Outputs ------- For each imported vdev: * uuid * type * path * size (bytes) * used (bytes) * number of volumes VOL_CREATE (0x0200) =================== Create or clone a volume. If the supplied volume uuid is null, a new volume is created on the specified vdev. The new volume's uuid is returned. If the supplied volume uuid is not nul, a clone of the volume onto the specified vdev is performed. The returned volume uuid will match the input. Inputs ------ * vdev uuid * volume uuid Outputs ------- * volume uuid VOL_LIST (0x0201) ================= List volumes managed by the server - all or on a specific vdev. Inputs ------ * vdev uuid (clear to indicate all vdevs) Outputs ------- For each loaded volume matching the uuid criteria: * uuid Other RPCs that may end up useful ================================= * RENAME - rename a "file"