El seguimiento inicial PID incorrecto del proceso - no reaparece


11

Originalmente hice esta pregunta en StackOverflow. Entonces me di cuenta de que este es probablemente un lugar mejor.

Tengo una configuración de bluepill para monitorear mis procesos delayed_job. (Aplicación Ruby On Rails)

Usando Ubuntu 12.10.

Estoy comenzando y monitoreando el servicio bluepill en sí mismo usando Ubuntu upstart. Mi configuración inicial está debajo ( /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

También he intentado con en expect forklugar de expect daemon. También he intentado eliminar la expect...línea por completo.

Cuando la máquina arranca, bluepill comienza bien.

$ ps aux | grep blue
root      1154  0.6  0.8 206416 17372 ?        Sl   21:19   0:00 bluepilld: <app_name>

El PID del proceso bluepill es 1154 aquí. Pero upstartparece estar rastreando el PID incorrecto. Está rastreando un PID que no existe.

$ initctl status bluepill
bluepill start/running, process 990

Creo que está rastreando el PID del sudoproceso que inició el proceso bluepill.

Esto evita que el proceso de bluepill se reaparezca si mato a la fuerza usando bluepill kill -9.

Además, creo que debido al seguimiento incorrecto del PID, el reinicio / apagado simplemente se bloquea y tengo que reiniciar la máquina cada vez.

¿Cuál podría ser el problema aquí?

ACTUALIZACIÓN :

El problema continúa hasta hoy (3 de mayo de 2015) en Ubuntu 14.04.2.

El problema no es por usar sudo. Ya no estoy usando sudo. Mi configuración inicial actualizada es 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

Cuando la máquina arranca, el programa se carga bien. Pero el arranque aún sigue el PID incorrecto, como se describió anteriormente.

La solución mencionada en los comentarios puede solucionar el problema pendiente. Sin embargo, no lo he probado.


¿Has intentado ver qué proceso es el 990? ps aux | grep 990debería hacerlo pero pstree 990podría ser más informativo.
Oli

No existe ningún proceso con el PID de 990.
Anjan

2
en cuanto a la necesidad de reiniciar para volver a arrancar en un buen estado, vea esta buena herramienta: github.com/ion1/workaround-upstart-snafu
andersonbd1

y puede acelerar esa herramienta con este comando: $ echo 3000 | sudo tee / proc / sys / kernel / pid_max
andersonbd1

Respuestas:


8

Muy tarde, pero espero que esto pueda ser de ayuda para otros usuarios.

Hay un error documentado en el arranque que puede hacer que initctl rastree el PID incorrecto si especifica la sección incorrecta forken una configuración de arranque: https://bugs.launchpad.net/upstart/+bug/406397

Lo que sucede es que el arranque comprueba la forksección y determina cuántos procesos bifurcados debe verificar antes de elegir el PID "verdadero" del programa que se controla. Si especifica expect forko expect daemonpero su programa no se bifurca un número suficiente de veces, startse bloqueará. Si, por otro lado, su proceso se bifurca demasiadas veces, initctlrastreará el PID incorrecto. Teóricamente, debería documentarse en esta sección del libro de cocina inicial , pero como puede ver en esta situación, hay un PID asociado con el proceso finalizado cuando no debería existir.

Las implicaciones de esto se explican en los comentarios del rastreador de errores, pero resumiré aquí: además de initctlno poder detener el proceso del demonio y quedar atrapado en un estado indocumentado / ilegal <service> start/killed, process <pid>, si el proceso que pertenece a ese PID se detiene (y generalmente lo hará) ), el PID se libera para que el sistema lo reutilice.

Si emite initctl stop <service>o service <service> stop, initctlmatará ese PID la próxima vez que aparezca. Esto significa que, en el futuro si no reinicias después de cometer este error, el siguiente proceso para usar ese PID se eliminará de inmediato initctl, aunque no sea el demonio. Podría ser algo tan simple cato tan complejo como ffmpeg, y le sería difícil descubrir por qué su paquete de software se bloqueó en medio de alguna operación de rutina.

Entonces, el problema es que especificó la expectopción incorrecta para la cantidad de bifurcaciones que su proceso de demonio realmente hace. Dicen que hay una reescritura inicial que aborda este problema, pero a partir de la versión inicial 1.8 (última versión de Ubuntu 13.04 / enero de 2014) el problema aún está presente.

Como usaste expect daemony terminaste con este problema, te recomiendo intentarlo expect fork.

Editar: Aquí hay un script compatible con Ubuntu BASH ( original de Wade Fitzpatrick modificado para usar Ubuntu sleep) que genera procesos hasta que se agota el espacio de dirección de ID de proceso disponible, momento en el cual comienza de nuevo en 0 y avanza hasta el "atascado" PID Luego se genera un proceso cuando initctlse cuelga el PID , lo initctlmata y se reinicia.

#!/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

Esta respuesta tiene información útil e interesante, sin embargo, no está claro para mí cómo esta respuesta responde a la pregunta inicial, ya que @Anjan mencionó "También he intentado con esperar fork en lugar de esperar daemon. También he intentado eliminar la línea esperar ... completamente. "
user12345

5

Para el ejemplo proporcionado:

$ initctl status bluepill
bluepill start/running, process 990

Una solución rápida para mí es:

# 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

fuente: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37

Espero que esto sea útil. Lo que está sucediendo se explica en las otras respuestas.


Buen guión. Esto puede tomar uno o dos minutos. A rebootveces puede ser preferible y también soluciona esto.
Peter Ilfrich

0

A menos que esté ejecutando un trabajo de nivel de usuario Upstart o utilizando la stanza setuid , su trabajo se ejecutará como root.

Dado que Upstart ya se está ejecutando como root, ¿por qué necesita usar sudo en su execestrofa?

Usar sudoo suen la execestrofa me ha causado los mismos problemas que usted describe aquí.

Por lo general, experimentaré el elemento 1 O ambos 1 Y 2:

  1. el advenedizo sigue el PID incorrecto
  2. advenedizo se cuelga cuando intento detener el proceso

Por supuesto, además debe hacer que la expectestrofa refleje el número correcto de horquillas.

YMMV, pero para mí:

  • el uso de sudo o su en la execestrofa con el número correcto de horquillas especificado generalmente da como resultado la situación 1 anterior.
  • el número incorrecto de horquillas especificado (con nuestro sin sudo / su in exec) da como resultado las situaciones 1 y 2 anteriores.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.