daemontools のインストール
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 を立てた
・ サービスやログを書く際に実行ユーザを変更しているのにも関わらず、ログ出力用のディレクトリにそのユーザの権限が無い。