Upstartがプロセスの誤ったPIDを追跡-再スポーンしない


11

私はもともとStackOverflowでこの質問をしました。その後、これはおそらくより良い場所であることに気づきました。

delay_jobプロセスを監視するためのbluepillセットアップがあります。(Ruby On Railsアプリケーション)

Ubuntu 12.10。を使用する

Ubuntuを使用してbluepillサービス自体を開始および監視していupstartます。私の初期設定は以下(/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

私ものexpect fork代わりに試しましたexpect daemon。また、expect...行を完全に削除しようとしました。

マシンが起動すると、bluepillは正常に起動します。

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

bluepillプロセスのPIDはここでは1154です。しかしupstart、間違ったPIDを追跡しているようです。存在しないPIDを追跡しています。

$ initctl status bluepill
bluepill start/running, process 990

sudobluepillプロセスを開始したプロセスのPIDを追跡していると思います。

これは、を使用してbluepillを強制的に強制終了した場合、bluepillプロセスが再生成されるのを防ぎkill -9ます。

さらに、誤ったPIDが追跡されているため、再起動/シャットダウンがハングするだけで、毎回マシンをハードリセットする必要があります。

ここで何が問題になりますか?

更新

この問題は、Ubuntu 14.04.2では今日(2015年5月3日)のままです。

問題は、sudoを使用しているためではありません。私はもうsudoを使用していません。私の更新されたupstart構成はこれです:

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

マシンが起動すると、プログラムは正常にロードされます。ただし、上記のように、upstartは引き続き間違ったPIDを追跡します。

コメントに記載されている回避策により、ハングの問題を解決できる場合があります。しかし、私はそれを試していません。


990のプロセスを調べてみましたか?ps aux | grep 990それを行う必要がpstree 990ありますが、より有益かもしれません。
オリ

PID 990のプロセスは存在しません。
アンジャン

2
はるかに良い状態に成り上がりを取り戻すために再起動する必要が同じくらい-この便利なツールを参照してください。github.com/ion1/workaround-upstart-snafu
andersonbd1

次のコマンドを使用すると、このツールを高速化できます。sudo tee / proc / sys / kernel / pid_max
andersonbd1

回答:


8

かなり遅れていますが、これが他のユーザーの助けになることを願っています。

upstart構成に不正なforkスタンザを指定すると、initstartが間違ったPIDを追跡する可能性があるupstartのバグが文書化されています:https : //bugs.launchpad.net/upstart/+bug/406397

何が起こるかというと、upstartはforkスタンザをチェックし、制御されているプログラムの「真の」PIDを選択する前にチェックするフォークプロセスの数を決定するということです。を指定するexpect forkexpect daemon、プログラムが十分な回数フォークしない場合、startハングします。一方、プロセスが何度もフォークする場合、initctl間違ったPIDを追跡します。理論的には、upstart cookbookのこのセクションに文書化する必要がありますが、この状況でわかるように、強制終了されるべきではないプロセスに関連付けられたPIDがあります。

これの意味はバグトラッカーのコメントで説明されていますが、ここで要約します:そのPIDに属するinitctlプロセスが停止すると、デーモンプロセスを停止できず、文書化されていない/違法な状態に陥り<service> start/killed, process <pid>ます)その後、PIDはシステムによって再利用のために解放されます。

あなたが発行する場合initctl stop <service>service <service> stopinitctlそのPIDにそれが表示され、次の時間を殺すでしょう。これは、この間違いを犯した後に再起動しない場合、どこかでそのPIDを使用する次のプロセスinitctlがデーモンではなくてもすぐに強制終了されることを意味します。単純なものからcat複雑なものffmpegまであり、日常的な操作の途中でソフトウェアパッケージがクラッシュした理由を理解するのは困難です。

したがって、問題はexpect、デーモンプロセスが実際に作成するフォークの数に誤ったオプションを指定したことです。彼らは、この問題に対処するアップライトのリライトがあると言いますが、アップスタート1.8(最新のUbuntu 13.04 / January 2014)の時点ではまだ問題が存在します。

expect daemonこの問題を使用し、最終的にはこの問題に遭遇したため、をお勧めしexpect forkます。

編集:ここではUbuntuのBASH互換スクリプトは(だウェイドフィッツパトリックによるオリジナルは Ubuntuのを使用するように変更sleep可能なプロセスIDのアドレス空間がなくなるまで、それが0に戻って始まり、「スタック」への道を働く時点で、スポーンプロセスという) PID。次に、PID initctlがハングアップしたときにプロセスが生成され、それをinitctl強制終了してリセットします。

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

この回答にはいくつかの有用で興味深い情報がありますが、@ Anjanが「expectデーモンの代わりにexpect forkでも試し
user12345 14

5

提供された例の場合:

$ initctl status bluepill
bluepill start/running, process 990

私の簡単な解決策は次のとおりです。

# 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

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

これが役立つことを願っています。何が起こっているかは、他の回答で説明されています。


素敵なスクリプト。これには1〜2分かかります。A rebootが望ましい場合があり、これも修正します。
ピーターイルフリッチ

0

Upstartユーザーレベルのジョブを実行している場合、またはsetuidスタンザを使用している場合を除き、ジョブはrootとして実行されています。

Upstartはすでにrootとして実行されているため、なぜexecスタンザでsudoを使用する必要があるのですか?

sudoまたはスタンザで使用するsuと、execここで説明するのと同じ問題が発生します。

通常、アイテム1または1と2の両方が発生します。

  1. upstartは誤ったPIDに従います
  2. プロセスを停止しようとするとupstartがハングする

もちろん、さらにexpectフォークの正しい数をスタンザに反映させる必要があります。

YMMV、しかし私にとって:

  • execスタンザでsudoまたはsuを使用して、正しい数のフォークを指定すると、通常、上記の状況1になります。
  • 指定したフォークの数が正しくない場合(sudo / suを使用しない場合exec)、上記の状況1および2が発生します。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.