Peios Learn
Products
PePeios pkpekit PvProvium UDUniversal Directory TrTrail PrProject WiWispist
Using Peios Security Basics Technical Documentation Source
Using Peios Security Basics Technical Documentation Source
Peios

Disks and mounts

Single-page view · as markdown

mount

Peios / Using Peios / Peiosutils / Disks and mounts

mount attaches a filesystem to the Peios mount tree. With no operands it instead lists what is currently mounted. It is a faithful reworking of the util-linux mount(8) surface for Peios, with two structural differences: Peios has no /etc/fstab and no /etc/mtab, so every mount is described entirely on the command line and live mount state is read from the kernel; and a mount can apply a KACS mount policy to the new filesystem at attach time (see Mount policies).

mount [-t TYPE] [-o OPTIONS] SOURCE TARGET
mount [-o remount,OPTIONS] TARGET
mount --bind|--rbind|--move SOURCE TARGET
mount --make-shared|--make-private|... TARGET
mount [-l] [-t TYPE]

Internally mount uses the fd-based mount API (fsopen / fsconfig / fsmount / move_mount, plus open_tree and mount_setattr), never the classic single-shot mount(2). This matters in one place you can see: when a mount fails, the kernel's fs_context message log is drained and printed as the reason, even without -v.

Operands and argument shapes #

Because there is no fstab to consult, operand resolution is strict:

  • No operands, no verb — list mode (see below).
  • Two operands — SOURCE TARGET.
  • One operand — an error. In util-linux a lone operand is resolved through fstab; Peios has none, so a single operand cannot be turned into a SOURCE TARGET pair. Supply both, or use --source / --target.
  • A lone target is valid only for -o remount and for a standalone propagation change (--make-*), which act on an existing mount point.

--source SRC and --target DIR name the operands explicitly and may be combined with a single positional. --target-prefix DIR prepends DIR/ to the target after it is chosen. Options may be interspersed with operands (mount SRC -o ro TGT), matching util-linux.

Paths, -o key=value values, labels and UUIDs are handled as opaque byte strings, never assumed to be UTF-8; an embedded NUL is a usage error.

Canonicalisation #

By default source and target paths are canonicalised (made absolute, symlinks resolved). -c / --no-canonicalize disables that; X-mount.nocanonicalize[=source|target] is the -o form and can disable it for just one side. The final path handed to the kernel is protected against a TOCTOU symlink swap on its last component.

Operation modes (verbs) #

mount performs one of several operations. The structural verbs — bind, rbind, move, beneath and remount — are mutually exclusive with one another. A propagation change is not a structural verb: it may stand alone on a target, or trail another verb or a new mount in the same command (applied afterwards as one or more mount_setattr steps), and several may be combined.

VerbHow to request itWhat it does
New mountmount [-t T] SRC TGTAttach a fresh instance of the filesystem at SRC onto TGT.
Bind-B / --bind, or -o bindMake an existing subtree visible at a second location.
Recursive bind-R / --rbind, or -o rbindBind a subtree together with every mount underneath it.
Move-M / --move, or -o moveRelocate an existing mount to a new mount point.
Move beneath--beneath SRC TGTAttach SRC beneath the mount currently at TGT (the kernel enforces several constraints; violations surface as exit 32).
Remount-o remount[,...] TGTChange the options of an existing mount (see Remounting).
Propagation--make-* / --make-r*, or the -o tokens belowChange how mount/unmount events propagate across a subtree.
Listmount / mount -lPrint the current mounts.

Propagation flags #

Each of these sets the propagation type of the mount at the target. The --make-r* (and r-prefixed -o) forms apply recursively to the whole subtree; the recursive form is all-or-nothing (it either applies to the entire subtree or to none of it).

Flag-o tokenRecursive flagRecursive -o tokenMeaning
--make-sharedshared--make-rsharedrsharedEvents propagate to and from peer mounts.
--make-slaveslave--make-rslaverslaveEvents propagate in from the master but not back out.
--make-privateprivate--make-rprivaterprivateNo propagation either way.
--make-unbindableunbindable--make-runbindablerunbindablePrivate, and cannot be bind-mounted.

