Systemd – Umount Device After Dependent Service Finishes

linuxmountsystemdudev

I'm trying to implement a mechanism of automated backup using udev rules and systemd. The idea is to launch a backup routine upon hot-plugging a specific storage device, quite similar to this question, for which I provided an answer myself by the way, but here I'm interesteded in discussing some further tweaks. Namely I want the device to be umounted after the backup service finishes.

Some background:

So far I got it to work using udev to start up a systemd service which itself runs a backup routine. The relevant files follow:

backup.service

[Unit]
Description=<DESCRIPTION HERE>
BindsTo=<STORAGE DEVICE UNIT HERE>.device mnt-backup.mount
After=<STORAGE DEVICE UNIT HERE>.device mnt-backup.mount

[Service]
ExecStart=<CALL TO BACKUP SCRIPT HERE>

mnt-backup.mount

[Unit]
DefaultDependencies=no
Conflicts=umount.target
Before=umount.target

[Mount]
What=/dev/disk/by-uuid/<DEVICE UUID HERE> 
Where=/mnt/backup
Type=<FILESYSTEM HERE>

90-backup.rules

KERNEL=="sd*", ATTRS{serial}=="<HD SERIAL HERE>", TAG+="systemd", ENV{SYSTEMD_WANTS}+="backup.service" 

The question:

Now I want mnt-backup.mount to be stopped as soon as backup.service finishes.

According to the documentation ExecStartPost= will be executed after the command in ExecStart=, so I tried adding

ExecStartPost=/usr/bin/systemctl stop mnt-backup.mount

to backup.service, even though I realise it stops mnt-backup.mount, to which it is itself bound, what, as far as I understand, effectively requires backup.service to be stoped before mnt-backup.mount for a graceful stop, hence creating a cyclic dependence.

When testing this, it worked a couple of times before I experienced a kernel panic, the first I've seen on my machine, so it got me wondering if this was somehow the cause.

In any case, is my approach correct?

Best Answer

While I'm not sure whether the previous approach is guaranteed to work, there's an alternative which certainly looks preferable.

The magic property is called StopWhenUnneeded. This should be set to true under [Unit] in the mount file, so it becomes:

mnt-backup.mount

[Unit]
DefaultDependencies=no
Conflicts=umount.target
Before=umount.target
StopWhenUnneeded=true

[Mount]
What=/dev/disk/by-uuid/<DEVICE UUID HERE> 
Where=/mnt/backup
Type=<FILESYSTEM HERE>

As simple as that.

The great advantage of this approach, is the fact it is explicitly supported by systemd and thus guaranteed to work.

I would also strongly suggest setting RefuseManualStart to true in the service unit, which forbids users to manually start the service. The idea is precisely to automate the backup mechanism, therefore the user shouldn't be able to explicitly start it, so better leave this responsability exclusively to udev.

Related Question