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.