Table of Contents
Systemd, the modern and powerful system and service manager for Linux, has become an essential component of many distributions, replacing traditional init systems. With its extensive capabilities and integration with numerous system processes, systemd simplifies the management of services, daemons, and system resources, including the mounting and unmounting of partitions.
In this tutorial, we will explore how to mount partitions using systemd unit files. This approach provides a reliable and efficient way to manage storage devices and their mount points, especially during system boot. We will guide you through the process of creating and configuring systemd unit files, ensuring that your partitions are mounted correctly and automatically, regardless of the complexity of your storage setup. By the end of this tutorial, you will have a solid understanding of the benefits of utilizing systemd unit files for partition management, and you will be able to implement these techniques in your own Linux systems.
Understanding systemd unit files
A systemd unit file consists of sections, each enclosed within square brackets (e.g.,
[Mount]). Each section contains key-value pairs, representing configuration options and their respective values. The options and their syntax depend on the type of unit file being defined. Comments in unit files start with a semicolon (
;) or a hash symbol (
There are several types of unit files, each serving a specific purpose:
- Service units: Define system services (e.g., web servers, databases) and their behavior. These units have a
- Mount units: Define filesystem mount points and their properties. These units have a
.mountfile extension and are the focus of this discussion.
- Automount units: Configure on-demand mounting of filesystems. These units have a
- Device units: Represent kernel devices and expose them to systemd. These units have a
- Target units: Group other units under a single unit for synchronization and ordering purposes. These units have a
- Socket units: Define inter-process communication (IPC) sockets for socket-based activation. These units have a
- Timer units: Schedule the activation of other units based on time or calendar events. These units have a
- Swap units: Manage swap devices or files. These units have a
- Path units: Monitor file system changes and activate other units based on these changes. These units have a
- Slice units: Organize system processes into a hierarchical tree for resource management. These units have a
Mount units are responsible for managing filesystem mount points in a systemd-managed system. The mount unit file defines the properties of a mount point, such as the partition to be mounted, the target mount point, the filesystem type, and mount options. Systemd automatically generates mount units for entries in
/etc/fstab, but you can also create custom mount unit files to gain more control over the mounting process.
The primary sections and options in a mount unit file are:
[Unit]: Contains general information about the unit, such as
Descriptionand dependency directives like
[Mount]: Specifies the configuration options for the mount point, such as
What(device or partition),
Type(filesystem type), and
Steps to mount partition using systemd unit file
Step-1: Identify the partition
Use a tool like
blkid to identify the partition you want to mount. Note its UUID, device path (e.g., /dev/sdb1), and filesystem type (e.g., ext4).
Step-2: Choose the mount point
Determine the desired mount point for the partition (e.g., /mnt/data).
Step-3: Create the mount unit file
The mount unit file should be named after the mount point, with slashes replaced by hyphens and the
.mount extension added (e.g., mnt-data.mount). Create the file in the
/etc/systemd/system/ directory using your preferred text editor:
[root@rhel-8 system]# pwd /usr/lib/systemd/system
For the sake of this article I will again show the output snippet of my
tmp_dir.mount which I created in my older article
[root@rhel-8 system]# cat tmp_dir.mount # This file is part of systemd. [Unit] Description=Test Directory (/tmp_dir) DefaultDependencies=no Conflicts=umount.target Before=local-fs.target umount.target After=swap.target [Mount] What=/dev/disk/by-uuid/cea0757d-6329-4bf8-abbf-03f9c313b07f Where=/tmp_dir Type=ext4 Options=defaults [Install] WantedBy=multi-user.target
Description: A brief description of the mount unit.
Requires: (Optional) List other units that must be started before this mount unit.
Before: (Optional) Specify the order in which the units should be started or stopped.
What: The device or partition to be mounted, preferably using the UUID (e.g., UUID=1234-5678-9ABC).
Where: The target mount point (e.g., /mnt/data).
Type: The filesystem type (e.g., ext4).
Options: Mount options, separated by commas (e.g., defaults,noatime).
Step-4: Create the automount unit file
Automount units must be named after the automount directories they control. Example: the automount point
/home/lennart must be configured in a unit file
home-lennart.automount. Here my mount point is under root directory hence my automount systemd unit file will be
To enable automounting, create a corresponding automount unit file with the
.automount extension. Below is my sample automount systemd unit file to automount file system
[root@rhel-8 system]# cat tmp_dir.automount [Unit] Description=Sample automount partition ConditionPathExists=/tmp_dir [Automount] Where=/tmp_dir TimeoutIdleSec=10 [Install] WantedBy=multi-user.target
Where:Takes an absolute path of a directory of the automount point. If the automount point does not exist at time that the automount point is installed, it is created. This string must be reflected in the unit filename. This option is mandatory.
DirectoryMode: Directories of automount points (and any parent directories) are automatically created if needed. This option specifies the file system access mode used when creating these directories. Takes an access mode in octal notation. Defaults to 0755.
TimeoutIdleSec: Configures an idleness timeout. Once the mount has been idle for the specified time, systemd will attempt to unmount. Takes a unit-less value in seconds, or a time span value such as "5min 20s". Pass 0 to disable the timeout logic. The timeout is disabled by default.
ConditionPathExists: a file existence condition is checked before a unit is started. If the specified absolute path name does not exist, the condition will fail. If the absolute path name passed to ConditionPathExists= is prefixed with an exclamation mark ("!"), the test is negated, and the unit is only started if the path does not exist.
I have given 10 seconds as the timeout period so that I don't have to wait longer to demonstrate you the behaviour.
Once you have created your automount systemd unit file to automount file system, reload the systemd daemon
[root@rhel-8 system]# systemctl daemon-reload
/tmp_dir is not in mounted state or else
tmp_dir.automount service will fail to start the service to automount file system.
Dependency with /etc/fstab
When using systemd, the
/etc/fstab file still plays an essential role in managing dependencies and mounting partitions. During the boot process, systemd reads
/etc/fstab and automatically generates transient mount and automount unit files for each entry. This allows systemd to mount the partitions specified in
/etc/fstab while honoring the traditional configuration.
However, creating custom mount unit files as described earlier gives you more control and flexibility over the mounting process, especially when it comes to handling dependencies and custom options.
When you have a combination of
/etc/fstab entries and custom mount unit files, systemd prioritizes the custom unit files. If there is a conflict between a custom mount unit file and an
/etc/fstab entry, the custom unit file will take precedence.
To manage dependencies between mount units generated from
/etc/fstab and other services, you can use the
x-systemd.before mount options in the
x-systemd.requires: Similar to the
Requiresdirective in a custom mount unit file, it specifies that the listed units must be started before this mount point.
x-systemd.after: Similar to the
Afterdirective, it indicates that this mount point should be mounted only after the listed units have started successfully.
x-systemd.before: Similar to the
Beforedirective, it specifies that this mount point should be mounted before the listed units.
Step 5: Start systemd service
Now let us start
[root@rhel-8 system]# systemctl start tmp_dir.automount
Let us check the service status. As it shows the service is running but is in
(waiting) state since we had given a Time Out value of 10 seconds for idle session
[root@rhel-8 system]# systemctl status tmp_dir.automount ● tmp_dir.automount - Sample automount partition Loaded: loaded (/usr/lib/systemd/system/tmp_dir.automount; disabled; vendor preset: disabled) Active: active (waiting) since Mon 2019-09-16 18:45:59 IST; 6s ago Where: /tmp_dir Sep 16 18:45:59 rhel-8.example systemd: Set up automount Sample automount partition.
mountcommand will still not show
/tmp_diras mounted yet because automount will mount this filesystem only once someone attempts to access the mount point which is the beauty of this service.
As you see
df command does not shows
/tmp_dir partition yet
[root@rhel-8 ~]# df -h Filesystem Size Used Avail Use% Mounted on devtmpfs 900M 0 900M 0% /dev tmpfs 915M 0 915M 0% /dev/shm tmpfs 915M 8.5M 907M 1% /run tmpfs 915M 0 915M 0% /sys/fs/cgroup /dev/mapper/rhel-root 15G 2.1G 12G 16% / /dev/sdc1 976M 2.6M 907M 1% /second_part /dev/sda1 483M 258M 225M 54% /boot tmpfs 183M 0 183M 0% /run/user/0
Now if I access this partition using
df command explicitly
[root@rhel-8 ~]# df -h /tmp_dir/ Filesystem Size Used Avail Use% Mounted on /dev/sdb1 976M 2.6M 907M 1% /tmp_dir
then the partition will get mounted automatically.
Also if you check the service status, the output snippet will give you a hint of what was happening in the backend
[root@rhel-8 ~]# systemctl status tmp_dir.automount ● tmp_dir.automount - Sample automount partition Loaded: loaded (/usr/lib/systemd/system/tmp_dir.automount; disabled; vendor preset: disabled) Active: active (waiting) since Mon 2019-09-16 18:45:59 IST; 17min ago Where: /tmp_dir Sep 16 18:45:59 rhel-8.example systemd: Set up automount Sample automount partition. Sep 16 19:00:54 rhel-8.example systemd: tmp_dir.automount: Got automount request for /tmp_dir, triggered by 3868 (df) Sep 16 19:01:09 rhel-8.example systemd: tmp_dir.automount: Got automount request for /tmp_dir, triggered by 1318 (bash) Sep 16 19:02:04 rhel-8.example systemd: tmp_dir.automount: Got automount request for /tmp_dir, triggered by 3903 (df)
This article provides a comprehensive guide on mounting partitions using systemd unit files, a powerful and flexible approach for managing storage devices in modern Linux systems. By leveraging systemd's capabilities, users can enjoy improved dependency handling, custom configuration options, and seamless integration with other systemd services.
The tutorial begins with identifying the partition and its UUID, device path, and filesystem type, followed by choosing a suitable mount point. Next, readers learn to create and configure a mount unit file, including specifying the device, mount point, filesystem type, and mount options. The article also explains how to create an optional automount unit file for on-demand mounting.
Furthermore, the guide delves into handling dependencies between mount units and other services using directives like
Before. These directives help ensure proper startup and shutdown order for the units. The tutorial also touches on the relationship between systemd mount units and traditional
/etc/fstab entries, illustrating how systemd can accommodate both methods while prioritizing custom unit files when conflicts arise.
By following this detailed guide, readers will be well-equipped to mount partitions using systemd unit files, enhancing the efficiency and reliability of their Linux systems' storage management.