Come posso eseguire uno script prima di ogni altra cosa allo spegnimento con systemd?


17

Nota: la domanda brevemente formulata può essere trovata in fondo.

Ho uno script che esegue un backup dei miei file su un'unità USB esterna. L'esecuzione può richiedere del tempo, a seconda della quantità di nuovi dati che ho creato. Voglio eseguirlo automaticamente ad ogni spegnimento del sistema.

Sto usando Fedora 23 con gli ultimi aggiornamenti (systemd).

Ho provato a raggiungere questo obiettivo in diversi modi, ma non sono riuscito a farlo funzionare.

Processo di lunga durata con 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

L'ho attivato con systemctl enable autobackup.servicee iniziato con systemctl start autobackup.service.

Parte del mio registro di avvio ( 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.

Nota che non ho abbreviato nulla in mezzo, è stato smontato / mnt / BACKUP poco prima dell'inizio dello script, coincidenza divertente ..

Prima di 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

L'output è sostanzialmente lo stesso.

Il problema

Penso che il problema sia che systemd avvia il mio script in parallelo con tutti gli altri script di arresto in entrambi i casi, che smontano BACKUP e disattivano l'infrastruttura del tubo (un altro errore che a volte ho avuto, quando lo smontaggio non era abbastanza veloce).

La domanda

Come posso insegnare a systemd ad avviare prima il mio script all'arresto, attendere fino alla sua uscita e quindi avviare il resto degli script / destinazioni / unità di arresto / qualunque cosa?

Risposte:


12

Non è necessario creare o modificare file di servizio. Inserisci semplicemente il tuo script

/usr/lib/systemd/system-shutdown/

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

Immediatamente prima di eseguire l'arresto di sistema reale / poweroff / reboot / kexec systemd-shutdown eseguirà tutti gli eseguibili in / usr / lib / systemd / system-shutdown / e passerà loro un argomento: "halt", "poweroff", "reboot "o" kexec ", a seconda dell'azione scelta. Tutti gli eseguibili in questa directory vengono eseguiti in parallelo e l'esecuzione dell'azione non viene continuata prima del completamento di tutti gli eseguibili.

Lo uso semplicemente per emettere un segnale acustico dall'altoparlante del PC.


2
Hai dovuto creare questa directory? Non ce l'ho né su Ubuntu 16.04 né su Raspbian (jessie) - entrambi sono basati su systemd.
WoJ,

2
I sistemi Debian usano il diverso percorso /lib/systemd/system-shutdown/. Inoltre, tenere presente che questi script vengono eseguiti molto tardi allo spegnimento, dopo che i file system sono già montati in sola lettura. Pertanto, qualsiasi accesso in scrittura al file system non riuscirà a meno che non venga rimontato come read-write ( mount -oremount,rw /). Vedi Come eseguire gli script in / usr / lib / systemd / system-shutdown / al riavvio o allo spegnimento?
Frank Breitling,

9
OP ha richiesto lo script eseguito "prima di tutto" allo spegnimento. Gli script di spegnimento del sistema vengono eseguiti dopo tutto il resto, immediatamente prima di uccidere il kernel.
Greg Alexander,

11

Capito!

Prendi la soluzione Processo di lunga durata con StopExec e modificalo in questo modo:

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

Nota la linea:

RequiresMountsFor=/mnt/BACKUP /home

Funziona come previsto in questo modo.


2
Non dovresti aver bisogno di fare il systemctl edit. systemctl enable autobackupha lo stesso effetto ed è più idiomatico, e dovrebbe funzionare poiché hai già la [Install]sezione nella tua unità. Dovrai correggere quel refuso nel nome di destinazione, però. ;)
Stefan Majewsky,

OMG Stavo cercando da tanto tempo una soluzione per chiamare il mio script di backup PRIMA che qualsiasi unità fosse smontata. Grazie!
decano,

2
Questo non funziona per me. Non ho alcun mount, voglio solo assicurarmi che il mio script venga eseguito prima che altre unità si spengano.
2rs2ts
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.