新しいサービスをログ記録なしで走らせる手順は?
たとえばサービス名 finger を新しく走らせるとする。svscan は すでに走っていて、/service 以下のディレクトリを見張っていると する:
bash-2.03# ls -l /service/finger/supervise/ total 1 prw------- 1 root system 0 Apr 26 13:54 control -rw------- 1 root system 0 Apr 26 13:42 lock prw------- 1 root system 0 Apr 26 13:42 ok -rw-r--r-- 1 root system 18 Apr 26 13:54 status
#!/bin/sh exec env - \ /usr/local/bin/tcpserver -u 65534 -g 65534 0 79 \ /usr/local/etc/in.fingerd注意: ここではこのシェルスクリプトのプロセス 自体がデーモンプロセスに override されるよう、 デーモンの起動には 必ず exec を使うこと。またデーモンはフォアグラウンドで 走りつづけなければならない。 しかしデーモンによっては (というか、現在使われている デーモンのほとんどが)、いきなり自分自身を fork して バックグラウンドに移行してしまうようにできている。このような デーモンには、 fghack を使ってみよう。
$ svc -d /service/fingerを実行すれば tcpserver は止まる (down)。ここで、
$ svc -u /service/fingerを実行すれば、tcpserver はふたたび走りだす (up)。
新しいサービスをログ記録つきで走らせる手順は?
サービス qmail を新しくログつきで走らせるとしよう。 /service/qmail というディレクトリを使うとする。ログを 残すためには、このディレクトリの sticky bit が立っていなければ ならないのだが、いきなり
$ mkdir /service/qmail (×)などとするのはマズい。svscan は新しくディレクトリを つくる瞬間にしか sticky ビットを見てくれない からだ。 このときにまだ sticky ビットが立っていないと、あとで /service/qmail/log ディレクトリを作っても、svscan は 何もしない (svscan を再起動すれば話は別だけど)。 なので、sticky ビットを立てるまでは /service 以下に qmail ディレクトリを置かないほうが得策だ。
svscan が /service 以下を検査するのは 5秒に 1回なので、
$ mkdir /service/qmail; chmod +t /service/qmailとシェルで入力して一瞬でやってしまうという手もある。 しかしこれも、完全にうまくいくとは保証されない。 よりまともな方法としては、次の 2つがある。
$ mv /service/.qmail /service/qmailを実行すればいい。
ここでは後者の方法でやってみよう:
$ cd /service $ mkdir .qmail $ mkdir .qmail/log $ chmod +t .qmail $ mv .qmail qmailsvscan が sticky bit を検知し、
$ svc -d /service/qmail $ svc -d /service/qmail/logを実行し、どちらのデーモンも開始しないようにしておく。 この例でもわかるように、デーモン用の supervise と ログ用の supervise は別々に制御しなければならない。
/service/qmail/run:
#!/bin/sh exec env - PATH="/var/qmail/bin:/usr/local/bin:/usr/bin:/bin" \ qmail-start ./Mailbox
/service/qmail/log/run: (なお、この例は daemontools HOW-TO の startup script の例 から引用させていただきました)
#!/bin/sh exec \ setuidgid qmaill \ multilog t ./main \ -'* status: *' \ -'* starting delivery *' \ -'* delivery * success*' \ -'* delivery * failure*' \ -'* new msg *' \ -'* info msg *' \ -'* end msg *' \ -'* bounce msg *' \ -'* delivery * deferral: Sorry,_I_couldn't_find_any_host_by_that_name*' \ -'* delivery * deferral: Sorry,_I_wasn't_able_to_establish_an_SMTP_*' \ ./alert \ '-*' '+* status: *' =status
multilog は daemontools に含まれているログ記録用デーモンだ。 上のスクリプトでは、setuidgid を使ってこのデーモンを qmaill というユーザで走らせている。multilog はログファイルの 行頭にタイムスタンプを付けくわえたり、必要な行だけをパターンマッチで 記録する (あるいは記録しない) ことが可能だ。 multilog の詳しい使い方については multilog のマニュアル を参照のこと。
$ chown qmaill.nofiles /service/qmail/logを実行しよう。
$ svc -u /service/qmail/log $ svc -u /service/qmailを実行する。これで qmail デーモンが走り出し、 /service/qmail/log/main/current にログが現れるはずだ。 multilog で t オプションを指定すると、ログの各行の先頭に TAI64N 形式のタイムスタンプがつく。これの見方は ログの変なタイムスタンプはなに? の項を参照。
このログの変なタイムスタンプはなに?
ログの各行頭に現れる @4000000039c97bf53afbe444 などという 文字列はタイムスタンプだよ。 これは TAI64N 形式というもので、うるう秒を考慮した 時間の表現形式になっている。TAI形式については http://tehanu.hpcl.titech.ac.jp/time/utctai.html に 説明がある。
TAI64N 形式をふつうの時刻として見るためには、daemontools に ついてくる tai64nlocal コマンドを使おう。これは標準入力から受けとったテキストの行頭の TAI64N 形式 タイムスタンプを、ローカル時刻で人間が読みやすい形式にして出力して くれるよ。以下のようにして使う:
$ tai64nlocal < /service/qmail/log/mail/current
デーモンを再起動/kill -HUP したい
svc を使おう。
$ svc -t /service/サービス名とすれば、そのサービスを行っているデーモンに TERM シグナルが 送られる。その後 supervise はすぐにこれを起動しなおすので、 結果として再起動したことになる。HUP シグナルを送るには、
$ svc -h /service/サービス名を実行する。svc にはまだほかにもいろいろな オプションがある。 http://www.emaillab.org/djb/tools/daemontools/svc.html を 参照のこと。
サービスを止めたい/再開したい
これも svc を使う。
$ svc -d /service/サービス名 (停止, down) $ svc -u /service/サービス名 (開始, up)
しかし、システム起動時には、svscan によって起動された supervise はデフォルトでデーモンを up してしまう。 これを防ぐためには、ディレクトリ /service/サービス名 に down という ファイルをつくっておく。
$ touch /service/サービス名/downとすればよい。中身はなくてもファイルの存在だけがスイッチになる。 supervise はその起動時にこのファイルを発見すると、 デフォルトでサービスを down のままにしておく。 supervise が down ファイルの有無を 検査するのは、supervise の起動時だけなので注意すること。 いったん supervise が起動してしまったら、デーモンの 停止・再開には svc を使おう。
サービスを完全に廃止したいんだけど
サービスを完全に廃止して supervise を止めるには、 まず /service/サービス名 というディレクトリを 最初に svscan の目が届かないところに置く必要がある。そうしないと supervise を止めてもすぐにまた svscan が supervise を 走らせてしまうからだ。といっても、サービス用のディレクトリを いきなり rm -rf などで消してしまうのは危険なので、 以下のようにする。たとえば /service/qmail を廃止することを 考えてみよう:
$ mv /service/qmail /service/.qmail/service ディレクトリから どこか他のディレクトリにリンクをはっているなら、 それを消すだけでよい。
$ svc -x /service/.qmail/log $ svc -x /service/.qmail-x オプションは、supervise に 「デーモンが終了したらきみも一緒に終了せよ」と指示する。 これでデーモン用の supervise とログ用の supervise に それぞれ終了が宣告された。ディレクトリの名前は変わっているが、 svc はそのまま通用する (なぜならこのプログラムは、ただ 与えられたディレクトリ名に「/supervise」という文字列を 追加し、そこの名前つきパイプを操作するだけだからだ)。 注意: デーモン用 supervise とログ用 supervise は それぞれ別個に指示してやらねばならない。
$ svc -d /service/.qmail/log $ svc -d /service/.qmailこれでデーモンは両方止まり、supervise も終了した。 svstat /service/.qmail を実行してみよう。 「supervise not running」と表示されるはずである。