読者です 読者をやめる 読者になる 読者になる

Upstartでプロセスが停止しない?

Upstartを使っていると停止させた時にプロセスが死なないことがあることに気づいた。
それは特定の条件、たぶん2回以上プロセスがforkされると、孫プロセスが死なないというものだ。
Linuxの正常な動作っぽいが。

たとえば、

start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
   su - vagrant -c '/bin/sh /usr/local/bin/hoge >> /var/log/app/hoge 2>&1'
end script

とやった場合に起こる。
プロセスツリーをみると以下のようになっている。

root     14648  0.0  0.0  48484  1452 ?        S    22:36   0:00  \_ su - vagrant -c /bin/sh /usr/local/bin/hoge >> /var/log/app/hoge.log 2>&1
vagrant  14649  0.0  0.1 108176  1636 ?        Ss   22:36   0:00      \_ -bash -c /bin/sh /usr/local/bin/hoge >> /var/log/app/hoge.log 2>&1
vagrant  14718  0.0  0.0 106064  1308 ?        S    22:36   0:00          \_ /bin/sh /usr/local/bin/hoge

で、いろいろ調べたが、
Upstartの expect daemon か expect fork を使えば回避出来そうなことが書かれていた。
しかしやってみたが解決しない…。

しょうがないので、いろいろ試した結果以下の様な書き方なら大丈夫だった。

start on runlevel [2345]
stop on runlevel [!2345]
respawn
script
   su - vagrant -c '/bin/sh /usr/local/bin/hoge' 2>&1 | su - vagrant -c 'tee -a /var/log/app/hoge.log'
end script

プロセスツリーをみると以下のようになっていた。

root     12550  0.0  0.0  48484  1452 ?        S    22:32   0:00  \_ su - vagrant -c /bin/sh /usr/local/bin/hoge
vagrant  12552  0.3  0.0 106064  1308 ?        Ss   22:32   0:00  |   \_ /bin/sh /usr/local/bin/hoge
root     12551  0.0  0.0  48484  1456 ?        S    22:32   0:00  \_ su - vagrant -c tee -a /var/log/app/hoge.log
vagrant  12553  0.3  0.0 101020   732 ?        Ss   22:32   0:00      \_ tee -a /var/log/app/hoge.log

これならそれぞれ一回しかforkしていないから大丈夫みたいだ。


また他のやり方としては、
http://stackoverflow.com/questions/12200217/can-upstart-expect-respawn-be-used-on-processes-that-fork-more-than-twice
にあるように、
pre-start scriptとpost-stop scriptを使って解決するやり方もある。
ugly hackなのであんまりやりたくないが…背に腹は代えられない。

ちなみに、
Upstartの代替として期待されているのが、Systemdだが、 http://ja.wikipedia.org/wiki/Systemd
Systemdは「PIDではなく cgroups を使ってサービスプロセス群を監視する。つまり、デーモンが2回forkしてもsystemdから逃れることはできない。」
とあるので、Systemdがきたら上記の問題は解決しそうだ。