A freshly created mount, bind or move is private by default unless its destination's parent is shared, in which case it joins that peer group — the standard kernel rule.

Source specification #

FormResolution
Device path (/dev/sda1)Used directly.
-L LABEL / LABEL=, -U UUID / UUID=, PARTLABEL=, PARTUUID=Resolved to a device via libblkid. No match is a mount failure (exit 32).
A directory or regular fileUsed directly (a bind source or target; a file may be a bind target).
A pseudo source (tmpfs, proc, sysfs, none, …)Passed through; -t is required because it cannot be probed.
An image fileAttached through a loop device (see Loop devices).

Filesystem type #

-t TYPE names the type explicitly. -t auto, or omitting -t entirely, asks libblkid to safely probe the source; an ambiguous or multiply-signed device is refused (exit 32) rather than guessed at. X-mount.auto-fstypes=LIST constrains the probe candidates. Type lists and no<type> negation are not accepted in the mounting path (they remain meaningful only as a listing filter).

The -o option language #

-o takes a comma-separated list of key or key=value tokens and is repeatable (all occurrences are joined). A key="..." double-quoted value protects embedded commas; the key=value split is on the first =. Every token is sorted into one of the following categories.

Per-mount attributes #

Applied to the mount itself. Each accepts its negation; ro/rw additionally accept a =vfs / =fs / =recursive scope qualifier (bare is =vfs, non-recursive; =fs targets the superblock read-only flag; =recursive applies to the whole subtree).

OptionEffect
ro / rwRead-only / read-write.
suid / nosuidHonour / ignore set-user-ID bits.
dev / nodevAllow / disallow device nodes.
exec / noexecAllow / disallow execution.
atime / noatimeUpdate / never update access times.
relatime / norelatimeRelative-atime updates on or off.
strictatime / nostrictatimeStrict-atime updates on or off.
diratime / nodiratimeDirectory access-time updates on or off.
nosymfollowDo not follow symlinks on this mount. There is no positive symfollow token — the attribute is cleared only via a remount mask.

The atime tokens share a single mode field; the last one specified wins.

Superblock flags #

OptionEffect
sync / asyncSynchronous / asynchronous writes.
dirsyncSynchronous directory updates.
lazytime / nolazytimeLazy on-disk timestamp updates on or off.
iversion / noiversionInode version counting on or off.
silent / loudSuppress or emit certain kernel messages.
mand / nomandObsolete (removed from the kernel). Accepted and ignored with a note under -v.

Filesystem-specific parameters #

Any token not recognised above is forwarded verbatim to the filesystem: key=value as a string parameter, a bare key as a flag. There is no built-in allow-list and no length limit; a rejection by the filesystem is reported with the offending key and the kernel's message.

For example, StrataFS takes its precedence-ordered directory stack through strata=:

mount -t stratafs none /bin -o 'strata=/lcl/bin+create:/usr/bin+ro'

See StrataFS for the stack flags, merge and write-routing model, and the stratafs inspection command.

Userspace-only tokens #

These never reach the filesystem. They include the meta-verbs remount, bind, rbind, move; the loop controls loop / loop=/dev/loopN, offset=, sizelimit= (numeric values accept K/M/G/T and KiB/MiB/… suffixes); the propagation tokens listed above; and defaults, which expands to rw,suid,dev,exec,async (later tokens override it).

Functional X-mount.* options #

OptionEffect
X-mount.mkdir[=mode]Create the target directory if missing (default mode 0755; the alias of -m).
X-mount.subdir=DIRAttach subdirectory DIR of a freshly mounted filesystem at the target. Effective only for a new-instance mount; silently ignored (noted under -v) for bind/move/remount/propagation.
X-mount.noloopSuppress the implicit loop device for a regular-file source.
X-mount.auto-fstypes=LISTConstrain the -t auto probe to these types.
X-mount.nocanonicalize[=source|target]The -o form of -c; with =source or =target it disables canonicalisation for just that path.

