How to Use systemd for Auto-Mounting Storage Volumes

When it comes to adding additional storage to your Linux workstation or server, mounting volumes with system is very effective and is the recommended method going forward. In this video, Jay will show you how to mount both storage volumes and NFS shares via systemd.

YouTube player

Systemd Refresher

Before we continue, I want to go over a few things regarding Systemd. We’re not going to go into too much detail about it in this article, since I covered this topic already in other videos/articles. However, since we’re going to be discussing Systemd to mount filesystems in this article I think it makes sense to at least give you a refresher.

Whenever you work with Systemd, most of the time you’re working with services. A service is a program that runs in the background. You can have it run all the time, on-demand, or even leave a service disabled until you need it in the future. For instance, let’s consider OpenSSH. OpenSSH runs in the background, and gives you remote access to your Linux installations. It’s one of many services that you might control via Systemd, but it doesn’t matter really what the service is in particular, since Systemd services are managed the same way regardless of what the actual application is. And you don’t have to follow-along with this part, since this is just a refresher.

Anyway, we can check the status of a service like this:

systemctl status ssh

In this case, you can replace ssh with Apache, NGINX, or whatever you might be running. Universally, this is the command syntax to check something with Systemd.

In addition, there’s other instructions you can give a Systemd service, such as stop, start, restart, enable or disable.

Let’s start with enable and disable.

In the output of the systemctl status command, you’ll see whether or not a service is enabled or disabled, as well as the vendor preset.

If a service is enabled, it’ll automatically be started at boot. In this case, ssh is enabled, so every time I reboot my computer or server, Systemd will ensure ssh is started. If I didn’t want that to be the case, I could disable it. Also take note of the vendor preset, which will vary from one distribution to another. If the vendor preset is enabled, then newly installed applications will automatically be enabled. For example, if you install Nginx and your distro’s vendor preset is enabled, then your distro will automatically enable it. If the vendor preset is disabled, you’ll have to enable and start it yourself.

For example, to enable a service, I might run this command:

sudo systemctl enable ssh

However, maybe you don’t want a service enabled, especially if it’s not being used all the time. In that case, you’ll disable it:

sudo systemctl disable ssh

Keep in mind, when you enable a service, it doesn’t start it right away – it simply sets it up to be automatically started during the next boot. On the other hand, if you disable a service, it won’t automatically start up.

If you do want to start a service that’s not already running, you might run a command like this:

sudo systemctl start ssh

Or, if you want to stop a service:

sudo systemctl stop ssh

Of course, there’s other systemd-related commands I could show you, but I wanted to keep this section short.

The only other thing I want to make sure you are aware of is the concept of a Systemd unit. A unit in systemd is any object that Systemd can manage. So far in this article, we’ve been working with services, which is a type of Systemd unit. Most of the time, you’ll be working with Systemd services, which is why some people think the terms Unit and Service in systemd mean the same thing, but that’s not the case. A service in Systemd is just one type of Unit that Systemd can control. Services control programs that run in the background.

There are other types of units in Systemd, one of them being mounts. Mount units enable us to manage attached filesystems. So basicaly, when it comes to Systemd, a service is a type of unit, and a mount is another type of unit. For the remainder of the article, we’re going to be working with mounts, since that’s the main topic of this tutorial. So what I’ll do is explain how to set up a mount, and then how to control it with Systemd. After that, I’ll discuss another type of unit later in the article, known as automount. But don’t worry – as usual, I’m going to break this down for you so that way you’ll understand it better.

Preparing our Environment

So, let’s get into it.

What you’re seeing here is a Debian VM I created specifically for this tutorial. The distribution really doesn’t matter much for this tutorial, so the commands I’m going to give you should work fine with other distributions as well, assuming they use Systemd. Most do though.

Anyway, this particular Debian VM has a secondary disk attached:

lsblk

In my case, this is a fresh disk. It’s never been used before, so it doesn’t even have any partitions available. So, what we’ll do right now is set up this secondary disk so we can use it. At this point in the tutorial, the commands I’m going to give you to set up a secondary disk aren’t specific to systemd, these are the things we need to do anytime we want to use a disk with Linux. I’ll let you know when we get to the Systemd-specific steps. Also, it probably goes without saying but even if you’re not using a VM like I am, and you’re using a physical machine with two or more physical disks, the process is the same.

From the output of lsblk, we can see in my case my disk is attached to the system at /dev/sdb. This may vary for you, but we’re using the device identifier that was returned from the lsblk command, so if your disk has a different name, be sure to alter the commands I’m going to give you to reflect the actual name for it on your end.

Anyway, the first thing we need to do in order to set up any disk in Linux is to create one or more partitions on it, then format it. Again, this has nothing to do with Systemd, but having a formatted volume is a requirement.

Before we go any further though, I just want to give you the disclaimer that you should be double sure you’re working with the correct disk. If you choose the wrong one, you could wipe out important data. That probably goes without saying, but just make sure you don’t end up working with the wrong disk.

With that out of the way, let’s set up the disk. To create a partition on it, I’ll use the fdisk command. There are other ways of creating partitions in Linux, but this command has always worked for me:

