Eu originalmente fiz essa pergunta no StackOverflow. Então percebi que este é provavelmente um lugar melhor.
Eu tenho a instalação do bluepill para monitorar meus processos delayed_job. (Aplicação Ruby On Rails)
Usando o Ubuntu 12.10.
Estou iniciando e monitorando o próprio serviço bluepill usando o Ubuntu upstart
. Minha configuração inicial está abaixo ( /etc/init/bluepill.conf
).
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
expect daemon
exec sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
Eu também tentei com em expect fork
vez de expect daemon
. Eu também tentei remover a expect...
linha completamente.
Quando a máquina inicializa, o bluepill inicia bem.
$ ps aux | grep blue
root 1154 0.6 0.8 206416 17372 ? Sl 21:19 0:00 bluepilld: <app_name>
O PID do processo de bluepill é 1154 aqui. Mas upstart
parece estar rastreando o PID errado. Ele está rastreando um PID que não existe.
$ initctl status bluepill
bluepill start/running, process 990
Eu acho que está rastreando o PID do sudo
processo que iniciou o processo do bluepill.
Isso está impedindo que o processo do bluepill seja reaparecido se eu forçar a matança usando o bluepill kill -9
.
Além disso, acho que, devido ao rastreamento incorreto do PID, a reinicialização / desligamento simplesmente trava e eu tenho que reiniciar a máquina todas as vezes.
Qual poderia ser o problema aqui?
ATUALIZAÇÃO :
O problema permanece até hoje (3 de maio de 2015) no Ubuntu 14.04.2.
O problema não é por causa do uso do sudo. Não estou mais usando o sudo. Minha configuração inicial atualizada é a seguinte:
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90
expect daemon
script
shared_path=/home/deploy/websites/some_app/shared
bluepill load $shared_path/config/delayed_job.bluepill
end script
Quando a máquina é inicializada, o programa carrega bem. Mas o iniciante ainda rastreia o PID errado, conforme descrito acima.
A solução alternativa mencionada nos comentários pode corrigir o problema de interrupção. Eu ainda não tentei.
ps aux | grep 990
deve fazê-lo, maspstree 990
pode ser mais informativo.Respostas:
Tarde demais, mas espero que isso possa ajudar outros usuários.
Há um erro documentado no upstart que pode fazer com que o initctl rastreie o PID errado se você especificar a
fork
sub-rotina incorreta em uma configuração inicial: https://bugs.launchpad.net/upstart/+bug/406397O que acontece é que o iniciante verifica a
fork
estrofe e determina quantos processos bifurcados deve verificar antes de escolher o PID "verdadeiro" do programa que está sendo controlado. Se você especificarexpect fork
ouexpect daemon
mas seu programa não bifurcar um número suficiente de vezes,start
será interrompido. Por outro lado, se o seu processo for bifurcar muitas vezes,initctl
rastreará o PID errado. Teoricamente, ele deve ser documentado nesta seção do livro de receitas inicial , mas como você pode ver nessa situação, há um PID associado ao processo morto, quando não deveria existir.As implicações disso são explicadas nos comentários do rastreador de bugs, mas vou resumir aqui: além de
initctl
não ser capaz de parar o processo daemon e ficar preso em um estado ilegal / não documentado<service> start/killed, process <pid>
, se o processo pertencente a esse PID parar (e geralmente será ), o PID é liberado para reutilização pelo sistema.Se você emitir
initctl stop <service>
ouservice <service> stop
,initctl
matará esse PID na próxima vez que ele aparecer. Isso significa que, em algum momento no caminho, se você não reiniciar após cometer esse erro, o próximo processo para usar esse PID será eliminado imediatamente,initctl
mesmo que não seja o daemon. Pode ser algo tão simples quantocat
ou tão complexo quantoffmpeg
, e é difícil descobrir por que o seu pacote de software travou no meio de alguma operação de rotina.Portanto, o problema é que você especificou a
expect
opção errada para o número de garfos que o processo do daemon realmente produz. Eles dizem que há uma reescrita inicial que soluciona esse problema, mas a partir do 1.8 inicial (último Ubuntu 13.04 / janeiro de 2014) o problema ainda está presente.Como você usou
expect daemon
e acabou com esse problema, recomendo tentarexpect fork
.Edit: Aqui está um script compatível com o Ubuntu BASH ( original por Wade Fitzpatrick modificado para usar o Ubuntu
sleep
) que gera processos até que o espaço de endereço do ID do processo disponível se esgote; nesse ponto, ele começa em 0 e segue até o "travado" PID. Um processo é gerado no PID,initctl
é desligado e oinitctl
mata e redefine.fonte
Para o exemplo fornecido:
uma solução rápida para mim é:
fonte: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37
Espero que isso seja útil. O que está acontecendo é explicado nas outras respostas.
fonte
reboot
pode às vezes ser preferível e também corrige isso.A menos que você esteja executando um trabalho inicial no nível do usuário ou usando a sub - rotina setuid - seu trabalho estará sendo executado como raiz.
Como o Upstart já está sendo executado como root, por que você precisa usar o sudo em sua
exec
estrofe?Usar
sudo
ousu
naexec
estrofe causou os mesmos problemas para mim, como você descreve aqui.Normalmente, experimentarei o item 1 OU os 1 E 2:
Obviamente, além disso, você deve fazer com que a
expect
estrofe reflita o número correto de garfos.YMMV, mas para mim:
exec
estrofe com o número correto de garfos especificados geralmente resulta na situação 1 acima.exec
) resulta na situação 1 E 2 acima.fonte