Come configurare systemd per uccidere e riavviare un demone al ricaricamento?


12

Ho un demone di vecchia scuola che voglio controllare usando systemd. Quando il suo file di configurazione cambia, deve essere ucciso e riavviato. In altre parole, dopo aver modificato il file di configurazione, systemctl reload MYSERVICEdovrebbe terminare il processo e riavviarlo.

Tentativo 1: provare le impostazioni predefinite. Questo dice a systemd come avviare il demone, ma non come ricaricarlo.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple

Di conseguenza, starte restartfunziona, ma reloaddà questo errore:

# systemctl reload MYSERVICE
Failed to reload MYSERVICE.service: Job type reload is not applicable for unit MYSERVICE.service.

Tentativo 2: spiegagli come terminare il processo. Questo uccide il processo ma systemd non lo riavvia per me.

[Service]
ExecStart=/usr/bin/MYSERVICE
Type=simple
ExecReload=/bin/kill -HUP $MAINPID

...seguito da...

# systemctl daemon-reload
# systemctl reload MYSERVICE

... termina il processo ma non si riavvia automaticamente.

Tentativo 3: utilizzare ExecReload per riavviare anche il processo. Questo non riesce per alcuni motivi:

ExecReload=/bin/kill -HUP $MAINPID ; /usr/bin/MYSERVICE

... il messaggio di errore che visualizzo ...:

# systemctl daemon-reload
# systemctl reload MYSERVICE
Job for MYSERVICE.service failed because the control process exited with error code. See "systemctl status MYSERVICE.service" and "journalctl -xe" for details.

Mi aspetterei che ci sia un ReloadType = kill_and_restart o qualcosa del genere, ma nessuna tale fortuna.

Come dire a systemd di uccidere e riavviare un demone al caricamento?


Questo ha davvero bisogno di essere calzato in ricarica , dove non si adatta esattamente? Non puoi fare in modo che il demone si comporti in modo sensato?
Michael Hampton,

Grazie @MichaelHampton, ma questa non è una situazione in cui posso riscrivere il programma. Apprezzo il tuo suggerimento utile. Detto questo, sono sicuro che questo è un caso d'uso comune e una risposta canonica potrebbe aiutare molte persone.
TomOnTime

1
Sono sicuro che una risposta potrebbe aiutare qualcuno, quindi ho votato a favore della domanda. Non sono sicuro che si tratti di un caso d'uso comune. Avendo usato systemd per circa cinque anni, quasi dal giorno in cui è stato lanciato sul mondo, questa è la prima volta che ricordo di aver sentito parlare di qualcuno che tentava questo tipo di scenario. È possibile che io abbia frainteso qualcosa a causa della mancanza di dettagli.
Michael Hampton,

Risposte:


16

La risposta è "tu no"! Ma abbiamo buone notizie.

La filosofia di systemd è che la ricarica è facoltativa e dovrebbe essere lasciata indefinita se non c'è una vera funzionalità di ricarica. Definirei la "vera funzionalità di ricarica" ​​come una ricarica che non uccide e riavvia il servizio, o farebbe cambiare il suo PID al servizio. In altre parole, systemd vuole solo riflettere quali funzionalità esistono.

Invece, dovresti usare systemctl reload-or-restartquale eseguirà un ricaricamento se esiste, e un riavvio in caso contrario.

Dalla pagina man ...

   reload-or-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. If the units are not running yet, they will be started.

   reload-or-try-restart PATTERN...
       Reload one or more units if they support it. If not, restart them
       instead. This does nothing if the units are not running. Note that,
       for compatibility with SysV init scripts, force-reload is
       equivalent to this command.

Pertanto: (1) lascia vuoto ExecReload, (2) usa systemctl reload-or-restart MYSERVICEe, (3) dovresti essere pronto.

Se si tenta di utilizzare ExecReload per definire un modo per terminare e riavviare il servizio, avrà un nuovo PID e il sistema verrà confuso.


3

La filosofia di systemd reloadè facoltativa e l'utente di systemd dovrebbe sapere, per ogni servizio, se deve chiamarlo reloado simularlo chiamando restart.

Pertanto, la risposta alla tua domanda è: "Non funziona e non dovrebbe. Per favore, risolvilo al prossimo livello superiore."

In altre parole, systemd vuole che tu implementi " ricaricare " solo se il servizio sottostante supporta una vera funzionalità di ricarica ... cioè una ricarica che non uccide e riavvia il servizio, o fa cambiare il suo PID al servizio. In altre parole, systemd vuole solo riflettere quali funzionalità esistono.

Forse ti starai chiedendo: ma non sarebbe più facile se potessi implementare un ricaricamento "falso" permettendo ExecReloaddi uccidere e riavviare il servizio? Quindi potrei usare systemctl reload FOOtutti i miei servizi e non dovrei ricordare quali lo supportano e quali no?

Sì, sarebbe più facile, ma non sarebbe il modo di systemd. Systemd vuole che il chiamante sia la cosa che sa se reloadesiste per il servizio. Systemd vuole essere un'interfaccia comune alle funzionalità esistenti, non vuole essere responsabile per colmare le lacune.

Ad esempio, fantoccio presuppone che un servizio guidato da systemd non abbia reloade per impostazione predefinita uccida e riavvii il processo . Se il tipo di servizio [] ha aggiunto un modo per specificare che il ricaricamento esiste e che deve essere utilizzato su notifica, dovrà sapere quali servizi hanno o non hanno un ricaricamento nativo. Chef e tutti gli altri sistemi dovrebbero anche imparare la stessa cosa perché systemd vuole che sia risolto a quel livello. (MiniRant: per avviare un processo systemd sembra essere il sistema onnicomprensivo, onnicomprensivo e personalizzante dello spazio-i-tutto-al-mio-livello. Quindi non posso dirti perché non lo fa estendere questa filosofia al ricaricamento. Forse uno degli autori può suonare qui.)


1
C'è systemctl reload-or-restart, che ricaricherà il servizio se lo supporta e lo riavvierà in caso contrario. Non ho idea del perché Puppet faccia questa ipotesi.
Michael Hampton,
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.