Upstart-Tracking falscher PID des Prozesses - kein Respawning

11

Ich habe diese Frage ursprünglich bei StackOverflow gestellt. Dann wurde mir klar, dass dies wahrscheinlich ein besserer Ort ist.

Ich habe ein Bluepill-Setup, um meine Prozesse mit verzögertem Job zu überwachen. (Ruby On Rails-Anwendung)

Verwenden von Ubuntu 12.10.

Ich starte und überwache den Bluepill-Dienst selbst mit Ubuntus upstart. Meine Upstart-Konfiguration ist unten ( /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

Ich habe es auch mit expect forkstatt versucht expect daemon. Ich habe auch versucht, die expect...Linie vollständig zu entfernen .

Wenn die Maschine startet, startet Bluepill einwandfrei.

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

Die PID des Bluepill-Prozesses beträgt hier 1154. Aber upstartscheint die falsche PID - Tracking zu werden. Es verfolgt eine PID, die nicht existiert.

$ initctl status bluepill
bluepill start/running, process 990

Ich denke, es verfolgt die PID des sudoProzesses, der den Bluepill-Prozess gestartet hat.

Dies verhindert, dass der Bluepill-Prozess erneut ausgeführt wird, wenn ich Bluepill mit Gewalt töte kill -9.

Außerdem denke ich, dass der Neustart / das Herunterfahren aufgrund der falschen PID, die verfolgt wird, nur hängt und ich die Maschine jedes Mal hart zurücksetzen muss.

Was könnte hier das Problem sein?

UPDATE :

Das Problem bleibt ab heute (3. Mai 2015) unter Ubuntu 14.04.2 bestehen.

Das Problem liegt nicht an der Verwendung von sudo. Ich benutze kein Sudo mehr. Meine aktualisierte Upstart-Konfiguration lautet wie folgt:

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

Wenn der Computer startet, wird das Programm einwandfrei geladen. Upstart verfolgt jedoch immer noch die falsche PID, wie oben beschrieben.

Die in den Kommentaren erwähnte Problemumgehung kann das Problem beim Aufhängen beheben. Ich habe es aber nicht versucht.

Anjan
quelle
Haben Sie versucht zu sehen, was Prozess 990 ist? ps aux | grep 990sollte es tun, pstree 990könnte aber informativer sein.
Oli
Es existiert kein Prozess mit der PID von 990.
Anjan
2
Was die Notwendigkeit eines Neustarts betrifft, um den Start wieder in einen guten Zustand zu versetzen
andersonbd1
und Sie können dieses Tool mit diesem Befehl beschleunigen: $ echo 3000 | sudo tee / proc / sys / kernel / pid_max
andersonbd1

Antworten:

8

Ziemlich spät, aber hoffentlich kann dies anderen Benutzern helfen.

Es gibt einen dokumentierten Fehler in upstart, der dazu führen kann, dass initctl die falsche PID verfolgt, wenn Sie forkin einer Upstart-Konfiguration die falsche Zeilengruppe angeben : https://bugs.launchpad.net/upstart/+bug/406397

Was passiert, ist, dass Upstart die Zeilengruppe überprüft forkund bestimmt, wie viele gegabelte Prozesse überprüft werden sollen, bevor die "wahre" PID des zu steuernden Programms ausgewählt wird. Wenn Sie angeben expect forkoder expect daemonaber Ihr Programm nicht ausreichend oft startgabelt, hängt es. Wenn sich Ihr Prozess andererseits zu oft teilt, initctlwird die falsche PID verfolgt. Theoretisch sollte dies in diesem Abschnitt des Upstart-Kochbuchs dokumentiert werden. Wie Sie jedoch in dieser Situation sehen können, ist dem getöteten Prozess eine PID zugeordnet, wenn dies nicht der Fall sein sollte.

Die Auswirkungen davon werden in den Bugtracker-Kommentaren erläutert, aber ich werde hier zusammenfassen: Abgesehen initctldavon, dass der Daemon-Prozess nicht gestoppt werden kann und in einem undokumentierten / illegalen Zustand stecken bleibt <service> start/killed, process <pid>, wenn der zu dieser PID gehörende Prozess stoppt (und dies normalerweise der Fall ist) ) wird dann die PID zur Wiederverwendung durch das System freigegeben.

