Tahr.Mount.Backend behaviour (tahr v0.1.0)

Copy Markdown View Source

Behaviour for the export resolution layer the MOUNT v3 handler delegates to. Keeps Tahr decoupled from any particular backing store (a static config file, an in-memory test fixture, a database of exports, …).

The MountList and ExportNode types live in Tahr.Mount.Types.

Callbacks

  • resolve/2 — given the path a client passed to MNT, return the file-handle the server will hand back, or an error atom mapped to a mountstat3 (:perm, :noent, :notdir, :acces, …).
  • list_exports/1 — return the list of currently-published exports (used by MOUNTPROC3_EXPORT).
  • list_mounts/1 — optional bookkeeping: list the currently-active mounts (used by MOUNTPROC3_DUMP). Implementations that don't track mount state can return [].
  • record_mount/3 / forget_mount/3 / forget_all_mounts/2 — bookkeeping hooks invoked by the handler on MNT / UMNT / UMNTALL. Default-implementable as no-ops; the handler will still send the protocol-correct reply to the client either way.

Every callback receives an auth term (Tahr.RPC.Auth.credential()) and an opaque ctx map drawn from the original RPC envelope, so backend implementations can do AUTH_SYS-aware lookup decisions (uid / gid / hostname-from-AUTH_SYS) without the handler having to flatten them out.

Summary

Types

Opaque context — the handler passes the RPC ctx through.

Reasons resolve/2 may refuse with.

Callbacks

Forget all of a client's mount entries. Called on MOUNTPROC3_UMNTALL. Default no-op.

Forget one client's mount entry for path. Called on MOUNTPROC3_UMNT. Default no-op.

Return all exports currently published by the server. The handler encodes the list as the MOUNTPROC3_EXPORT reply.

Return the list of mounts the backend wants to advertise via MOUNTPROC3_DUMP. Backends that don't track mount state should return an empty list — the protocol allows that.

Record a successful mount. Called from the handler after resolve/2 returns :ok. Default no-op.

Resolve a MNT request to a file-handle.

Types

ctx()

@type ctx() :: map()

Opaque context — the handler passes the RPC ctx through.

resolve_error()

@type resolve_error() ::
  :perm | :noent | :io | :acces | :notdir | :inval | :nametoolong

Reasons resolve/2 may refuse with.

Callbacks

forget_all_mounts(client, credential)

(optional)
@callback forget_all_mounts(client :: String.t(), Tahr.RPC.Auth.credential()) :: :ok

Forget all of a client's mount entries. Called on MOUNTPROC3_UMNTALL. Default no-op.

forget_mount(client, path, credential)

(optional)
@callback forget_mount(
  client :: String.t(),
  path :: Tahr.Mount.Types.dirpath(),
  Tahr.RPC.Auth.credential()
) ::
  :ok

Forget one client's mount entry for path. Called on MOUNTPROC3_UMNT. Default no-op.

list_exports(ctx)

@callback list_exports(ctx()) :: [Tahr.Mount.Types.ExportNode.t()]

Return all exports currently published by the server. The handler encodes the list as the MOUNTPROC3_EXPORT reply.

list_mounts(ctx)

(optional)
@callback list_mounts(ctx()) :: [Tahr.Mount.Types.MountList.t()]

Return the list of mounts the backend wants to advertise via MOUNTPROC3_DUMP. Backends that don't track mount state should return an empty list — the protocol allows that.

record_mount(client, path, credential)

(optional)
@callback record_mount(
  client :: String.t(),
  path :: Tahr.Mount.Types.dirpath(),
  Tahr.RPC.Auth.credential()
) ::
  :ok

Record a successful mount. Called from the handler after resolve/2 returns :ok. Default no-op.

resolve(path, ctx)

@callback resolve(path :: Tahr.Mount.Types.dirpath(), ctx()) ::
  {:ok, Tahr.Mount.Types.fhandle3(), [non_neg_integer()]}
  | {:error, resolve_error()}

Resolve a MNT request to a file-handle.

Return {:ok, fhandle, auth_flavors} on success — auth_flavors is the list of RPC auth flavour numbers the export accepts (e.g. [1] for AUTH_SYS only).

Return {:error, reason} to refuse the mount; the handler maps reason to the RFC 1813 mountstat3 code.