LinuxXV · /etc/fstab and Mount ManagementMount units
Mount units by hand, and verifying a mount change before you reboot
What you'll learn
- Decide between an fstab line and a hand-written .mount unit
- Name a mount unit correctly with systemd-escape and know why the name is not cosmetic
- Translate fstab-only options into their unit equivalents
- Verify a unit with systemd-analyze verify and read its exit status honestly
- Test a mount transiently with systemd-mount before making it persistent
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11
Everything in /etc/fstab becomes a .mount unit anyway. The
generator does the translation and drops the result in
/run/systemd/generator/. Writing the unit yourself skips the
translation - which buys you things fstab cannot express, and
costs you options that only exist on the fstab side.
The other half of this lesson is the part that gets skipped: a mount change is untested until the host reboots, and there is a short list of checks that catch everything except the timing.
When the unit form is worth it
fstab is one file, shared by every team that touches the host,
edited by hand, and read only at boot and on daemon-reload. It
is the right place for the base filesystems of the machine.
A .mount unit is a file of its own, which means it can be
shipped by configuration management alongside the service that
needs it, removed with that service, and given dependencies that
fstab has no column for:
| You need | fstab | .mount unit |
|---|---|---|
| Order the mount after a specific service | x-systemd.after= (workable) | After= (direct) |
| Refuse to mount unless a condition holds | not available | ConditionPathExists=, ConditionKernelCommandLine= |
| Ship the mount with the application, not with the host | no | yes - one file, one owner |
| Bound the wait for the device | x-systemd.device-timeout= | explicit After=/Requires= on the .device unit |
| Bound the mount attempt | x-systemd.mount-timeout= | TimeoutSec= |
The unit, and the name that is not cosmetic
man 5 systemd.mount states the rule flatly: mount units must
be named after the mount point directories they control, using
systemd’s path escaping. Do not compute the name in your head.
$ systemd-escape -p --suffix=mount /var/lib/postgresql/16/mainvar-lib-postgresql-16-main.mount# /etc/systemd/system/srv-data.mount
[Unit]
Description=Application data volume
Documentation=man:systemd.mount(5)
After=iscsi.service
Requires=iscsi.service
[Mount]
What=/dev/disk/by-uuid/8f2c1b7a-3d4e-4f50-a611-2b3c4d5e6f70
Where=/srv/data
Type=xfs
Options=noatime,nodev,nosuid
TimeoutSec=45s
[Install]
WantedBy=remote-fs.target
Four things in that file are load-bearing:
Where=must match the unit filename. systemd refuses to load the unit otherwise; the check below shows exactly what the refusal looks like.What=should be a stable path./dev/disk/by-uuid/...or/dev/disk/by-id/..., never/dev/sdb1- the same rule as fstab, for the same reason.TimeoutSec=is the unit-side equivalent ofx-systemd.mount-timeout=.man 5 systemd.mountsays bothx-systemd.mount-timeout=andx-systemd.device-timeout=are ignored when they appear in a unit’sOptions=line, so copying an fstab option string into a unit quietly drops them.[Install] WantedBy=is what makes it start at boot. Leave it out and the unit works perfectly when you start it by hand and never starts on its own.
Verifying before the reboot
systemd-analyze verify loads a unit file exactly as systemd
would, plus everything it references, and reports what it finds.
It runs against a file path, so you can check a unit before it
is installed anywhere.
$ systemd-analyze verify /etc/systemd/system/srv-data.mount/etc/systemd/system/srv-data.mount:10: Unknown key 'TimeoutSecs' in section [Mount], ignoring.$ systemd-analyze verify /etc/systemd/system/data.mountdata.mount: Where= setting doesn't match unit name. Refusing.
Unit data.mount has a bad unit file setting.The full pre-reboot sequence
- systemd-analyze verify on the unit file, or sudo findmnt --verify --verbose for an fstab change. Catches syntax, unknown directives, bad unit names, missing mount points.
- sudo systemctl daemon-reload. Without this, systemd is still working from the previous version of the file - and for an fstab change, from the previous run of the generator.
- systemctl cat srv-data.mount. Read back what systemd now believes, not what you wrote. The options, the After= lines and the TimeoutSec must all be there.
- sudo systemctl start srv-data.mount, then findmnt /srv/data. Proves the mount works now, with the network up and every device enumerated.
- systemctl is-enabled srv-data.mount. Proves it will be started at the next boot rather than only by hand.
- Reboot, inside a window, with console access. This is the only step that can catch a timing failure, and it is the step that is always skipped.
Steps 1 to 5 eliminate the syntax class of failure completely. They eliminate none of the timing class - a device that enumerates late, a filer that is slow to answer, a mount whose parent is not yet mounted. Only a boot exercises those, because only at boot is the system in the state where they happen.
Automount units
An .automount unit is a separate file that sits in front of a
.mount unit of the same name. Enable and start the
.automount; the .mount is triggered on first access.
# /etc/systemd/system/srv-archive.automount
[Unit]
Description=On-demand archive share
[Automount]
Where=/srv/archive
TimeoutIdleSec=600
[Install]
WantedBy=remote-fs.target
The .mount unit with the same name must still exist - the
automount only supplies the trigger. Enable the .automount,
not the .mount; enabling both means the filesystem is mounted
at boot and has an idle trigger, which is not what anyone
intends.
sudo systemctl enable --now srv-archive.automount
systemctl list-units --type=automount
Knowledge check
Knowledge check · 4 questions
Q1. You copy an fstab option string, including x-systemd.mount-timeout=30, into the Options= line of a hand-written .mount unit. What happens?
Q2. A zero exit status from systemd-analyze verify means the unit file contains no problems.
Q3. Which checks can be run on a live host and will catch a defective mount change before the reboot? Select all that apply.
Q4. An fstab line and a hand-written unit both describe /srv/data, with different options. Which one takes effect, and why?
Passing score: 75%. Answers are checked in this browser.