GNU/Linux >> Linux Esercitazione >  >> Linux

Modo corretto di utilizzare OnFailure in systemd

Per eseguire un po' di pulizia se il servizio fallisce, puoi usare ExecStopPost= , che viene eseguito indipendentemente dal fatto che il servizio abbia esito positivo o meno.

Nel codice eseguito su ExecStopPost= , puoi utilizzare uno tra $SERVICE_RESULT , $EXIT_CODE o $EXIT_STATUS determinare la condizione di guasto e agire di conseguenza. Consulta la documentazione su queste variabili d'ambiente per verificare quale è appropriata per te.

Quindi puoi usare Restart=on-failure in modo che systemd tenti di riavviare la tua unità quando fallisce.

Mettendo tutto insieme, ecco come sarebbe. Supponendo che run_program uscirà con lo stato 2 ogni volta che i file sono danneggiati (si spera che tu possa adattarlo ad altri scenari di errore dalla documentazione sopra), dovrebbe funzionare:

[Service]
ExecStart=/bin/run_program
ExecStopPost=/bin/sh -c 'if [ "$$EXIT_STATUS" = 2 ]; then rm /file/to/delete; fi'
Restart=on-failure

(NOTA :Il doppio simbolo del dollaro $$ è eseguire l'escape su systemd, in modo che la shell veda $EXIT_STATUS e accede a quella variabile. Anche l'uso di un singolo simbolo del dollaro funzionerebbe, ma poi systemd farebbe quella sostituzione e la shell vedrebbe [ "2" = 2 ] , che probabilmente funziona anche... Ad ogni modo, puoi aggirare la maggior parte di ciò inserendo tutta questa logica in uno script di shell e chiamandolo con il suo percorso completo in ExecStopPost= , sarebbe probabilmente meglio e potresti anche aggiungere facilmente più comandi allo script, come registrare l'azione intrapresa per recuperare dalla condizione di errore.)

Spero che questo ti dia abbastanza indicazioni per capire come configurarlo correttamente data la tua particolare situazione!


NOTA :Probabilmente vorrai usare ExecStopPost= invece di OnFailure= qui (vedi la mia altra risposta), ma questo sta cercando di spiegare perché il tuo OnFailure= la configurazione non funziona.

Il problema con OnFailure= non avviare l'unità potrebbe essere perché si trova nella sezione sbagliata, deve essere nel [Unit] sezione e non [Service] .

Puoi provare invece questo:

# software.service
[Unit]
Description=Software
OnFailure=software-fail.service

[Service]
ExecStart=/bin/run_program

E:

# software-fail.service
[Unit]
Description=Delete corrupt files

[Service]
ExecStart=/bin/rm /file/to/delete
ExecStop=/bin/systemctl --user start software.service

Posso farlo funzionare con questa configurazione.

Ma nota che usando OnFailure= non è l'ideale qui, dal momento che non puoi davvero dire perché il programma ha fallito, e concatenarne un altro inizio in ExecStop= chiamando /bin/systemctl start direttamente è piuttosto complicato... La soluzione usando ExecStopPost= e guardare lo stato di uscita è decisamente superiore.

Se definisci OnFailure= all'interno di [Service] , systemd (almeno la versione 234 di Fedora 27) si lamenta con:

software.service:6: Unknown lvalue 'OnFailure' in section 'Service'

Non sono sicuro se lo vedi nei tuoi log o no... (Forse questo è stato aggiunto in systemd recente?) Questo dovrebbe essere un indizio di cosa sta succedendo lì.


Linux
  1. Come utilizzare il comando Systemctl per gestire i servizi Systemd

  2. Come creare un servizio Systemd in Linux

  3. In che modo Systemd utilizza gli script /etc/init.d?

  4. Qual è il modo di usare Xargs attraverso un tubo?

  5. Debian:modo corretto di utilizzare Onfailure in Systemd?

Gestisci l'avvio usando systemd

Comandi Systemctl per gestire il servizio Systemd

Gestire cgroup con systemd

Modo corretto di usare Ubuntu systemctl per controllare Systemd

systemd - Dando al mio servizio più argomenti

Uso di CPUQuota in systemd