Wie führe ich ein Skript vor allem anderen beim Herunterfahren mit systemd aus?

17

Hinweis: Eine kurz formulierte Frage finden Sie unten.

Ich habe ein Skript, das eine Sicherungskopie meiner Dateien auf einem externen USB-Laufwerk erstellt. Die Ausführung kann eine Weile dauern, je nachdem, wie viele neue Daten ich erstellt habe. Ich möchte es automatisch bei jedem Herunterfahren des Systems ausführen.

Ich benutze Fedora 23 mit den neuesten Updates (systemd).

Ich habe versucht, dies auf verschiedene Arten zu erreichen, aber ich konnte es nicht zum Laufen bringen.

Langfristiger Prozess mit 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

Ich habe es mit aktiviert und mit systemctl enable autobackup.servicegestartet systemctl start autobackup.service.

Teil meines Bootlogs ( 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.

Beachten Sie, dass ich nichts dazwischen verkürzt habe, es hat / mnt / BACKUP wirklich kurz vor dem Start des Skripts abgehängt, lustiger Zufall.

Vor dem Herunterfahren.Ziel

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

Die Ausgabe ist grundsätzlich gleich.

Das Problem

Ich denke, das Problem ist, dass systemd mein Skript in beiden Fällen parallel zu allen anderen Shutdown-Skripten startet, die BACKUP aushängen und die Pipe-Infrastruktur deaktivieren (ein weiterer Fehler, den ich manchmal bekam, wenn das Aushängen nicht schnell genug war).

Die Frage

Wie kann ich systemd beibringen, mein Skript zuerst beim Herunterfahren zu starten, zu warten, bis es beendet wird, und dann den Rest der Skripte / Ziele / Einheiten / was auch immer zum Herunterfahren zu starten?

le_me
quelle

Antworten:

12

Es müssen keine Servicedateien erstellt oder bearbeitet werden. Legen Sie einfach Ihr Skript ein

/usr/lib/systemd/system-shutdown/

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

Unmittelbar vor dem eigentlichen Systemstopp / Ausschalten / Neustart / Kexec führt systemd-shutdown alle ausführbaren Dateien in / usr / lib / systemd / system-shutdown / aus und übergibt ihnen ein Argument: entweder "Halt", "Ausschalten", "Neustart" "oder" kexec ", je nach gewählter Aktion. Alle ausführbaren Dateien in diesem Verzeichnis werden parallel ausgeführt, und die Ausführung der Aktion wird nicht fortgesetzt, bevor alle ausführbaren Dateien abgeschlossen sind.

Ich benutze es, um einfach den PC-Lautsprecher zu piepen.

Joost
quelle
2
Musstest du dieses Verzeichnis machen? Ich habe es weder auf Ubuntu 16.04 noch auf Raspbian (jessie) - beide sind systembasiert.
WoJ
2
Debian-Systeme verwenden den anderen Pfad /lib/systemd/system-shutdown/. Beachten Sie außerdem, dass diese Skripts sehr spät beim Herunterfahren ausgeführt werden, nachdem Dateisysteme bereits schreibgeschützt bereitgestellt wurden. Jeder Schreibzugriff auf das Dateisystem schlägt fehl, sofern er nicht als read-write ( mount -oremount,rw /) erneut bereitgestellt wird . Weitere Informationen finden Sie unter Ausführen von Skripten in / usr / lib / systemd / system-shutdown / beim Neustart oder Herunterfahren.
Frank Breitling
8
OP hat beim Herunterfahren nach einem Skript gefragt, das "vor allem anderen" ausgeführt wird. Die Skripte zum Herunterfahren des Systems werden nach allen anderen ausgeführt, unmittelbar bevor der Kernel beendet wird.
Greg Alexander
11

Ich hab es geschafft!

Nimm die Lösung Langfristiger Prozess mit StopExec und ändere ihn wie folgt :

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

Beachten Sie die Zeile:

RequiresMountsFor=/mnt/BACKUP /home

Es funktioniert so wie erwartet.

le_me
quelle
2
Sie sollten das nicht tun müssen systemctl edit. systemctl enable autobackuphat den gleichen Effekt und ist mehr idiomatisch und sollte funktionieren, da Sie bereits den [Install]Abschnitt in Ihrem Gerät haben. Sie müssen diesen Tippfehler jedoch im Zielnamen korrigieren. ;)
Stefan Majewsky
OMG Ich habe so lange nach einer Lösung gesucht, um mein Backup-Skript aufzurufen, BEVOR Laufwerke nicht gemountet werden. Vielen Dank!
Deanresin
1
Das funktioniert bei mir nicht. Ich habe keine Reittiere, ich möchte nur sicherstellen, dass mein Skript ausgeführt wird, bevor andere Einheiten heruntergefahren werden.
21.