RHCSA – Mount Filesystems during boot time using Systemd

Overview

By the end of this article you should be able to answer the following questions:

Let’s say we have the following scenario:

  • we have the partition: /dev/sdb1
  • we have the mountpoint: /tmp/sdb1custom
  • the /dev/sdb1 partition has the xfs mountpoint installed on it.
  • The /dev/sdb1 needs to be automounted by the multi-user.target

What will be compatible name of the mount unit file that you need to create?

$ touch /etc/systemd/system/tmp-sdb1custom.mount
# replace the “/” to create the mount unit’s file name.

What should this file contain?

$ cat /etc/systemd/system/tmp-sdb1custom.mount
[Unit]
Description=My new file system

[Mount]
What=/dev/sdb1
Where=/tmp/sdb1custom
Type=xfs
Options=grpquota,ro

[Install]
WantedBy=multi-user.target


What is the command to activate the mount?

$ systemctl start tmp-sdb1custom.mount

What is the command to activate the automounting?

$ systemctl enable tmp-sdb1custom.mount


In an earlier lesson we saw how to use the /etc/fstab file to automatically mount a file system during boot time. However there’s a new way to automount using systemd. This is done by creating a “mount” unit file. You should find some existing ones here:

$ ls -l /usr/lib/systemd/system | grep "mount$"
-rw-r--r--. 1 root root  636 Jun 10  2014 dev-hugepages.mount
-rw-r--r--. 1 root root  590 Jun 10  2014 dev-mqueue.mount
-rw-r--r--. 1 root root  115 Jun 10  2014 proc-fs-nfsd.mount
-rw-r--r--. 1 root root  693 Jun 10  2014 proc-sys-fs-binfmt_misc.automount
-rw-r--r--. 1 root root  603 Jun 10  2014 proc-sys-fs-binfmt_misc.mount
-rw-r--r--. 1 root root  681 Jun 10  2014 sys-fs-fuse-connections.mount
-rw-r--r--. 1 root root  685 Jun 10  2014 sys-kernel-config.mount
-rw-r--r--. 1 root root  628 Jun 10  2014 sys-kernel-debug.mount
-rw-r--r--. 1 root root  669 Jun 10  2014 tmp.mount
-rw-r--r--. 1 root root  131 Jun 10  2014 var-lib-nfs-rpc_pipefs.mount

To see which of these are active, do:

$ systemctl list-units --type=mount
UNIT                         LOAD   ACTIVE SUB     DESCRIPTION
-.mount                      loaded active mounted /
boot.mount                   loaded active mounted /boot
dev-hugepages.mount          loaded active mounted Huge Pages File System
dev-mqueue.mount             loaded active mounted POSIX Message Queue File System
proc-fs-nfsd.mount           loaded active mounted RPC Pipe File System
sys-kernel-config.mount      loaded active mounted Configuration File System
sys-kernel-debug.mount       loaded active mounted Debug File System
var-lib-nfs-rpc_pipefs.mount loaded active mounted RPC Pipe File System

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

8 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Now, let’s say I created a new partition, sdb1, and I have a filesytem installed on it.

$ lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   20G  0 disk
├─sda1            8:1    0  500M  0 part /boot
└─sda2            8:2    0 19.5G  0 part
  ├─centos-swap 253:0    0    2G  0 lvm  [SWAP]
  └─centos-root 253:1    0 17.5G  0 lvm  /
sdb               8:16   0    2G  0 disk
└─sdb1            8:17   0    1G  0 part
sr0              11:0    1 1024M  0 rom

I now want to automount sdb1 using systemd. The first thing I want to do is create the mountpoint, and for this example, I’ll create:

$ mkdir /tmp/sdb1custom

Next I need to create a .mount file. I can’t create the .mount file in /usr/lib/systemd/system, because that directory is for systemd’s internal use only. Instead I create it in /etc/systemd/system/. The easiest/quickest way to do this is by making a copy from an existing *.mount file, in my case I’ll use tmp.mount as my template:

