(私家版 daemontools FAQ) 2. 実際の運用に関する質問

back


新しいサービスをログ記録なしで走らせる手順は?

たとえばサービス名 finger を新しく走らせるとする。svscan は すでに走っていて、/service 以下のディレクトリを見張っていると する:

  1. mkdir /service/finger として、まずサービス用の ディレクトリを作る。すぐに svscan がこれを検知して supervise を立ち上げ、/service/finger/supervise ディレクトリが作られるはずだ。このディレクトリを ls してみると、次のようになっている:
    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
    
  2. svc -d /service/finger を実行し、 finger デーモンを開始しないよう、 supervise に通知しておく。 run スクリプトを編集するときはこうしておくこと。
  3. デーモン起動用のスクリプト run をそのディレクトリ内に作り、 実行可能にしておく。たとえばこれは次のようなものだ。 これは ucspi-tcp パッケージ に含まれている tcpserver を使って、uid=nobody(65534), gid=nobody(65534) で tcp の 79番ポートをつかって GNU finger サービスを行うデーモンである:
       #!/bin/sh
       exec env - \
               /usr/local/bin/tcpserver -u 65534 -g 65534 0 79 \
               /usr/local/etc/in.fingerd
           
    注意: ここではこのシェルスクリプトのプロセス 自体がデーモンプロセスに override されるよう、 デーモンの起動には 必ず exec を使うこと。またデーモンはフォアグラウンドで 走りつづけなければならない。 しかしデーモンによっては (というか、現在使われている デーモンのほとんどが)、いきなり自分自身を fork して バックグラウンドに移行してしまうようにできている。このような デーモンには、 fghack を使ってみよう。
  4. svc -u /service/finger を実行する。 もうこれでサービスは開始されている。 finger してみよう。ps してみると、たしかに tcpserver が走っているのが わかる。svstat /service/finger とやると、現在の 状態が表示されるよ。
  5. このサービスを止めたり再開したりしてみよう。
           $ 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つがある。

ここでは後者の方法でやってみよう:

  1. まず、つぎのように実行する:
           $ cd /service
           $ mkdir .qmail
           $ mkdir .qmail/log
           $ chmod +t .qmail
           $ mv .qmail qmail
           
    svscan が sticky bit を検知し、
    /service/qmail/supervise
    /service/qmail/log/supervise という 2つのディレクトリが できるはずだ。
  2. つぎに、
           $ svc -d /service/qmail
           $ svc -d /service/qmail/log
           
    を実行し、どちらのデーモンも開始しないようにしておく。 この例でもわかるように、デーモン用の supervise と ログ用の supervise は別々に制御しなければならない。
  3. run スクリプトを書く。qmail デーモン用とログ用の 2つが必要だ。

    /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 のマニュアル を参照のこと。

  4. つぎに、ログが正しく残せるように /service/qmail/log ディレクトリの所有者を 正しく設定しよう。上のスクリプトでは、multilog は qmaill というユーザ権限で走ることになっている。multilog は /service/qmail/log 以下にログを残すから、 このディレクトリは qmaill ユーザが変更できるように なっていなければならない。
           $ chown qmaill.nofiles /service/qmail/log
           
    を実行しよう。
  5. これで準備ができた。あとは
           $ 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 を廃止することを 考えてみよう:

  1. まず、mv などでディレクトリ名を「.」で始まるものに 変更する。たとえば:
           $ mv /service/qmail /service/.qmail
           
    /service ディレクトリから どこか他のディレクトリにリンクをはっているなら、 それを消すだけでよい。
  2. 以下のように実行する:
           $ svc -x /service/.qmail/log
           $ svc -x /service/.qmail
           
    -x オプションは、supervise に 「デーモンが終了したらきみも一緒に終了せよ」と指示する。 これでデーモン用の supervise とログ用の supervise に それぞれ終了が宣告された。ディレクトリの名前は変わっているが、 svc はそのまま通用する (なぜならこのプログラムは、ただ 与えられたディレクトリ名に「/supervise」という文字列を 追加し、そこの名前つきパイプを操作するだけだからだ)。 注意: デーモン用 supervise とログ用 supervise は それぞれ別個に指示してやらねばならない。
  3. さて、上のように実行しただけでは、まだデーモン自体は 走りつづけているので、それが終了するまでは supervise も 終われない。そこで以下を実行する:
           $ svc -d /service/.qmail/log
           $ svc -d /service/.qmail
           
    これでデーモンは両方止まり、supervise も終了した。 svstat /service/.qmail を実行してみよう。 「supervise not running」と表示されるはずである。
  4. あとはこのディレクトリを rm -rf するなり、好きに 始末してほしい。

Last modified: Wed Sep 26 18:24:52 2001
Yusuke Shinyama