Wenn Sie initctl stop <service>oder ausgeben service <service> stop, initctlwird diese PID beim nächsten Erscheinen beendet. Dies bedeutet, dass irgendwo später, wenn Sie nach diesem Fehler keinen Neustart durchführen, der nächste Prozess, bei dem diese PID verwendet wird, sofort beendet wird initctl, obwohl dies nicht der Dämon ist. Es könnte so einfach catoder so komplex sein ffmpeg, und es fällt Ihnen schwer herauszufinden, warum Ihr Softwarepaket mitten in einem Routinevorgang abgestürzt ist.

Das Problem ist also, dass Sie die falsche expectOption für die Anzahl der Gabeln angegeben haben, die Ihr Daemon-Prozess tatsächlich macht. Sie sagen, dass es ein Upstart-Rewrite gibt, das dieses Problem behebt, aber ab Upstart 1.8 (aktuell Ubuntu 13.04 / Januar 2014) ist das Problem immer noch vorhanden.

Da Sie expect daemondieses Problem verwendet haben und am Ende aufgetreten sind, empfehle ich, es zu versuchen expect fork.

Bearbeiten: Hier ist ein Ubuntu BASH-kompatibles Skript ( Original von Wade Fitzpatrick, modifiziert, um Ubuntu zu verwenden sleep), das Prozesse erzeugt, bis der verfügbare Adressraum der Prozess-ID erschöpft ist. An diesem Punkt beginnt es wieder bei 0 und arbeitet sich bis zum "stecken gebliebenen" vor. PID. Ein Prozess wird dann erzeugt, wenn die PID initctlaufgelegt wird, initctlihn beendet und zurückgesetzt wird.

#!/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
quelle
Diese Antwort enthält einige nützliche und interessante Informationen. Es ist mir jedoch unklar, wie diese Antwort die ursprüngliche Frage beantwortet, als @Anjan erwähnte: "Ich habe es auch mit
user12345
5

Für das bereitgestellte Beispiel:

$ initctl status bluepill
bluepill start/running, process 990

Eine schnelle Lösung für mich ist:

# 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

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

Ich hoffe das wird hilfreich sein. Was los ist, wird in den anderen Antworten erklärt.

Szymon Jeż
quelle
Schönes Skript. Dies kann ein oder zwei Minuten dauern. A ist rebootmanchmal vorzuziehen und behebt dies auch.
Peter Ilfrich
0

Wenn Sie keinen Upstart-Job auf Benutzerebene ausführen oder die Zeilengruppe setuid verwenden, wird Ihr Job als root ausgeführt.

Da Upstart bereits als Root ausgeführt wird, warum müssen Sie in Ihrer Zeilengruppe überhaupt sudo verwenden exec?

Die Verwendung von sudooder suin der execStrophe hat für mich die gleichen Probleme verursacht, die Sie hier beschreiben.

Normalerweise erlebe ich Punkt 1 ODER sowohl 1 als auch 2:

  1. Der Start erfolgt nach der falschen PID
  2. Der Emporkömmling hängt, wenn ich versuche, den Prozess zu stoppen

Zusätzlich muss die expectZeilengruppe natürlich die richtige Anzahl von Gabeln widerspiegeln.

YMMV, aber für mich:

  • Die Verwendung von sudo oder su in der execZeilengruppe mit der richtigen Anzahl von Gabeln führt im Allgemeinen zu Situation 1 oben.
  • Eine falsche Anzahl der angegebenen Gabeln (mit unserer ohne sudo / su in exec) führt zu Situation 1 UND 2 oben.
user12345
quelle