Acompanhamento inicial PID incorreto do processo - não reaparecendo

11

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 forkvez 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 upstartparece 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 sudoprocesso 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.

Anjan
fonte
você já tentou analisar qual é o processo 990? ps aux | grep 990deve fazê-lo, mas pstree 990pode ser mais informativo.
Oli
Nenhum processo com o PID 990 existe.
Anjan
2
no que diz respeito à necessidade de reinicializar para obter um upstart de volta a um bom estado - veja esta boa ferramenta: github.com/ion1/workaround-upstart-snafu
andersonbd1
e você pode acelerar essa ferramenta com este comando: $ echo 3000 | sudo tee / proc / sys / kernel / pid_max
andersonbd1

Respostas:

8

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 forksub-rotina incorreta em uma configuração inicial: https://bugs.launchpad.net/upstart/+bug/406397

O que acontece é que o iniciante verifica a forkestrofe e determina quantos processos bifurcados deve verificar antes de escolher o PID "verdadeiro" do programa que está sendo controlado. Se você especificar expect forkou expect daemonmas seu programa não bifurcar um número suficiente de vezes, startserá interrompido. Por outro lado, se o seu processo for bifurcar muitas vezes, initctlrastreará 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 initctlnã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>ou service <service> stop, initctlmatará 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, initctlmesmo que não seja o daemon. Pode ser algo tão simples quanto catou tão complexo quanto ffmpeg, 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 expectopçã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 daemone acabou com esse problema, recomendo tentar expect 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 o initctlmata 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 - 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
Dakota
fonte
Esta resposta tem algumas informações úteis e interessantes, no entanto, não está claro para mim como essa resposta responde à pergunta inicial, como @Anjan mencionou "Eu também tentei com o fork de expectativa em vez do daemon de expectativa. Também tentei remover a linha de espera ... completamente. "
user12345
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: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37

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

Szymon Jeż
fonte
Bom roteiro. Isso pode levar um ou dois minutos. Um rebootpode às vezes ser preferível e também corrige isso.
Peter Ilfrich
0

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 execestrofe?

Usar sudoou suna execestrofe causou os mesmos problemas para mim, como você descreve aqui.

Normalmente, experimentarei o item 1 OU os 1 E 2:

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

Obviamente, além disso, você deve fazer com que a expectestrofe reflita o número correto de garfos.

YMMV, mas para mim:

  • o uso de sudo ou su na execestrofe com o número correto de garfos especificados geralmente resulta na situação 1 acima.
  • O número incorreto de garfos especificado (com o nosso sem sudo / su in exec) resulta na situação 1 E 2 acima.
user12345
fonte