2015年6月28日日曜日

指定したユーザーで実行したプログラム(su - user -c program)のPIDファイルを作成する


もっとカッコイイ方法はあると思いますが、とりあえずこんな感じで...
# ./sleep.sh /var/run/sleep.pid

sleep.sh


まず、指定ユーザー(sleep)がプログラム(sleep 60)を実行した後に
"/tmp"下にPIDファイルを書き出しています。
(パーミッションの問題で直接"/var/run/"下に書き出せない)

そして、"root"で"/var/run/"下にPIDファイルを移動しています。

ポイントは、プロセスIDを取得する変数"$!"
をバックスラッシュでエスケープ(\$!)しているところでしょうか?

上記コマンド実行後、下記のように"sleep"ユーザーで実行されているのがわかり
# ps aux | grep sleep
sleep     2822  0.0  0.0 107888   620 ?        S    23:11   0:00 sleep 60
root      2825  0.0  0.0 110400   860 pts/0    S+   23:11   0:00 grep sleep
プロセスIDも問題なく書きだされていることが確認できます。
# cat /var/run/sleep.pid 
2822

Monitの状態("unmonitor"など)をリセットする


Monitで下記のように再起動の上限までいってしまい"unmonitor"の状態になってしまい、
それ以降、プロセスが監視されない状態になってしまったときの対策です。
[JST Jun 28 18:08:14] error    : 'sleep' service restarted 5 times within 5 cycles(s) - unmonitor
まあ普通はMonitのコマンドで実施すると思いますが、
# monit status
monit: error connecting to the monit daemon
のようなエラーが出てしまうことがあります。これはMonitのWebのインターフェースが
利用できない状態になってるためのエラーですが、基本的に使ってないので、
今さら有効にするのもどうかなー、と思い、別の方法を探してみました。

ってことで下記を実行することでリセットできます。
# service monit stop
# rm -f /root/.monit.state
# service monit start
※ "/root/.monit.state"はMonitの状態を記録するファイル(デフォルト)です。

すると、再度プロセスの監視が始まり、プロセスが落ちても起動してくれるようになります。

Monitでプロセスを自動復旧させる


よくある話ですが、せっかくなのでInitスクリプトから作ってみました。

まずは対象のプログラムですが、下記のようにバックグラウンドで
スリープするだけのものを用意しました。

/tmp/sleep.sh

スクリプト内でプロセスID($!)を書き出しているところがポイントです。

次に上記のプログラムを起動するInitスクリプトです。
下記のように、それっぽく用意しました。
プログラム起動時にPIDファイルを引数として渡しています。

/etc/init.d/sleep

次の仕様に準じるところまでは作りこんでいません...
Linux Standard Base Core Specification, Generic Part
Chapter 22. System Initialization
22.2. Init Script Actions

最後にMonitの設定ファイルです。上述のPIDファイルを指定しています。

/etc/monit.d/sleep



準備ができたらMonitを再起動します。
# service monit restart
Shutting down monit:                                       [  OK  ]
Starting monit:                                            [  OK  ]
スリープのプロセスは、当然、指定の時間がくると終了するので、
下記のようにログから、Monitがそれを検知して起動していることがわかります。
# tail -f /var/log/monit
...
[JST Jun 28 16:27:48] error    : 'sleep' process is not running
[JST Jun 28 16:27:48] info     : 'sleep' trying to restart
[JST Jun 28 16:27:48] info     : 'sleep' start: /etc/init.d/sleep
[JST Jun 28 16:28:49] info     : 'sleep' process is running with pid 31169