$ cp /usr/lib/systemd/system/tmp.mount /etc/systemd/system/tmp-sdb1custom.mount

Note: the .mount file’s name has to mirror the mountpoint’s name, just replace the slashes with hyphens.

Now, let’s view it’s content:

$ cat /etc/systemd/system/tmp-sdb1custom.mount
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=Temporary directory
Documentation=man:hier(7)
Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems
DefaultDependencies=no
Conflicts=umount.target
Before=local-fs.target umount.target

[Mount]
What=tmpfs
Where=/tmp
Type=tmpfs
Options=mode=1777,strictatime



# Make 'systemctl enable tmp.mount' work:
[Install]
WantedBy=local-fs.target


I have highlighted the mandatory parts in bold above. Using this template as a starting point, I created the following file:

$ cat /etc/systemd/system/tmp-sdb1custom.mount
[Unit]
Description=My new file system

[Mount]
What=/dev/sdb1
Where=/tmp/sdb1custom
Type=xfs
Options=grpquota,ro

[Install]
WantedBy=multi-user.target

Notice that when compared to a *.service file, a *.mount file has a “[Mount]” section instead of a “[Service]” section.

Now we can test this by manually mounting using the sytemctl command. But let’s confirm it isn’t mounted yet:

$ mount | grep sdb1

Now let’s mount it using the systemctl command:

$ systemctl start tmp-sdb1custom.mount

Notice that’s it’s similar to the command you use to start a service. We can confirm that the mount has been successful using systemctl:

$ systemctl status tmp-sdb1custom.mount
tmp-sdb1custom.mount - My new file system
   Loaded: loaded (/etc/systemd/system/tmp-sdb1custom.mount; disabled)
   Active: active (mounted) since Mon 2015-06-08 23:09:21 BST; 6s ago
    Where: /tmp/sdb1custom
     What: /dev/sdb1
  Process: 1745 ExecMount=/bin/mount /dev/sdb1 /tmp/sdb1custom -t xfs -o grpquota,ro (code=exited, status=0/SUCCESS)

Jun 08 23:09:21 localhost.localdomain systemd[1]: Mounting My new file system...

We can also check it worked using the mount command:

$ mount | grep sdb1
/dev/sdb1 on /tmp/sdb1custom type xfs (ro,relatime,seclabel,attr2,inode64,grpquota)

Another way to check is using lsblk:

$ lsblk
NAME            MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda               8:0    0   20G  0 disk
├─sda1            8:1    0  500M  0 part /boot
└─sda2            8:2    0 19.5G  0 part
  ├─centos-swap 253:0    0    2G  0 lvm  [SWAP]
  └─centos-root 253:1    0 17.5G  0 lvm  /
sdb               8:16   0    2G  0 disk
└─sdb1            8:17   0    1G  0 part /tmp/sdb1custom
sr0              11:0    1 1024M  0 rom

Now to unmount we do:

$ umount /dev/sdb1

Now if we want this filesystem to auto-mount during the boot process, we need to enable it (in the same way that we do for services), therefore we do:

$ systemctl enable tmp-sdb1custom.mount
ln -s '/etc/systemd/system/tmp-sdb1custom.mount' '/etc/systemd/system/multi-user.target.wants/tmp-sdb1custom.mount'

Now let’s confirm that it is enabled:

$ systemctl status tmp-sdb1custom.mount
tmp-sdb1custom.mount - My new file system
   Loaded: loaded (/etc/systemd/system/tmp-sdb1custom.mount; enabled)
   Active: active (mounted) since Mon 2015-06-08 23:09:21 BST; 6min ago
    Where: /tmp/sdb1custom
     What: /dev/sdb1

Jun 08 23:09:21 localhost.localdomain systemd[1]: Mounting My new file system...

Now let’s go ahead and reboot the machine. After that let’s see if sdb1 get’s automounted:

$ mount | grep sdb1
/dev/sdb1 on /tmp/sdb1custom type xfs (ro,relatime,seclabel,attr2,inode64,grpquota)

Success!