Wick.Fusermount (wick v0.1.0)

Copy Markdown View Source

Mount and unmount FUSE filesystems via the fusermount3 helper.

The Linux FUSE kernel ABI requires a userspace helper for unprivileged mounts: a setuid fusermount3 binary opens /dev/fuse, performs the mount(2) syscall on behalf of the caller, and returns the resulting fd over a SCM_RIGHTS Unix socket. This module wraps that protocol.

Mount

mount/2 invokes fusermount3 via Wick.Native.fusermount3_mount/2 and returns the handle wrapping the FUSE fd, ready to use with Wick.Native.select_read/1, read_frame/1 and write_frame/2.

Unmount

unmount/1 invokes fusermount3 -u <mount_point> via an Erlang Port so that the BEAM's child-process management (through erl_child_setup) reaps the helper without colliding with SIGCHLD = SIG_IGN. The fuser crate's direct fusermount3 invocation is broken under the BEAM for exactly this reason — see the parent epic (#107) for context.

Example

{:ok, handle} =
  Wick.Fusermount.mount(
    "/tmp/my-mount",
    ["fsname=wick", "subtype=wick", "default_permissions"]
  )

# ... use the handle to drive the FUSE protocol ...

:ok = Wick.Fusermount.unmount("/tmp/my-mount")

Options

mount/2 accepts options as a list of strings; they are joined with , and passed as a single argument to fusermount3 -o. Each option is either a flag ("allow_other") or a key=value pair ("max_read=131072"). The list may be empty, in which case fusermount3 is invoked with -o "", accepting only the kernel defaults. No validation is performed here — invalid options surface as {:error, :fusermount_no_fd} from the helper.

Summary

Types

Errors returned by mount/2 and unmount/1.

Mount option list. Each entry is a string in the form "flag" or "key=value", matching the format accepted by fusermount3 -o.

Options accepted by unmount/2.

Functions

Mount a FUSE filesystem at mount_point with the given options and return a handle wrapping the /dev/fuse fd.

Unmount the FUSE filesystem at mount_point by invoking fusermount3 -u.

Types

error()

@type error() :: Wick.Native.error() | :timeout | {:fusermount, non_neg_integer()}

Errors returned by mount/2 and unmount/1.

Mount errors are the union of Wick.Native.error/0. Unmount errors include :timeout if the helper does not exit within the configured window, and {:fusermount, status} if it exits with a non-zero status (typically because the mount point is not currently mounted, or the user lacks permission).

options()

@type options() :: [String.t()]

Mount option list. Each entry is a string in the form "flag" or "key=value", matching the format accepted by fusermount3 -o.

unmount_opts()

@type unmount_opts() :: [lazy: boolean(), timeout: pos_integer()]

Options accepted by unmount/2.

  • :lazy (boolean, default false) — pass -z to fusermount3, requesting MNT_DETACH semantics. The mount is removed from the namespace immediately and finalised once all open file descriptors against it close. Use this when the caller cannot guarantee the FUSE fd has been closed before unmounting.
  • :timeout (positive integer, default 5_000) — milliseconds to wait for fusermount3 to exit before returning {:error, :timeout}.

Functions

mount(mount_point, options \\ [])

@spec mount(mount_point :: String.t(), options()) ::
  {:ok, Wick.Native.handle()} | {:error, Wick.Native.error()}

Mount a FUSE filesystem at mount_point with the given options and return a handle wrapping the /dev/fuse fd.

See the module documentation for the option format.

unmount(mount_point, opts \\ [])

@spec unmount(mount_point :: String.t(), unmount_opts()) :: :ok | {:error, error()}

Unmount the FUSE filesystem at mount_point by invoking fusermount3 -u.

See unmount_opts/0 for the supported options. With the defaults this performs a regular umount(2), which fails with EBUSY if the caller still holds the FUSE fd open — release the handle (or pass lazy: true) before calling this.