web-dev-qa-db-fra.com

Comment exécuter un script avant tout le reste à l'arrêt avec systemd?

Remarque: une question brièvement formulée se trouve en bas.

J'ai un script qui fait une sauvegarde de mes fichiers sur un lecteur USB externe. L'exécution peut prendre un certain temps, en fonction de la quantité de nouvelles données que j'ai créées. Je veux l'exécuter automatiquement à chaque arrêt du système.

J'utilise Fedora 23 avec les dernières mises à jour (systemd).

J'ai essayé d'y parvenir de plusieurs manières, mais je ne pouvais pas le faire fonctionner.

Long processus avec 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

Je l'ai activé avec systemctl enable autobackup.service et l'ai démarré avec systemctl start autobackup.service.

Partie de mon journal de démarrage (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.

Notez que je n’ai rien raccourci entre les deux, c’est vraiment démonté/mnt/BACKUP juste avant le début du script, drôle coïncidence ..

Avant 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

La sortie est fondamentalement la même.

Le problème

Je pense que le problème est que systemd démarre mon script en parallèle avec tous les autres scripts d'arrêt dans les deux cas, ce qui permet de démonter BACKUP et de désactiver l'infrastructure de canal (une autre erreur que j'ai parfois rencontrée, lorsque le démontage n'était pas assez rapide).

La question

Comment puis-je apprendre à Systemd à démarrer mon script d’abord à l’arrêt, à attendre qu’il se ferme, puis à lancer le reste des scripts/cibles/unités/autres éléments arrêtés?

16
le_me

J? ai compris!

Prenez la solution Long processus en cours avec StopExec et modifiez-le comme suit:

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

Notez la ligne:

RequiresMountsFor=/mnt/BACKUP /home

Cela fonctionne comme prévu de cette façon.

11
le_me

Pas besoin de créer ou d'éditer des fichiers de service. Déposez simplement votre script dans

/usr/lib/systemd/system-shutdown/

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

Immédiatement avant d'exécuter le système actuel stop/poweroff/reboot/kexec, systemd-shutdown exécutera tous les exécutables dans/usr/lib/systemd/system-shutdown/et leur passera un argument: soit "halt", "poweroff", "reboot", "ou" kexec ", en fonction de l'action choisie. Tous les exécutables de ce répertoire sont exécutés en parallèle et l'exécution de l'action n'est pas poursuivie avant la fin de tous les exécutables.

Je l'utilise simplement pour biper le haut-parleur du PC.

11
Joost