X-mount.idmap and X-mount.owner / group / mode are not supported and are rejected with a usage error: Peios ownership is SID/security-descriptor based, so the fix is to add a SID/ACE to the descriptor rather than remap or chown.

KACS mount policy #

This is the genuinely Peios-specific part of mount. A mount policy is a per-superblock setting that governs how FACS treats the filesystem; the full model is described in Mount policies and its detail pages. mount can set that policy at attach time:

OptionPolicy class
-o policy=deny-missingfacs_deny_missing — a file with no SD is unreachable.
-o policy=synth-ephemeralfacs_synthesize_ephemeral — a missing SD is synthesised in memory only.
-o policy=synth-persistfacs_synthesize_persistent — a missing SD is synthesised and written back.
--synth-sddl SDDLProvide the mount-level SD template used during synthesis (only valid with a synth-* policy).

policy=unmanaged is not user-settable; only the kernel sets the unmanaged class, for its own pseudo-filesystems. policy= is valid only on a new mount of a real filesystem — combining it with bind/move/remount/propagation, or with list mode, is a usage error. See Policy classes for what each class does and SD storage by filesystem for how the SD is physically stored.

The policy is applied to the detached filesystem before it is attached: if setting it fails, nothing is ever published with an unintended policy (no rollback needed). Because setting a mount policy is a SeTcbPrivilege-gated operation (see Managing mounts), a caller without that privilege gets a clean EPERM (exit 1) and no mount. --synth-sddl is validated client-side first — it must be well-formed SDDL and must include an owner.

Peios applies no coarse uid==0 check anywhere: the mount applet is not installed set-user-ID, and every privileged action is authorised per-operation by KACS.

Remounting #

-o remount changes the options of an existing mount without detaching it. Peios does not perform the util-linux "read the old flags and re-supply them" dance — the fd-based API applies deltas rather than resetting, so each remount touches only what you name. Per-mount attributes (ro/rw, nosuid, atime, …) are changed via mount_setattr; superblock flags, filesystem parameters and ro=fs/rw=fs go through the superblock reconfigure path. =recursive remounts the whole subtree, all-or-nothing.

A bind mount shares its source's superblock, so any superblock-level option on a bind remount (a Category-B flag, a filesystem parameter, or ro=fs/rw=fs) is refused as a usage error rather than silently mutating the shared superblock for every mount of that filesystem. Only per-mount VFS attributes are valid on a bind remount.

Loop devices #

A regular-file source is backed by a loop device automatically when the type is unspecified or the filesystem is recognised by libblkid; X-mount.noloop suppresses this. -o loop forces auto-allocation of a free device, loop=/dev/loopN names one, and offset= / sizelimit= select a region of the file (they imply loop and are an error against a real block device). A backing file already attached at the same offset and size is reused rather than doubly attached, to avoid corruption. Loops created by mount are auto-cleared by the kernel on unmount, so they do not leak; umount -d force-clears the rest (see umount).

Other flags #

FlagEffect
-t, --types TYPEFilesystem type, or auto.
-o, --options LISTMount options (above); repeatable.
-r, --ro, --read-onlyMount read-only (-o ro).
-w, --rw, --read-writeMount read-write and forbid the automatic read-only fallback on a write-protected device (-o rw).
--source SRC / --target DIRName the operands explicitly.
--target-prefix DIRPrepend DIR/ to the target.
-B, --bind / -R, --rbind / -M, --move / --beneathThe structural verbs.
--make-*, --make-r*Propagation changes.
--exclusiveForce a unique superblock instance (no reuse). Meaningful only for multi-instance filesystems (e.g. tmpfs) or read-only block mounts; on an already-mounted writable block device it fails with EBUSY (exit 32).
-m, --mkdir[=MODE]Create the target directory if missing (default mode 0755).
-L, --label LABEL / -U, --uuid UUIDSelect the source by filesystem label / UUID.
-c, --no-canonicalizeDo not canonicalise paths.
-f, --fakeDry run: parse, resolve and plan everything but skip the mount syscalls and the policy step.
-v, --verboseNarrate resolved values and each syscall; drain the kernel fs_context log. Repeatable but -vv is the same as -v.
-l, --show-labelsIn list mode, append each filesystem's label.
--onlyonceSkip the mount if it is already present (a driver-aware check against live mount state, not a naive string match).
-N, --namespace NSOperate inside mount namespace NS (a PID, an ns file path, or a named namespace). Source resolution happens in the caller's namespace; the mount lands in the target namespace.
-i, --internal-onlyDo not invoke a mount.<type> helper.
-n, --no-mtabAccepted and ignored (Peios has no mtab).
--synth-sddl SDDLKACS synth-policy template SD (above).
-h, --help / -V, --versionStandard.

