Create and Verify a systemd Mount Unit
You will create a native systemd mount unit for a bind mount, check that its filename matches the destination path, start it, verify the result, and remove it again. The examples target systemd 255.4-1ubuntu8.17 on a Debian-family system.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, systemd, and a source directory that already exists. The workflow changes the live mount table and writes under /etc/systemd/system, so commands marked sudo require elevated privileges. Do not use the example paths if they contain data that must remain private or untouched.
1. Decide whether you need a unit file
For a human-managed persistent mount, /etc/fstab is generally the preferred configuration. A native .mount file is useful when tooling owns the configuration, when you need unit dependencies, or when the mount belongs with other systemd units. This guide uses a native unit and a bind mount because it does not require formatting or partitioning a block device.
A bind mount exposes an existing directory at another path. It does not copy files. Starting the unit changes what applications see below the destination, and stopping it removes that view. Check the source and destination carefully before starting anything:
$ test -d /srv/project-data && echo source-is-a-directory
source-is-a-directory
$ test ! -e /mnt/project-data && echo destination-is-free
destination-is-free
If either check fails, stop and choose paths you have authority to use. Do not create the destination just to hide a path mistake. A mount unit can create a missing mount point, and that automatic creation does not make an incorrect path safe.
2. Derive the unit filename from Where=
The unit name is not arbitrary. It must encode the mount point, with the escaping rules used by systemd. For /mnt/project-data, ask the installed tool for the exact name:
$ systemd-escape --path --suffix=mount /mnt/project-data
mnt-project\x2ddata.mount
The backslash sequence is part of the filename. Create the file with that exact name. A unit called project-data.mount can contain otherwise valid settings and still control nothing because it does not represent the path in Where=.
Checkpoint: the destination in this guide maps to mnt-project\x2ddata.mount. If you change Where=, repeat this step rather than editing the old name by intuition.
3. Write the [Mount] configuration
Create the unit as root. The mandatory settings are What= and Where=. Type=none describes this bind-mount invocation, and Options=bind passes the mount option to mount(8):
$ sudo install -d -m 0755 /etc/systemd/system
$ sudo tee '/etc/systemd/system/mnt-project\x2ddata.mount' > /dev/null <<'UNIT'
[Unit]
Description=Project data bind mount
[Mount]
What=/srv/project-data
Where=/mnt/project-data
Type=none
Options=bind
DirectoryMode=0755
[Install]
WantedBy=multi-user.target
UNIT
DirectoryMode= controls directories systemd creates for the mount point and its parents. It does not change the permissions of the existing source directory. The [Install] section only supplies enablement metadata; it does not start the unit by itself.
Do not add User= or Group= here. The systemd.mount manual says they are not useful for mount units because systemd invokes mount(8) as UID 0.
4. Validate before touching the live mount table
Reload the manager's unit files, then ask systemd to parse and verify the unit. These commands do not mount the filesystem:
$ sudo systemctl daemon-reload
$ systemd-analyze verify '/etc/systemd/system/mnt-project\x2ddata.mount'
A clean systemd-analyze verify normally prints nothing and returns status 0. Check that explicitly if you are putting this into a script:
$ printf 'verify status: %s\n' "$?"
verify status: 0
If verification reports a missing source or an invalid option, fix the unit before starting it. Syntax validation cannot prove that the source contains the data you expect, nor can it prove that every mount option is suitable for the filesystem.
5. Start the mount and inspect the result
Starting a mount changes system state. Confirm the unit name and destination once more, then start it:
$ sudo systemctl start mnt-project\x2ddata.mount
$ systemctl status --no-pager mnt-project\x2ddata.mount
The status should show Active: active (mounted). The exact timestamps and process details vary. Verify the kernel's view as well:
$ findmnt --mountpoint /mnt/project-data
TARGET SOURCE FSTYPE OPTIONS
/mnt/project-data /srv/project-data none rw,bind
Column spacing and the complete option list may differ. The useful checks are the target, the source, and a successful command exit status. If the start fails, read the unit's journal without repeatedly retrying:
$ sudo journalctl -u mnt-project\x2ddata.mount -b --no-pager
6. Choose boot behaviour deliberately
The unit can be enabled so systemd pulls it in during normal boot:
$ sudo systemctl enable mnt-project\x2ddata.mount
Created symlink ...
The symlink path and exact message vary. Because the unit has WantedBy=multi-user.target, enablement records a boot relationship; it does not replace the verification you performed. If this mount must not delay or affect boot when unavailable, review nofail and the related dependency behaviour before using it. For a mount that should appear only when accessed, consider an accompanying .automount unit instead.
Network mounts need extra care. systemd classifies mounts from their filesystem type, but _netdev can force network-mount ordering when that detection is insufficient. Do not copy that option into this local bind-mount example.
7. Stop and remove the example cleanly
When you have finished testing, undo the live change before removing the unit file:
$ sudo systemctl disable --now mnt-project\x2ddata.mount
Removed ...
--now stops the mounted unit and disables its boot link. Check that it is no longer mounted:
$ findmnt --mountpoint /mnt/project-data
$ printf 'findmnt status: %s\n' "$?"
findmnt status: 1
The non-zero status is expected when no mount remains at that path. Only after that check should you remove the unit file and reload systemd:
$ sudo rm '/etc/systemd/system/mnt-project\x2ddata.mount'
$ sudo systemctl daemon-reload
Removing the unit file does not delete /srv/project-data. It also does not necessarily remove the empty mount-point directory that systemd created. Inspect /mnt/project-data before deleting it, and never use a broad recursive deletion to tidy up a mount point.
Done means
- The unit filename was generated from the exact
Where=path. What=andWhere=point to paths you checked first.systemd-analyze verifyreturned status 0 before the mount was started.systemctl statusandfindmntconfirmed the active source and destination.- Boot enablement was an explicit choice, not an accidental side effect.
- The test mount was stopped before its unit file was removed.