daemontools のインストール

最終更新日時:2017-02-14 14:11:07
daemontools

daemontools-0.76 の例です。
まず、daemontools を daemontools の公式サイト からダウンロードします。
次に 以下のように /package ディレクトリを作成します。

 # mkdir -p /package
 # chmod 1755 /package
 # cd /package


作成したディレクトリ上でアーカイブを展開し、コンパイル・インストールします。
ただし、glibc のバージョンによっては src/error.h を #include と書き換える必要があります。

 # gzip -dc /path/to/anywhere/daemontools-0.76.tar.gz | tar xvf -
 # cd admin/daemontools-0.76
 # package/install


package/installすると、/etc/inittab に変更が加えられ、svscanboot がブート時に実行されるように設定されます。
また、この svscanboot から実行される svscan が監視するディレクトリ(/service)が作成されます。

なお、package/installの時点でerrno関係でエラーが出ることがあります。
その際には、概ねsrc/error.hを以下のように修正することで対応可能です。

 /*extern int errno;*/ ←削除
 #include <errno.h>    ←追加


RedHat EL6(CentOS6) での問題


RHEL6 では、起動時の仕掛けに変更があったようで、inittab は使われなくなりました。
daemontools は inittab で起動することを前提にインストール処理が行われるので、このままでは自動起動はされません。
従って、以下の修正を行う必要があります。

まずは、daemontools がインストール処理で追加した、/etc/inittab の以下の記載を削除(コメントアウト)します。

 SV:123456:respawn:/command/svscanboot


次に、/etc/init/svscan.conf を以下の内容で作成します。

 start on runlevel [12345]
 respawn
 exec /command/svscanboot


これで自動起動されるはずですので、OS を再起動してみましょう。
OS 再起動はしたくない場合には、以下を実行で daemontools を起動することが出来ます。

 # initctl reload-configuration
 # initctl start svscan



サービスの登録


/service の下にディレクトリを作成することによって、daemontools の制御下に置くサービスを登録することができます。
サービスのディレクトリ内には必ず run という名前のスクリプトファイルが必要となり、このスクリプトで起動したいコマンドを exec します。
ただし、自分自身を fork してバックグラウンドで動くようなコマンドは daemontools では制御できません。
svscan から自動的に実行される supervise がこの run スクリプトを自動的に実行します。
自動的に実行されるので、/service の下にディレクトリを作成する時には、既に準備が全て整っている必要があります。
従って、/service でない他のディレクトリにサービス用のディレクトリを作成しておき、最後に /service へシンボリックリンクを張るのが良いでしょう。
また、サービスだけでなく、ログも daemontools の制御下に置くことができます。
サービスのログも制御したい場合には、そのサービスのディレクトリに sticky bit を立てます。
そして、サービスのディレクトリ内に log という名前のディレクトリを作成し、log の下にログ用の run スクリプトを作成します。
この run スクリプトで実際にログを出力する処理を書きます。

例:test_service というサービスを追加


まず、/service とは別の場所に test_service 用のディレクトリを作成します。
ログの制御も行うのであれば、sticky bit を立てておき、さらに log ディレクトリも作成しておきます。

 # mkdir /var/test_service
 # mkdir /var/test_service/log
 # chmod 1775 /var/test_service


run スクリプト (/var/test_service/run) を作成します。
ログも制御する場合、実行するサービスの出力が標準出力ではなく、エラー出力に出力される場合には、標準出力にリダイレクトしてやる必要があります。
run スクリプトは、例えば以下のような感じになります。

 #!/bin/sh
 exec 2>&1
 exec /usr/local/sbin/test_service


ログ用の run スクリプト (/var/test_service/log/run) を同様に作成します。
特に決まっているわけではないのですが、daemontools に含まれている multilog を使うのが通常のようですので、特に必要のない限り multilog を使うのが良いでしょう。
ログ用の run スクリプトは以下のような感じになります。

 #!/bin/sh
 exec multilog t ./main


上記の例では main というディレクトリの下にログを出力することになります。
これで準備が全て整ったので、/service にリンクを張ります。

 # ln -s /var/test_service /service 


数秒後、サービスが自動的に起動されていると思います。
サービスがうまく実行されていない場合(永久に起動を繰り返している)や、ログが出力されない場合には以下のようなことが考えられます。

・ 単に run スクリプトが間違っている
・ run で exec するコマンドがバックグラウンドで動くタイプ
・ run で & を付けて exec している
・ サービスのディレクトリ名が "." で始まる名前にしている
・ サービスのディレクトリに sticky bit が立っていない。もしくは、サービスを開始してしまってから sticky bit を立てた
・ サービスやログを書く際に実行ユーザを変更しているのにも関わらず、ログ出力用のディレクトリにそのユーザの権限が無い。

お問い合わせは 掲示板 にて。