Gentoo Linux (OpenRC) でinitスクリプトを書くには [基本編]
何かの機能を提供するシステムを構成する時、OSのパッケージ管理システムに必要なサービスが含まれていなくて、手動でインストールしないといけない場合がある。
その場合、困るのが「再起動時の自動起動」。手動でやってると、メンテナンスで再起動なんかした時に、つい忘れてしまうんだよね。
ここは精神の安定とシステムの平和を守るためにも、自動にしておきたいところ。
Gentoo (正確にはOpenRCをinitシステムとして使っている場合のみだけど ) では、initスクリプト (起動スクリプト) を用意してやることで、サービスや開始や停止、自動起動の登録などの制御ができるようになる。
これは、サービス (デーモン) を自作するときにも役に立つ。例えばWebアプリを稼働させる場合、キャッシュサーバ、Webサーバ、アプリサーバ、DBサーバなどが相互に依存して絡み合いながら動作するので、適切な起動順で各サービスを自動起動させるのは、運用上、結構重要だ。
というわけで、今回はOpenRCにおけるinitスクリプトの基本をメモメモ。
サービスの基本
ここらへんは簡単に。hogehoge
がサービス名ね。
- 起動
/etc/init.d/hogehoge start
- 停止
/etc/init.d/hogehoge stop
- 再起動
/etc/init.d/hogehoge restart
- 説明の表示
/etc/init.d/hogehoge describe
一般的なサービスの起動と終了の方法に同じです。
これらのコマンドを指定して起動すると、対応するスクリプトコードが実行されることになる。
全体のレイアウトと保存先
まずはinitスクリプトの全体像を見てみる。
#! /sbin/runscript
depend() {
依存関係の設定に必要な処理
}
start() {
開始時に必要な処理
startコマンドで実行される
}
stop() {
停止時に必要な処理
stopコマンドで実行される
}
見ての通り、サービスの開始と停止、依存関係を設定している。
この内容のファイルを作り、編集して/etc/init.d
に保存する。こんなかんじ。
# touch /etc/init.d/hogehoge
# nano /etc/init.d/hogehoge
# chmod 755 /etc/init.d/hogehoge
実行属性を忘れないこと。hogehoge
はサービス名で、自動起動や依存関係などの設定をするときに使う。
文法
とっても簡単。
- 基本はBシェル系のシェルスクリプト。
- なのでコメント、変数、関数などの形式も同様。
- initスクリプトの中だけで使える特殊なコマンドがある。
つまり、シェルスクリプトを書いたことがあれば、まったく問題なくinitスクリプトを書けるってことだ。
依存関係の設定
サービス間の依存関係を設定しておくことで、サービスの起動順序を制御できる。
依存関係は、depend()
関数の中に書く。
depend() {
need net
use logger
}
ここでneed
とかuse
ってのがでてきた。
これは、依存性を設定するコマンド。
use service |
絶対に必要なわけではないけど、あるとより多くの機能が使えるようになるようなサービスが有る場合、そのサービス名を指定する。ロガーなんかが該当する。具体的なサービスでもいいし、仮想サービスでもいい。 |
---|---|
need service |
絶対に必要なサービスの名前。ないと起動できないもの。具体的なサービスでもいいし、仮想サービスでもいい。 |
before service |
同じinitレベルでservice が自動起動する場合に限り、service より先に起動するようにする。 |
after service |
同じinitレベルでservice が自動起動する場合に限り、service より後に起動するようにする。before の反対。 |
provide service |
仮想サービスを提供する。 |
config file |
file が更新された場合、依存関係に基づく起動順序を再計算する。 |
仮想サービス
ここで、仮想サービスについて簡単にメモメモ。
仮想サービスは、ある機能を提供するサービスが複数ある時に、そのどれでもOKな場合に利用する機能。例えば、syslog-ng、metalog、sysklogdなどは、同じ仮想サービスlogger
を提供する。
有名どころとしては、logger
、cron
、net
など。
使える一覧は、こんなかんじで取得するといいかも。
# cd /etc/init.d
# grep "^[[:space:]]*provide " *
開始
サービスを開始する時のコマンドは、start()
関数の中に書く。
start() {
ebegin "Starting Apache"
apachectl start
eend $?
}
ここではApache HTTP Serverを例にしている*1。
ehogehoge
形式のコマンドは、initスクリプトの中だけで使えるコマンド。とりあえず基本編では、次の5つをピックアップ。
einfo [message] |
message を表示する。情報提供用。この時、先頭には緑色の「* 」が付く。 |
---|---|
ewarn [message] |
message を表示する。警告表示用。この時、先頭には黄色の「* 」が付く。 |
eerror [message] |
message を表示する。エラー表示用。この時、先頭には赤色の「* 」が付く。 |
ebegin [message] |
message を表示する。起動メッセージ用。この時、先頭には緑色の「* 」が付き、末尾には「... 」が付く。 |
eend retval [message] |
retval が0でなければ、エラーメッセージとしてmessage を表示する (eerror を使う)。メッセージ行の最後には、「[!!] 」が付いて、エラーの発生を知らせる。 |
[hogehoge]
は、「hogehoge
は省略できる」って意味だ。これらのコマンドを使って、ユーザにメッセージを表示する。
停止
サービスを停止する時のコマンドは、stop()
関数の中に書く。
start() {
ebegin "Stopping Apache"
apachectl stop
eend $?
}
基本はstart()
と同様。
再起動
再起動は、ちょっと特別に扱わないといけない。
基本的には、stop()
→start()
が自動で実行されるが、特別な処理を行いたい場合がある。その場合は、次のようにして「再起動」であることを判断する。
start() {
if [ "${RC_CMD}" = "restart" ]; then
ebegin "Restarting Apache"
apachectl graceful
else
ebegin "Starting Apache"
apachectl start
fi
eend $?
}
stop() {
if [ "${RC_CMD}" != "restart" ]; then
ebegin "Stopping Apache"
apachectl stop
eend $?
fi
}
つまり、RC_CMD
変数に「指定されたコマンド」が入っているので、それを見るってわけだ。
環境変数
このように、OpenRCのinitスクリプトの中では設定済みの変数がいくつかある。幾つかピックアップ。
RC_SVCNAME |
このサービスの名前。具体的には、/etc/init.d/hogehoge というinitスクリプトであれば、hogehoge がサービス名になる。 |
---|---|
RC_CMD |
initスクリプトを起動する際に指定されたコマンド。例えば、start 、stop 、restart など。 |
RC_UNAME |
uname -s と同じ。Linuxなら、Linux が入る。 |
以上、initスクリプト基本編でした。
次回に続く。