I’m working on a systemd .service script that is supposed to start after a CIFS network location is mounted via /etc/fstab to /mnt/ on boot-up.
The script waits for an OpenVPN dependency script to launch first, but I also want it to wait for mount to complete.
/etc/systemd/system/my-daemon.service:
[Unit] Description=Launch My Daemon After=network.target vpn-launch.service Requires=vpn-launch.service
I tried to add systemd.mount to the line: After=network.target vpn-launch.service systemd.mount, but it didn’t give the results I was hoping for.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
a CIFS network location is mounted via
/etc/fstabto/mnt/on boot-up.
No, it is not. Get this right, and the rest falls into place naturally.
The mount is handled by a (generated) systemd mount unit that will be named something like mnt-wibble.mount. You can see its actual name in the output of systemctl list-units --type=mount command. You can look at it in detail just like any other unit with systemctl status.
Very simply, then: you have to order your unit to be started after that mount unit is started.
After=network.target vpn-launch.service mnt-wibble.mount
Further reading
Method 2
Although both answers are correct, I want to add my two cents to the discussion, because when I have looked for it I was missing some instructions and examples of how to proceed.
- Add the filesystem to
/etc/fstab - Type
mount -awhich mounts all filesystems mentioned in fstab - Look for the systemd unit that has been generated with:
systemctl list-units | grep '/path/to/mount' | awk '{ print $1 }'(should return something that ends with
.mount) - Add the found mount-unit to the
After=statement in the*.servicefile
Here is an example of starting the my-daemon service on boot but after the network is ready, a CIFS share is mounted at /mnt/cifs, and the vpn-launch service has started:
/etc/fstab
//servername/sharename /mnt/cifs cifs defaults,some,other,options 0 0
Note: You may want to add nofail to your fstab options (e.g. when using an external drive). Otherwise, your machine won’t boot if the device is not connected. See ArchWiki’s fstab article
/etc/systemd/system/my-daemon.service
[Unit] Description=Launch My Daemon Requires=vpn-launch.service mnt-cifs.mount After=network.target vpn-launch.service mnt-cifs.mount [Service] ExecStart=/path/to/my-daemon [Install] WantedBy=multi-user.target
Do not forget to enable the service such that it is started on boot: systemctl enable my-daemon
Note that this works for other filesystems (NFS, HDDs, etc.) as well.
As already mentioned, both answers are correct and I encourage everybody to read them but for me a couple of examples would have saved me some time.
Update (2019-06-25):
- added a note regarding fstab options to prevent boot lock when using external drives
- added
mnt-cifs.mountto theRequires=list which causes themy-daemon.servicefail to start-up when the cifs mount was not successfully mounted
Method 3
Sorry but I can’t comment yet.
Like JdeBP said, you should be ordering on the filesystem mount. You can predict the name of the mount unit or, alternatively, you can use (in unit section):
RequiresMountsFor=/absolute/path/of/mount
This option creates the dependencies to the appropriate *.mount units to make the path accessible before starting the service. It may not be on all systemd versions, but I’ve been using it in a CentOS 7 machine for the last 6 months or so.
Method 4
First determine the mount unit name with:
systemctl list-units --type=mount
It will likely be named after the mountpoint in /mnt such as
mnt-syncthingx2ddeb.mount
for a mount point of /mnt/syncthing .
Then add this mount unit to the After= directive in your service, such as:
After=network.target mnt-syncthingx2ddeb.mount
Edit your service with
systemctl edit --full [servicename.service]
to preserve the config after an update. Now your service will wait for the mount before starting!
Method 5
@bm-bergmotte: thanks for your instruction which helped me a lot.
For me it´s just working, if I put
After=network.target vpn-launch.service mnt-cifs.mount Requires=vpn-launch.service mnt-cifs.mount
If I don´t put “mnt-cifs.mount” inside the “Requires” (and in this order) it works for reboot/ startup, but the service starts anyway, if the device is not mounted. After putting it additionally inside “”Requires” the service mounts the device before starting it, if the device was not mounted.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0