No external mount helpers ship in this version, so a network or FUSE type fails with "no helper for type" (exit 1) — a clean deferral, not a crash.

List mode #

With no operands, mount prints one line per mount, read from /proc/self/mountinfo:

SOURCE on TARGET type FSTYPE (OPTIONS)

mount -t TYPE with no operands filters the list by filesystem type instead of mounting; here type lists (-t ext4,xfs) and no<type> negation (-t nosysfs) are honoured. -l appends [LABEL] to each line when a label is known.

Details of the rendering: the option field is the positional VFS-then-superblock merge with a coalesced ro/rw, not sorted; mountinfo octal escapes are decoded; control characters in the mount point become ?; and the source is shown as the kernel recorded it, with /dev/loopN resolved to its backing file and /dev/dm-N to /dev/mapper/<name>. The listing shows only mounts the caller's token may observe; a partial or empty view is correct, not an error, and the paths of filtered-out parents are never reconstructed.

For a device-oriented view of what is available to mount, use lsblk.

Exit status #

CodeMeaning
0Success.
1Incorrect invocation or a permission denial — bad flags, mutually-exclusive verbs, a lone operand, an invalid policy= or --synth-sddl, an authorisation failure (EPERM/EACCES), an embedded NUL, or "no helper for type".
2System error (out of memory, no free loop device, cannot fork).
4Internal error (an invariant failure).
8Interrupted (SIGINT), after signal-safe cleanup.
32Mount failure — a syscall in the flow failed, a label/UUID had no match, a probe was undetermined, or a --beneath/move/--exclusive kernel refusal.
126An external mount.<type> helper was found but failed to execute (moot until a helper ships).

Code 16 (mtab) is never produced. Code 64 (some succeeded, some failed) only arises when several source arguments are given and at least one succeeds while another fails.

umount

Peios / Using Peios / Peiosutils / Disks and mounts

umount detaches a filesystem from the Peios mount tree. It is the counterpart of mount and, like it, reads live mount state from the kernel (/proc/self/mountinfo) rather than any /etc/mtab — Peios has none. Each operand is resolved against that live state and unmounted with umount2(2).

umount [-lfRA] [-dr] TARGET|SOURCE...

Operands and how they are resolved #

Each operand is either a mount point or a source:

  • If the (canonicalised) operand is itself a mount point in the current mount table, it is unmounted directly. This is always unambiguous.
  • Otherwise the operand is treated as a source and matched against the sources in the mount table. If it is mounted in exactly one place, that place is unmounted. If it is mounted in several places, umount refuses with an error naming the candidates — resolve it by naming a specific mount point, or use -A to unmount all of them.

If an operand matches nothing, it is "not mounted": normally an error (exit 32), but -g makes that a success and -q suppresses the message.

Several operands may be given in one invocation, and options may be interspersed with them (umount /a -f /b). Paths are handled as opaque bytes; an embedded NUL is a usage error. By default each operand is canonicalised; -c disables that and additionally selects UMOUNT_NOFOLLOW so the kernel does not follow a symlink in the final component.

Recursive and all-targets unmounts #

Two flags expand a single operand into multiple unmounts. Within one operand the expansion stops on the first failure.

  • -R / --recursive unmounts the target and everything mounted underneath it, including any over-mount stack at a single point, ordered deepest-first.
  • -A / --all-targets unmounts every mount point of the given source in the current mount namespace. This is the live-mountinfo "unmount everywhere" complement to source resolution; it is not an fstab feature.
  • -A -R together compose: for each mount point of the source, recurse underneath it.

