web-dev-qa-db-fra.com

Relancez le suivi du mauvais PID du processus - ne réapparaissez pas

J'ai initialement posé cette question sur StackOverflow. Puis réalisé que c'est probablement un meilleur endroit.

J'ai la configuration bluepill pour surveiller mes processus delay_job. (Ruby sur Rails application)

Utiliser Ubuntu 12.10.

Je lance et surveille le service bluepill lui-même à l'aide de upstart d'Ubuntu. Ma configuration initiale est ci-dessous (/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

J'ai également essayé avec expect fork au lieu de expect daemon. J'ai également essayé de supprimer complètement la ligne expect....

Lorsque la machine démarre, bluepill démarre bien.

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

Le PID du processus bluepill est ici 1154. Mais upstart semble suivre le mauvais PID. Il suit un PID qui n'existe pas.

$ initctl status bluepill
bluepill start/running, process 990

Je pense que cela suit le PID du processus Sudo qui a démarré le processus bluepill.

Ceci empêche le processus de bluepill d'être réapparu si je tue de force le bluepill en utilisant kill -9.

De plus, je pense qu'en raison du mauvais PID suivi, le redémarrage/arrêt se bloque et je dois réinitialiser la machine à chaque fois.

Quel pourrait être le problème ici?

UPDATE:

Le problème persiste aujourd'hui (3 mai 2015) sur Ubuntu 14.04.2.

Le problème n'est pas dû à l'utilisation de Sudo. Je n'utilise plus Sudo. Ma configuration upstart mise à jour est la suivante:

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

Lorsque la machine démarre, le programme se charge correctement. Mais Upstart suit toujours le mauvais PID, comme décrit ci-dessus.

La solution de contournement mentionnée dans les commentaires peut résoudre le problème suspendu. Je n'ai pas essayé, cependant.

11
Anjan

Assez tard, mais j'espère que cela pourra aider d'autres utilisateurs.

Il y a un bogue documenté dans upstart qui peut amener initctl à suivre le PID incorrect si vous spécifiez la strophe forkincorrecte dans une configuration upstart: https://bugs.launchpad.net/upstart/+bug/406397 =

Ce qui se passe, c’est que upstart vérifie la strophe forket détermine le nombre de processus en chaîne qu’il doit vérifier avant de choisir le "vrai" PID du programme contrôlé. Si vous spécifiez expect fork ou expect daemon mais que votre programme ne se divise pas en nombre suffisant, startse bloque. Si, en revanche, votre processus recourt trop souvent, initctlsuivra le mauvais PID. Théoriquement, il devrait être documenté dans ceci section du livre de recettes upstart , mais comme vous pouvez le voir dans cette situation, un PID est associé au processus tué, alors qu'il ne devrait pas en être.

Les implications de ceci sont expliquées dans les commentaires de bugtracker, mais je vais résumer ici: outre initctlname__, ne pas pouvoir arrêter le processus du démon et être bloqué dans un état non documenté/illégal <service> start/killed, process <pid>, si le processus appartenant à ce PID s'arrête (et généralement le PID est libéré pour être réutilisé par le système.

Si vous émettez initctl stop <service> ou service <service> stop, initctlsupprimera ce PID lors de sa prochaine apparition. Cela signifie que quelque part sur la route si vous ne redémarrez pas après avoir commis cette erreur, le prochain processus d'utilisation de ce PID sera immédiatement tué par initctlmême s'il ne s'agira pas du démon. Cela pourrait être quelque chose d'aussi simple que catou d'aussi complexe que ffmpegname__, et vous auriez du mal à comprendre pourquoi votre progiciel est tombé en panne au milieu d'une opération de routine.

Le problème est donc que vous avez spécifié la mauvaise option expectpour le nombre de fourches réellement générées par votre processus démon. Ils disent qu'il y a une réécriture récente qui aborde ce problème, mais qu'à partir de la dernière version 1.8 (dernière Ubuntu 13.04/Janvier 2014), le problème est toujours présent.

Puisque vous avez utilisé expect daemon et que vous avez eu ce problème, je vous recommande d'essayer expect fork.

Edit: Voici un script compatible Ubuntu BASH ( original de Wade Fitzpatrick modifié pour utiliser Ubuntu sleepname__) qui génère des processus jusqu'à épuisement de l'espace d'adressage d'ID de processus disponible. Il démarre à 0 et fonctionne à nouveau. son chemin jusqu'au PID "bloqué". Un processus est ensuite généré lorsque le PID initctlest suspendu et initctlle tue et le réinitialise.

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

Pour l'exemple fourni:

$ initctl status bluepill
bluepill start/running, process 990

une solution rapide pour moi est:

# 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

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

J'espère que cela vous sera utile. Ce qui se passe est expliqué dans les autres réponses.

5
Szymon Jeż

Sauf si vous exécutez un travail de niveau utilisateur Upstart ou à l'aide de la strophe setuid -, votre travail s'exécute en tant que root.

Comme Upstart fonctionne déjà en tant que root, pourquoi avez-vous besoin d'utiliser Sudo dans votre strophe execname__?

L'utilisation de Sudoou sudans la strophe execa causé les mêmes problèmes que ceux décrits ci-dessous.

En général, je vais faire l'expérience du point 1 OR à la fois 1 ET 2:

  1. upstart suit le PID incorrect
  2. upstart se bloque lorsque j'essaie d'arrêter le processus

Bien entendu, vous devez en outre que la strophe expectreflète le nombre correct de fourches.

YMMV, mais pour moi:

  • si vous utilisez Sudo ou su dans la strophe execavec le nombre correct de fourches spécifié, vous obtenez généralement la situation 1 ci-dessus.
  • nombre incorrect de forks spécifié (avec notre sans Sudo/su dans execname__) entraîne la situation 1 ET 2 ci-dessus.
0
user12345