sudo fdisk /dev/sdb

Now, we’ve entered into the fdisk console. We can type “p” and press enter to see the current partition table – but I don’t have any partitions on my end, since this is a brand-new disk that’s never been used. To create a partition, I’ll type “c” for create and press enter.

Now that we’ve created a partition, the output of the lsblk command will look different:

lsblk

Next, we’ll format the disk. I’ll just go with ext4 since it works well enough and is the most common filesystem on Linux:

sudo mkfs.ext4 /dev/sdb1

At this point, we have a usable disk. It contains one partition, and we’ve formatted it. But in order to use it, we have to mount the disk volume to our filesystem. But in order to do that, we’ll need a few things. First, we’ll need to get the block ID for the storage volume.

sudo blkid /dev/sdb1

What you’ll do is copy the UUID, and save it somewhere, we’ll need it shortly. For those that have no idea with a UUID happens to be, it stands for universally unique identifier. The reason we need this is because sometimes disks can change position. For example, if you’re using a physical Linux machine and you move the disk to another SATA connection, then the path for the disk might change. The UUID however, doesn’t change. It follows the volume where you end up attaching it. Anyway, just save your UUID somewhere, for example in a text editor or something, and we’ll continue.

The next thing we need is to decide where we want to mount the filesystem. This can be just about any path within your Linux installation, but a good default is to use the /mnt directory. I’m going to use this path:

/mnt/disk_2

At this point, we don’t need to create this directory. We just need to decide where we want to mount the disk. And you can change the path to something else if you’d like. For example, maybe you’ll use /mnt/backup if it’s storage you plan on saving backups too, /mnt/games for your Steam library, you can get creative. Regardless of the path you have in mind, write it down and we’ll move on.

Now, we get to Systemd.

Mounting Storage Volumes with Systemd

Now that we’ve set up our storage volume, we can start looking at how to mount it with Systemd. To do that, we’ll need to create a unit that Systemd will use to mount the drive. But in order to do that, we’ll need to know what to name the mount unit. There’s a specific naming scheme, but here’s an easy way to figure it out.

First, run the following command:

systemd-escape -p --suffix=mount "/mnt/disk_2"

Be sure to change the path in the command to match where you ultimately want to mount your storage volume. In my case, I get the following answer:

mnt-disk_2.mount

So, to create the mount unit for systemd, we’ll create a definition for it:

sudo nano /etc/systemd/system/mnt-disk_2.mount

Be sure that the last part reflects the name that was returned by the previous command. Then, inside the file, we’ll place the following:

[Unit]
Description=Mount storage volume

[Mount]
What=/dev/disk/by-uuid/e1d1a2dd-dbdd-41e1-bc54-00ff8fe4e6a0
Where=/mnt/disk_2
Type=ext4
Options=rw,noatime

[Install]
WantedBy=multi-user.target

There’s a few things you’ll want to be sure of. First, double-check the UUID. The section that’s highlighted on the screen right now should be changed to the UUID you copied earlier. This helps Systemd identify the disk you intend on working with.

Also, “Where” refers to the mount directory, so update this with whatever path you chose earlier if you went with something different.

When you’re done, save the file (explain it).

Next, we need to ensure Systemd is aware of the mount unit we just created. To have Systemd refresh itself, we’ll run the following command:

sudo systemctl daemon-reload

Now that we’ve done that, we can inspect our mount unit the same way we would with a service:

systemctl status mnt-disk_2.mount

Now, you’ll probably start to get an idea of why I gave you a quick refresher on Systemd earlier. Even though we created a mount instead of a service, we can use the same systemctl commands we’d normally use with a service to manage our mount. Earlier, we checked the status of ssh, but this time we’re checking the status of our mount.

To understand better what’s going on here, our mount can be enabled or disabled, just like a service. Like I mentioned earlier, if a service is enabled, it’ll start at boot. If it’s disabled, it won’t. And the same thing applies here too with a systemd mount. If it’s enabled, the volume will automatically be accessible when you start your Linux workstation or server. If the mount is disabled, it won’t be available automatically.

So, if we want our mount to automatically attach, we’ll run:

sudo systemctl enable mnt-disk_2.mount

And like I mentioned, that will make sure the storage volume is ready to go when you boot up your Linux instance. But also, keep in mind that may or may not be what you want. For example, if you’re setting up a backup mount, you might only want it accessible while you’re performing a backup, and then disconnect it when you’re done in order to avoid accidentally deleting something. If a mount is enabled but you don’t want it to be, you can use the disable option.

However, just like services, enabling a mount doesn’t attach the volume to your system. If you want to actually start using it now, you can start the mount:

sudo systemctl start mnt-disk_2.mount

As soon as you do this, the volume is attached to your system. You can see this by running the mount command:

mount

Something I want to point out before we continue, is that I didn’t have you create the mount directory that you chose earlier. If you’ve mounted filesystems in Linux the old fashioned way, you’re probably accustomed to creating the mount directory the first time. However, with a mount unit, systemd will create the directory for you if you haven’t already done so, which is why we didn’t have to worry about creating it manually.

Network Shares