-R and -r are mutually exclusive (combining them is a usage error, exit 1).

Flags #

FlagEffect
-l, --lazyDetach the filesystem now and clean up references later (MNT_DETACH).
-f, --forceForce the unmount (MNT_FORCE), e.g. for an unreachable server.
-R, --recursiveUnmount the target and everything under it (see above).
-A, --all-targetsUnmount every mount point of the given source (see above).
-d, --detach-loopAfter unmounting, free the backing loop device. Best-effort and verified: it clears the device only if it still backs the mount just removed, so a recycled loop number is never clobbered. Usually redundant, since mount-created loops auto-clear on unmount.
-r, --read-onlyIf the unmount fails, remount the filesystem read-only instead (via mount_setattr). Mutually exclusive with -R.
-g, --gracefulExit 0 when the target is absent or not mounted (rather than failing). Applied unconditionally.
-q, --quietSuppress "not mounted" messages.
-c, --no-canonicalizeDo not canonicalise paths; selects UMOUNT_NOFOLLOW. Applied unconditionally.
-v, --verboseSay what is being unmounted. Repeatable.
-N, --namespace NSEnter mount namespace NS (a PID, an ns file path, or a named namespace) before reading its mount table and unmounting. All work happens inside that namespace.
-n, --no-mtabAccepted and ignored (no mtab on Peios).
-i, --internal-onlyDo not invoke a umount.<type> helper (none ship).
--fakeDry run: resolve operands and report, but skip the unmount syscalls.
-h, --help / -V, --versionStandard.

The umount2 flag mapping is direct: -l → MNT_DETACH, -f → MNT_FORCE, -c (or a symlinked final component) → UMOUNT_NOFOLLOW. MNT_EXPIRE is deliberately not exposed, matching util-linux.

On privilege #

