Upstart tracking errado PID do processo - não respawning

11

Eu originalmente fiz essa pergunta no StackOverflow. Então percebi que este é provavelmente um lugar melhor.

Eu tenho a configuração do bluepill para monitorar meus processos de delayed_job. (Aplicação Ruby On Rails)

Usando o Ubuntu 12.10.

Estou iniciando e monitorando o serviço bluepill usando o upstart do Ubuntu. Minha configuração do upstart 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 expect fork em vez de expect daemon . Eu também tentei remover a linha expect... 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 bluepill é 1154 aqui. Mas upstart parece estar rastreando o PID errado. Está rastreando um PID que não existe.

$ initctl status bluepill
bluepill start/running, process 990

Acho que está acompanhando o PID do processo sudo que iniciou o processo do bluepill.

Isso está impedindo que o processo do bluepill seja recuperado se eu matar com força o bluepill usando kill -9 .

Além disso, acho que por causa do PID errado que está sendo rastreado, reinicialização / desligamento apenas trava e eu tenho que reinicializar a máquina toda vez.

Qual poderia ser o problema aqui?

UPDATE :

O problema permanece até hoje (3 de maio de 2015) no Ubuntu 14.04.2.

O problema não é devido ao uso do sudo. Eu não estou mais usando o sudo. Minha configuração upstart atualizada é esta:

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 inicia, o programa é carregado muito bem. Mas o upstart ainda rastreia o PID errado, como descrito acima.

A solução mencionada nos comentários pode corrigir o problema pendente. Eu ainda não tentei isso.

    
por Anjan 12.07.2013 / 10:28

3 respostas

8

Muito tarde, mas espero que isso possa ajudar outros usuários.

Existe um bug documentado no upstart que pode fazer com que o initctl rastreie o PID errado se você especificar a sub-rotina fork incorreta em uma configuração upstart: link

O que acontece é que o upstart verifica a estrofe fork e determina quantos processos bifurcados deve verificar antes de escolher o PID "verdadeiro" do programa que está sendo controlado. Se você especificar expect fork ou expect daemon , mas seu programa não for bifurcado um número suficiente de vezes, start será interrompido. Se, por outro lado, seu processo se bifurcar muitas vezes, initctl rastreará o PID incorreto. Teoricamente, 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 disto são explicadas nos comentários do bugtracker, 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 pertencer para que o PID pare (e geralmente será) então o PID é liberado para reutilização pelo sistema.

Se você emitir initctl stop <service> ou service <service> stop , initctl eliminará esse PID na próxima vez que aparecer. Isso significa que, em algum ponto da estrada, se você não reiniciar depois de cometer esse erro, o próximo processo para usar esse PID será imediatamente eliminado por initctl , mesmo que não seja o daemon. Pode ser algo tão simples como cat ou tão complexo quanto ffmpeg , e você teria dificuldade em descobrir por que seu pacote de software falhou no meio de alguma operação de rotina.

Portanto, o problema é que você especificou a opção expect errada para o número de forquilhas que o processo daemon realmente faz. Eles dizem que há uma reescrita que resolve esse problema, mas a partir da versão 1.8 (mais recente Ubuntu 13.04 / janeiro de 2014), o problema ainda está presente.

Como você usou expect daemon e acabou com esse problema, recomendo que você tente expect fork .

Edit: Aqui está um script compatível com Ubuntu BASH ( original de Wade Fitzpatrick modificado para use o Ubuntu sleep ) que gera processos até que o espaço de endereço de ID do processo disponível esteja esgotado, ponto no qual ele inicia em 0 e trabalha até o PID "preso". Em seguida, é gerado um processo no PID initctl , e initctl o mata e redefine.

#!/bin/bash

# usage: sh /tmp/upstart_fix.sh <pid>

sleep 0.001 &
firstPID=$!
#first lets exhaust the space
while (( $! >= $firstPID ))
do
    sleep 0.001 &
done

# [ will use testPID itself, we want to use the next pid
declare -i testPID
testPID=$(( - 1))
while (( $! < $testPID ))
do
    sleep 0.001 &
done

# fork a background process then die so init reaps its pid
sleep 3 &
echo "Init will reap PID=$!"
kill -9 $$
# EOF
    
por Dakota 14.02.2014 / 23:43
5

Para o exemplo fornecido:

$ initctl status bluepill
bluepill start/running, process 990

uma solução rápida para mim é:

# If upstart gets stuck for some job in stop/killed state
export PID=990
cd /usr/local/bin
wget https://raw.github.com/ion1/workaround-upstart-snafu/master/workaround-upstart-snafu
chmod +x workaround-upstart-snafu
./workaround-upstart-snafu $PID

fonte: link

Espero que isso seja útil. O que está acontecendo é explicado nas outras respostas.

    
por Szymon Jeż 10.10.2014 / 10:24
0

A menos que você esteja executando um trabalho de nível de usuário Upstart ou usando a estrofe setuid - então seu trabalho está sendo executado como root.

Como o Upstart já está sendo executado como root, por que você precisa usar o sudo na sua estrofe exec ?

Usar sudo ou su na sub-rotina exec causou os mesmos problemas para mim, conforme descrito aqui.

Normalmente, vou experimentar o item 1 OU ambos 1 AND 2:

  1. o upstart segue o PID incorreto
  2. o upstart trava quando tento parar o processo

É claro que você também precisa que a estrofe expect reflita o número correto de garfos.

YMMV, mas para mim:

  • usar sudo ou su na estrofe exec com o número correto de garfos especificado geralmente resulta na situação 1 acima.
  • o número incorreto de garfos especificado (com o nosso sem sudo / su em exec ) resulta nas situações 1 e 2 acima.
por user12345 27.07.2014 / 22:56