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?

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.

  • 1
    Did you have to make this directory? I do not have it neither on Ubuntu 16.04 nor Raspbian (jessie) - both are systemd based. – WoJ Aug 28 '16 at 13:21
  • 1
    Debian systems use the different path /lib/systemd/system-shutdown/. And in addition be aware that these scripts are executed very late in shutdown, after file systems are already mounted read-only. So any write access to the file system will fail unless remounted as read-write (mount -oremount,rw /). See How to execute scripts in /usr/lib/systemd/system-shutdown/ at reboot or shutdown? – Frank Breitling Feb 24 '17 at 15:07
  • 3
    OP asked for script executed "before everything else" on shutdown. The system-shutdown scripts are executed after everything else, immediately before killing the kernel. – Greg Alexander Apr 29 '17 at 4:01
up vote 9 down vote accepted

I got it!

Take solution Long running process with StopExec and modify it like so:

autobackup.service:

[Unit]
Description=Slow backup script
RequiresMountsFor=/mnt/BACKUP /home

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

[Install]
WantedBy=multi-user.target

Note the line:

RequiresMountsFor=/mnt/BACKUP /home

It works as expected this way.

  • 2
    You shouldn't need to do the systemctl edit. systemctl enable autobackup has the same effect and is more idiomatic, and should work since you already have the [Install] section in your unit. You will have to correct that typo in the target name, though. ;) – Stefan Majewsky Apr 13 '16 at 10:45
  • OMG I was searching so long for a solution to calling my backup script BEFORE any drives are unmounted. Thank you! – deanresin May 30 '16 at 21:29
  • This does not work for me. I don't have any mounts, I just want to make sure my script runs before other units shut down. – 2rs2ts 2 days ago

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.