As with mount, there is no coarse uid==0 check: the applet is not set-user-ID and every unmount is authorised per-operation by KACS. Where util-linux silently suppresses an option for non-root users (-c, and -g's effectiveness), Peios applies it unconditionally.

Exit status #

CodeMeaning
0Success (or a -g no-op on an absent target).
1Incorrect invocation or a permission denial — including -R with -r, a missing operand, an ambiguous source, an embedded NUL, or an authorisation failure.
2System error (e.g. cannot read the mount table).
8Interrupted (SIGINT).
32Unmount failed, or the target is not mounted (unless -g).
64Several source/target arguments were given and at least one succeeded while another failed.
126An external umount.<type> helper was found but failed to execute (moot until a helper ships).

A single -R / -A / -A -R invocation stops on the first failure and yields 32; the aggregate 64 only appears across multiple top-level arguments. To see what is currently mounted before unmounting, use mount with no arguments or lsblk.

lsblk

Peios / Using Peios / Peiosutils / Disks and mounts

lsblk lists the block devices on the system and their relationships — disks, their partitions, and the device-mapper and loop devices layered on top. It is the device-oriented companion to mount: where mount with no arguments shows what is mounted, lsblk shows what is available to mount and what filesystem sits on each device.

lsblk [options] [DEVICE...]

By default it prints a tree, one row per device with children indented beneath their parent. Given one or more DEVICE operands (a name like sda, a full path like /dev/sda, or anything resolving to a device node), it re-roots the output at those devices.

Where the data comes from #

Each column is sourced from one of four places, and any that cannot be read degrades to an empty cell rather than aborting the run:

  • sysfs (/sys/block) — the device tree, sizes, and the topology/hardware columns. Peios leaves /sys/block unpatched, so this is the standard no-udev path.
  • libblkid — filesystem identity: FSTYPE, FSVER, UUID, LABEL, and the partition-table columns. libblkid is opened at runtime.
  • The device node's security descriptor — OWNER and MODE, read the same way ls -l reads them.
  • The /dev/disk/by-* symlink farm — ID-LINK. Populated by the device manager once it has run; there is deliberately no /run/udev/data parser, so the column reads the links themselves and is empty in the initramfs, where no device manager runs.

Output modes #

The mode selects how the rows are formatted; it does not change which columns are shown.

FlagMode
(default)Indented tree.
-l, --listFlat list — the same columns, no tree glyphs.
-J, --jsonJSON. Flag columns render as bare booleans and MOUNTPOINTS as an array; children nest under a children key.
-P, --pairsKEY="value" pairs, one device per line.
-r, --rawRaw, space-separated. Values that could contain a space or control character are hex-escaped (\xNN) so fields stay parseable.
-T, --tree[=COLUMN]Force tree output even alongside -l, optionally attaching the tree glyphs to COLUMN instead of NAME.

Columns #

With no column flag, lsblk prints the default set: NAME, MAJ:MIN, RM, SIZE, RO, TYPE, MOUNTPOINTS. Three flags swap in a preset, and -o names an explicit list (which wins over all of them):

FlagColumn set
-o, --output LISTExactly the comma-separated columns named (case-insensitive; an unknown name is a usage error).
-O, --output-allEvery available column.
-f, --fsFilesystem view: NAME, FSTYPE, FSVER, LABEL, UUID, MOUNTPOINTS.
-m, --permsPermissions view: NAME, SIZE, OWNER, MODE.

The available columns are NAME, KNAME, PATH, MAJ:MIN, FSTYPE, FSVER, LABEL, UUID, PTUUID, PTTYPE, PARTTYPE, PARTLABEL, PARTUUID, MOUNTPOINT, MOUNTPOINTS, SIZE, RO, RM, HOTPLUG, TYPE, OWNER, MODE, MODEL, VENDOR, REV, SERIAL, TRAN, HCTL, ALIGNMENT, MIN-IO, OPT-IO, PHY-SEC, LOG-SEC, STATE, ROTA, SCHED, PKNAME, and ID-LINK.

The OWNER and MODE columns #

OWNER and MODE describe the device node, not the filesystem on it, and they mirror ls -l exactly — there is no GROUP column and no POSIX permission bits, because access to a device node is governed by its security descriptor, not by a mode. OWNER is the owner SID (S-1-…); MODE is a three-character [type][x][+]: the device-type character (b for a block device, c for a character device), an x slot (never set for a block device), and a + when the DACL is inheritance-protected. When the SD cannot be read — for instance on a non-Peios host with no KACS syscalls — OWNER shows ? and MODE degrades honestly.

Filtering, sorting and shaping #

FlagEffect
-a, --allInclude empty (zero-size) devices, which are hidden by default.
-d, --nodepsDo not print a device's holders or slaves (drop the children).
-I, --include LISTShow only devices with these major numbers (comma-separated).
-e, --exclude LISTExclude devices by major number. The default is 1 (RAM disks); an explicit -e replaces that default, and -a clears exclusions entirely.
-s, --inversePrint dependencies in inverse order (holders above the devices they depend on).
-M, --mergeCollapse a subtree shared by several parents (a multipath device) to a single occurrence.
-E, --dedup COLUMNDrop rows whose COLUMN value duplicates an earlier one.
-x, --sort COLUMNSort siblings by COLUMN (numeric columns sort by value, not text).

Formatting #

FlagEffect
-b, --bytesPrint SIZE as an exact byte count instead of a human-readable value.
-p, --pathsPrint full /dev paths in the NAME column.
-n, --noheadingsOmit the header row.
-i, --asciiDraw the tree with ASCII characters instead of box-drawing glyphs.
-y, --shellRender column keys shell-safe (MAJ:MIN becomes MAJ_MIN).
-w, --width NUMTruncate each table row to NUM columns wide.
--sysroot DIRRead sysfs, the mount table and /dev from DIR instead of / (chiefly for testing against a fixture).
-h, --help / -V, --versionStandard.

Exit status #

CodeMeaning
0Success.
1Incorrect invocation (an unknown column, a malformed major-number or width value) or a failed run (for example, /sys/block is unreadable).

lsblk uses this single non-zero code, matching util-linux. A per-device read failure is not fatal: it degrades the affected columns to empty or ? and the run continues. A broken output pipe (piping into head, for instance) is treated as success.

Peios Learn — documentation for the Peios project.

Built with Trail.