Por que o iniciante continua reaparecendo no meu processo?

19

Eu escrevi um script inicial para iniciar um daemon dentro de uma sessão do tmux. Funciona bem e reaparece o processo se ele morrer inesperadamente, mas não consigo pará-lo manualmente.

O trabalho (chamado bukkit) fica assim:

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 emito um stop bukkit, congela por ~ 10 segundos (o temporizador, eu acho) e imprime bukkit start/running, process 2391. Quando configurei o upstart para depurar, encontrei estas linhas relevantes no 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

Por que o upstart continua reaparecendo no meu processo quando deveria interrompê-lo?

passy
fonte

Respostas:

23

A dificuldade aqui é a combinação de 'respawn' com um script de pré-parada que diz ao processo para parar. Do 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.

A documentação é um pouco incerta sobre se sair com um status de saída zero deve causar um reaparecimento. No entanto, fundamentalmente, você encontrou um bug inicial, porque o processo principal que termina quando o objetivo é 'parar' não deve resultar em uma alteração em 'reaparecer'.

Para contornar esse bug, você poderá usar a "saída normal" para informar ao iniciante que essa é uma maneira normal de interromper o trabalho e que não deve reaparecer.

  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

Observe que, em geral, seria mais robusto interromper o processo com um sinal (especificando "sinal de interrupção N", se necessário), em vez de com um processo de pré-parada que emita comandos; mas é claro que isso nem sempre é possível se o serviço não oferecer suporte ao desligamento limpo após o recebimento de um sinal.

slangasek
fonte
Obrigado, essa solução alternativa funciona perfeitamente para o meu caso. Encontrei um relatório de erro para isso, mas parece que esse comportamento é realmente projetado conscientemente.
passy 22/09
A resposta de Scott James Remnant não é o correto - é um bug, não uma decisão design, o caso de teste referido destina-se a testar algo mais :)
slangasek
2

Uma correção foi lançada na versão 1.10 para isso; agora, isso não deve acontecer.

cprcrack
fonte
Isso não fornece uma resposta para a pergunta. Para criticar ou solicitar esclarecimentos a um autor, deixe um comentário abaixo da postagem.
amc
2
Não tenho muita certeza disso. Minha resposta é equivalente a dizer: isso acontece porque você está usando uma versão antiga do upstart com um bug, use a versão 1.10 ou mais recente para corrigi-lo. Algo que nenhuma das outras respostas declara e, na verdade, a resposta mais útil agora que a correção foi lançada e há poucas razões para uma solução alternativa.
Cprcrack
Concordo que é útil, mas eu acho que é mais útil como um comentário à resposta aceita
amc