Linux – Run a Script Before Shutdown with Systemd

administratorlinuxshutdownsystemd

Note: Briefly formulated question can be found at the bottom.

I have a script which makes a backup of my files onto an external USB drive. Executing it can take a while, depending on the amount of new data I've created. I want to run it automatically on every shutdown of the system.

I'm using fedora 23 with latest updates (systemd).

I tried to achieve this in several ways, but I couldn't get it to work.

Long running process with StopExec

autobackup.service:

[Unit]
Description=Slow backup script
Requires=local-fs.target

[Service]
ExecStart=/bin/true
ExecStop=/etc/systemd/system/do_backup.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=multiuser.target

I activated it with systemctl enable autobackup.service and started it with systemctl start autobackup.service.

Part of my boot log (journalctl -b-1):

Dez 22 17:45:27 localhost systemd[1]: Unmounted /mnt/BACKUP.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At subvol /home/BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: parent subvol is not reachable from inside the root subvol.
Dez 22 17:45:27 localhost do_backup.sh[4296]: At snapshot BACKUP.2015_12_22-17_45_25
Dez 22 17:45:27 localhost do_backup.sh[4296]: ERROR: failed to dump stream. Broken pipe
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Control process exited, code=exited status=1
Dez 22 17:45:27 localhost systemd[1]: Stopped Slow backup script.
Dez 22 17:45:27 localhost systemd[1]: autobackup.service: Unit entered failed state.

Note that I didn't shorten anything in between, it really unmounted /mnt/BACKUP just before the script started, funny coincidence..

Before shutdown.target

autobackup.service:

[Unit]
Description=Slow backup script
DefaultDependencies=no
Before=shutdown.target

[Service]
ExecStart=/etc/systemd/system/do_backup.sh
Type=oneshot

systemctl edit shutdown.target

[Unit]
Requires=autobackup.service

Output is basically the same.

The Problem

I think the problem is that systemd starts my script in parallel with all the other shutdown scripts in both cases, which unmount BACKUP and deactivate the pipe infrastructure (another error I sometimes got, when the unmount wasn't fast enough).

The Question

How can I teach systemd to start my script first on shutdown, wait until it exits and then start the rest of the shutdown scripts/targets/units/whatever?

Best Answer

No need to create or edit service files. Simply drop your script in

/usr/lib/systemd/system-shutdown/

https://www.freedesktop.org/software/systemd/man/systemd-halt.service.html

Immediately before executing the actual system halt/poweroff/reboot/kexec systemd-shutdown will run all executables in /usr/lib/systemd/system-shutdown/ and pass one arguments to them: either "halt", "poweroff", "reboot" or "kexec", depending on the chosen action. All executables in this directory are executed in parallel, and execution of the action is not continued before all executables finished.

I use it to simply beep the PC speaker.

Related Question