Perché l’upstart continua a rigenerare il mio processo?

Ho scritto uno script upstart per avviare un demone all’interno di una sessione tmux. Funziona bene e respawn il processo se muore in modo imprevisto, ma non riesco a fermarlo manualmente.

Il lavoro (chiamato bukkit) si presenta così:

start on filesystem stop on runlevel [!2345] respawn respawn limit 5 30 chdir /home/minecraft/bukkit expect daemon kill timeout 30 pre-start script test -x /home/minecraft/bukkit/craftbukkit-0.0.1-SNAPSHOT.jar || { stop; exit 0; } end script pre-stop script tmux send -t bukkit "stop" tmux send -t bukkit "Enter" sleep 10 # Wait for server to shut down properly end script exec tmux new-session -d -s minecraft -n bukkit "sudo -u minecraft -- /home/minecraft/java/jre1.6.0_27/bin/java -Xincgc -Xmx1G -jar /home/minecraft/bukkit/craftbukkit-0.0.1-SNAPSHOT.jar" 

Quando stop bukkit uno stop bukkit si blocca per ~ 10 secondi (il timer di spegnimento, immagino) e stampa bukkit start/running, process 2391 . Quando ho impostato startstart per il debug, ho trovato queste righe rilevanti nel log:

 Sep 21 19:14:59 cheftest init: bukkit goal changed from start to stop Sep 21 19:14:59 cheftest init: bukkit main process (2499) exited normally Sep 21 19:14:59 cheftest init: bukkit main process ended, respawning Sep 21 19:14:59 cheftest init: bukkit goal changed from stop to respawn 

Perché l’upstart continua a rigenerare il mio processo quando dovrebbe fermarlo?

La difficoltà qui è la combinazione di ‘respawn’ con uno script di pre-arresto che dice al processo di fermarsi. Da init (5):

  respawn A service or task with this stanza will be automatically started if it should stop abnormally. All reasons for a service stopping, except the stop(8) command itself, are considered abnormal. Tasks may exit with a zero exit status to prevent being respawned. 

La documentazione è un po ‘oscura sul punto se l’uscita con uno stato di uscita zero dovrebbe causare un respawn. Tuttavia, fondamentalmente hai trovato un bug di partenza perché il processo principale che termina quando l’objective è “stop” non dovrebbe comportare una modifica a “respawn”.

Per ovviare a questo errore, dovresti essere in grado di utilizzare “exit normale” per informare upstart che questo è un modo normale per interrompere il lavoro e che non dovrebbe essere respawn.

  normal exit STATUS|SIGNAL... Additional exit statuses or even signals may be added, if the job process terminates with any of these it will not be considered to have failed and will not be respawned. normal exit 0 1 TERM HUP 

Si noti che, in generale, sarebbe più robusto uccidere il processo con un segnale (specificando “kill signal N” se necessario) anziché con un processo di pre-arresto che emette comandi; ma ovviamente questo non è sempre ansible se il servizio non supporta l’arresto pulito al ricevimento di un segnale.

Nel caso in cui qualcun altro finisca qui, ho inviato una patch funzionante al bug:

https://bugs.launchpad.net/upstart/+bug/568288/comments/6

Per questo è stata rilasciata una correzione nella versione 1.10, quindi ora non dovrebbe accadere.