Next, I wanted to go over the concept of mounting NFS shares via Systemd. The process plays out similarly when compared to mounting storage volumes, but there are a few differences.

In order to mount a network share though, you’ll need to have an NFS share already created. I’ve created a video that shows you the process of sharing files with NFS in Linux, so you can always use that if you don’t have one in mind. Most of the time though, you’ll create NFS shares in your network attached storage solution.

Anyway, assuming you have an NFS share that you want to access, let’s see how to do that within Systemd. Just like before, we need to decide where we want to mount this. Since naming is important, we’ll use the following command to determine what we should name our file:

systemd-escape -p --suffix=mount "/mnt/nfs_share"

Mine returns:

mnt-nfs_share.mount

So, we’ll create the following file:

sudo nano /etc/systemd/mnt-nfs_share.mount

And inside that file, we’ll place the following:

[Unit]
Description = NFS mount

[Mount]
What=srv-nas-truenas-prod-1.learnlinux.tv:/mnt/volume2/public
Where=/mnt/nfs_share
Type=nfs
Options=defaults
TimeoutSec=5

[Install]
WantedBy=multi-user.target

Next, let’s reload systemd so that it knows about the unit that we’ve just created:

sudo systemctl daemon-reload

And, that’s about it. Now, we can enable, disable, start or stop this new mount unit just like our previous one. The only difference here is that I’m mounting an NFS share, instead of a physical or virtual disk.

Automounting

There’s one more cool trick I want to show you before I finish this article, that will make your network mounts even better. What I’m going to do right now is introduce a new unit type for Systemd, an automount unit.

An automount unit will basically mount the remote filesystem automatically. Now, you might be wondering – why is this necessary? After all, you can simply enable our NFS mount unit with the systemctl enable command, and that’ll make sure that the share is mounted automatically. However, the difference with automount is that the NFS share will only be mounted when you go to use it, and will automatically unmount when it’s not in use.

The reason why you might want to do this, is because sometimes you may encounter file locking issues, or other headaches, when using NFS shares. To best understand this, let’s see it in action.

First, let’s determine what we should call our automount unit:

systemd-escape -p --suffix=automount "/mnt/nfs_share"

Mine returns:

mnt-nfs_share.automount

With that in mind, let’s create our automount unit:

[Unit]
Description=NFS Automount

[Automount]
Where=/mnt/nfs_share
TimeoutIdleSec=10

[Install]
WantedBy=multi-user.target

Now that we’ve created an automount service, we can start it:

sudo systemctl start mnt-nfs_share.automount

We should also enable it so that way it starts at boot:

sudo systemctl enable mnt-nfs_share.automount

At this point, we should ensure the NFS mount unit itself is disabled. The reason for this is because an automount unit will take care of mounting an unmounting the share for us, so there’s no reason to have the mount unit enabled or even running at this point.

sudo systemctl disable mnt-nfs_share.mount
sudo systemctl stop mnt-nfs_share.mount

At this point, our NFS share is not mounted to our system at all.

Now, here comes the fun part. Even though our NFS share is not mounted, let’s try to access it anyway:

ls -l /mnt/nfs_share

Once we’ve done that, the share was mounted automatically – on its own. So basically, the way that automount works is that the share won’t be mounted at first, but immediately whenever you go to use it, Systemd will notice and immediately mount it for you. So, when we ran the ls command, it wasn’t mounted – but immediately Systemd mounted the share so fast that the ls command still worked. After about ten seconds passes, which we set in the timeout, the volume will be unmounted.

On my end, I’ve actually used this for my plex server. I had a VM setup to run Plex, and I only gave it 32GB of storage, which is clearly not enough if you plan on storing movies. So, what I did was create an automount for a share that contains all of my TV shows and movies, and set up that path within Plex. Whenever plex goes to scan for new content, or whenever I go to watch a movie or TV show, the share is automatically mounted and everything works just like it should. And the good thing about an automount, is that we can better avoid situations in which a stuck mount stops us from rebooting our server, since it’s only ever mounted when it’s in use. When it comes to applications, they’ll think the volume is always mounted, because every time a program or service attempts to access the directory we want our share mounted to, it mounts immediately with no disruption. Of course, this is completely optional, but it’s a very efficient way of managing mounts.

Config Files

The following unit files were discussed in this article so be sure to update them for your environment:

mnt-disk_2.mount

[Unit]
Description=Mount storage volume

[Mount]
What=/dev/disk/by-uuid/e1d1a2dd-dbdd-41e1-bc54-00ff8fe4e6a0
Where=/mnt/disk_2
Type=ext4
Options=rw,noatime

[Install]
WantedBy=multi-user.target

mnt-nfs_share.mount

[Unit]
Description = NFS mount

[Mount]
What=srv-nas-truenas-prod-1.learnlinux.tv:/mnt/volume2/public
Where=/mnt/nfs_share
Type=nfs
Options=defaults
TimeoutSec=5

[Install]
WantedBy=multi-user.target

mnt-nfs_share.automount

[Unit]
Description=NFS Automount

[Automount]
Where=/mnt/nfs_share
TimeoutIdleSec=10

[Install]
WantedBy=multi-user.target