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
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
@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).
@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.
@type unmount_opts() :: [lazy: boolean(), timeout: pos_integer()]
Options accepted by unmount/2.
:lazy(boolean, defaultfalse) — pass-ztofusermount3, requestingMNT_DETACHsemantics. 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, default5_000) — milliseconds to wait forfusermount3to exit before returning{:error, :timeout}.
Functions
@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.
@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.