If you're new to systemd you're probably thinking that the title sounds like the sort of thing that should be easy, and you're right! If you're used to systemd, you'll already know that it's probably not easy, and you're also right!
On the surface, you should be able to just add your entries to
/etc/fstab as you've been doing up until now and if that's working for you: stick to it!
If, however, you either a) are having problems with mounts being attempted before your network is up (common with WiFi systems) or b) want to do everything the full systemd way, then read on!
The Mount File
Systemd includes a helpful
mount unit type, handled as a
.mount unit file (just like
.service etc). As of the time of writing, this file actually just gets 'executed' through the usual
mount command anyway, but let's have a look at what a mount file looks like.
Check out James Oguya's excellent post on this topic for the full details.
[Unit] Description = Mount NFS Share [Mount] What=172.24.0.5:/srv/backups Where=/mnt/backups Type=nfs Options=defaults # Uncomment the below if your server is real slow # TimeoutSec=10 [Install] WantedBy=multi-user.target
and that's it! Sort of.
Put this file in
/etc/systemd/system like your other system units, but be warned: the file must be named exactly for its target mount point. In the example above, the file would be
Don't ask me why, I don't know either.
systemctl daemon-reload and
systemctl start mnt-backups.mount to mount your filesystem. Now to mount at boot, you would think you can just
systemctl enable ... but unfortunately it's not that simple.
Putting a boot in it
Now if you just run
systemctl enable ... with your unit as it stands, it will almost certainly fail since systemd won't know to wait for the network before it actually runs the mount.
You can control this using the
After= option in the
[Unit] Description = Mount Server Private Directory After=## this bit here ## [Mount] ...
Now your first thought will be to use the "special"
remote-fs.target here and this might work in simple setups. If your system is using Network Manager however, the accepted wisdom seems to be to use
After=NetworkManager-wait-online.service as your dependency. This will usually work for wired connections, so try this first.
There's a bit of a caveat here though:
NetworkManager doesn't actually wait
If you check the
/usr/lib/systemd/system/NetworkManager-wait-online.service file yourself, you'll notice the service is just using
nm-online to wait for the network. However, if you check the arguments being used, you'll see that using the
-s flag here only waits for NetworkManager itself to be ready, not the actual connection to be connected and ready. While you can simply remove the
-s flag here (see notes below), I find it better to create a new service.
Creating a service that actually waits
In my case, I created the following file at
[Unit] Description=Wait until NM actually online Requires=NetworkManager-wait-online.service After=NetworkManager-wait-online.service [Service] Type=oneshot ExecStart=/usr/bin/nm-online -q --timeout=120 RemainAfterExit=yes [Install] WantedBy=multi-user.target
This will run after the existing
NetworkManager-wait-online.service but will only successfully start (and stay active) once Network Manager has actually connected to the network.
systemctl daemon-reload and
systemctl enable --now network-online.service to confirm your service is working and enable the check to run at boot
Adding this to your mount
Now you have this service, you can slightly tweak your existing
.mount file with the following lines in the
Now your mount won't be run until NetworkManager reports your network as actually connected.
Putting it together
You can actually use this new
network-online.service as a
After= criteria on any other services you have that should wait until the network is actually connected, instead of just having the stack up.
What about if I'm not using NetworkManager?
Fair point actually. The overall principles at work remain the same: create a service with a command that will only return a success code when the network is available and have your mounts depend on that. You'll just have to find the right system service to use as an
After= substitute for
NetworkManager-wait-online.service and find a command you can use to replace
What about removing the
-s flag in the builtin unit?
So this is a valid approach with two important caveats:
- You might break existing stuff. In my non-rigorous testing, boot behaviour actually got worse when I made this change and there were a few services that seemed to have trouble starting/waiting for the modified service.
- DO NOT modify the builtin service file. If you're on a vaguely recent release, you should be able to create a
/etc/systemd/system/NetworkManager-wait-online.service.d/directory and put
.conffiles in there to override the built-in one. Check the docs or the better unofficial docs
Can't you do this in
Yes and no, in my experience. Yes,
/etc/fstab is both the easiest and most Linux-y way of doing mounts, but it's also unintuitive, error-prone and doesn't integrate well with things like NetworkManager/netctl/whatever. Personally, I'd prefer to whip up an easy
.mount file then try and decipher whatever
x-systemd.automount means, and which column of this plaintext file it should be in.
Why not use
This is the big one: the answer to the vast majority of problems with NetworkManager/systemd/etc and mount delay is to use "automounts" which are essentially lazy filesystem mounts, that are auto-mounted the first time they're accessed. For the most part, these do solve a few of the problems from above. That being said, if you want your boot to actually wait for the filesystem rather than leave it until first access, you will need to use this method instead.