/etc/init.d/functions を読む
それらしい起動スクリプトを作りたくて /etc/init.d/functions を読んだので、メモを残しておきます。所々に書かれているコメント以外にも制約が多く、「まぁソース嫁や」と暗に要求してくれる漢気溢れるスクリプトでした。
当然内容は無保証ですので利用される場合はご注意ください。また、基本的に「メモの公開」でして興味ある部分しか調べてないのと、清書する気力が残っていないので結構ばらばらな文章となっています。ご容赦。
今回確認したのは CentOS5 です。
ファイル構造と用語 program 起動されるプログラム。正確には実行可能ファイルのパス文字列。 basename ここでは起動される daemon のプログラム名を差す様子。apache なら httpd。 pidfile /var/run/{basename}.pid で配置される。ここに起動された program の pid が入 る。 /var/lock/subsys/* program が動いていれば、program の basename と同名のファイルをここに touch することでロックをかける慣習の様子。でもロックファイル作る関数が functions には存在しない。えーw データ構造 /etc/sysconfig/init このファイルがないと functions 自身に書かれたデフォルト値を利用する。 BOOTUP color ブートアップする際に色を利用するか RES_COL 60 [ ok ] とかの表示をどこから始めるか 以下からSETCOLOR シリーズは echo を利用して何かやっているみたい エスケープシーケンスをしていることはわかるのだが。MOVE_TO_COL 以外は 色の設定。MOVE_TO_COL は名前からしてカーソルの移動か何かっぽいが、エスケープ シーケンス見てみないと判らない。 echo -e がエスケープシーケンスのための ものっぽい。 MOVE_TO_COL SETCOLOR_SUCCESS SETCOLOR_FAILURE STECOLOR_WARNING SETCOLOR_NORMAL LOGELEVEL 3 ブート時のログレベル。カーネルの。 syslog はこれでリセットされるって書いてある。 PROMPT no 以外をセットすると hotkey interactive startup が 有効になるらしい。何かは不明。 AUTOSWAP よくわからん。。 __sed_discard_ignored_files 関数 fstab_decode_str() checkpid() __umount_loop() __umount_loopback_loop() __pids_var_run Usage: __pids_var_run {base} {pidfile} return: 0 ... プロセスは生きている 1 ... プロセスは死んでるけれどpidfileが残っている 3 ... プロセスは死んでいる memo: 中身的には渡された引数をもとに pidfile のチェックをしている。読みづらいが /proc を見て、プロセスが生きているかどうかを判断している。 のだが、プロセスが生きているかど蚊の判断基準が pidfile に記載されている pid だけっぽく、basename を見ている気がしない。同じ pid が生きてると「生き ているとみなされる」ことがありそう。まぁ現実的にはあまりないのかな。 というかグローバル変数にチェックしたPIDを入れたりしてる。シェルだと仕方な いのかなぁ。 この関数見ると pidfile は複数行に対応していないことが判る。プロセスを複数 起動するプログラムの場合、一行に空白文字区切りで複数書かないといけない。 __pids_pidof() daemon() program を daemon として起動するための関数。--check とかのオプションがあるけ れど、本質的には、1.重複なくプロセスを起動する 2.起動したプロセスの pid を記録する 3.ユーザにわかりやすく起動の成功/失敗を伝える ためにある様 子。 意外と設定できることが多い。 Usage: daemon [+/-nicelevel] {program} options --check {base} # base とはプログラムの basename の模様 --user {user} --pidfile {pidfiile} --force これらのオプションは、例えば --user=hoge といった形式でも利用できる様子。 variables: gotbase プログラムの basename を取得したかどうかのフラグ 取得できていない場合、 ${1##*/} で取得する。 force 強制のフラグ nicelevel default 0. corelimit 実体は "ulimit -S -c ${DAEMON_COREFILE_LIMIT:-0}" 見てのとおりデフォルト 0 が設定されている。 pid 起動要求した program がすでに起動していればここにその pid が 入る。 __pids_var_run のところにも書いたがグローバル変数。 __pids_var_run でセットするという荒業をやっているみたい。 base 起動要求されたプログラムの basename。 user --user に指定された username が入る。 nice 環境変数 $NICELEVEL が設定されていればそれを適用させる。 なければ 0 にする。 bg 使われてるところが見当たりません。 pid_file --pidfiile を指定した場合に入るみたい。 memo: 基本的な流れとしては、要求された program の basename を取得して、 basenameから pidfile 名を取得して生きているかどうかを調べる。生きている 場合、--force であれば処理を続行し、でなければ終了する。生きていない場合 はもちろん続行。 で、ulimit で corefile のサイズ上限を設定したあと、nicelevel を設定。こ のあたりはオプショナルっぽい。 このあとに起動処理に入る。起動処理では --user で設定した user で起動す る。user の指定がなければそのまま起動(なので、通常 root のはず)。 で、この起動なのだが $* を実行することで起動している。つまり起動したいプ ログラムのパスを最後に持ってこないとエラーになるはず。 killproc() Usage: killproc [-p pidfile] [-d delay] {program} [-signal] 起動している program を落とすためにある。性格にはシグナルを送信するためにある 様子。書き方からしてオプションの指定の順番がシビアで、-p とか -d とかの Usage の順番に書かないとたぶん動かない。 -signal は program に与えるシグナルを指定する。kill コマンドの引数ママになっ ているので任意で指定できる。よく判らない挙動だけれど、-signal を指定していな い場合は先ず TERM を送り、sleep 1 の後 program が停止していなければ delay 秒 sleep した後に、再度チェック、それでも生きていれば -KILL して usleep 100000 (=0.1秒スリープ)した後に生存確認を行い、生きていると failure、死んでれば successとする。一方、-signal が指定されていると、シグナルを投げた後まったく スリープせずに成否判定を行う、というか kill コマンドが成功していれば成功扱い になる。たぶん停止は TERM シグナルですべきだよね、他のシグナル指定されたら停 止要求かどうか判らないからシグナル投げられたかどうかだけ判定するよ、というこ とだと思う。 戻り値: 0 停止成功またはシグナル成功 7 program は起動していない pidfileofproc() pidofproc() status() Usage: status [-p pidfile] {program} 詳しくは見ていないけれど、与えられた program の basename を調べて pidfile を探索し、program が動作しているかどうかなどのステータスを返す。 例えば、 status /usr/sbin/httpd とか status httpd とかってできる。 echo_success() echo_failure() echo_passed() echo_warning() update_boot_stage() success() program 起動成功時に表示される [ OK ] を出す関数。 source /etc/init.d/functions してから success って打つと面白い(俺は)。 failure() success の失敗版。 passed() success のところに PASSED って表示される warning() success のところに WARNING って(ry 画面が WARNING で埋め尽くされることを期待して while [ 0 ]; do warning; done とかやったけれど期待通りにならなかった。echo 入れればいいのか。 action() 面白げなのだが深入りはしない(ぉ strstr() confirm() get_numeric_dev() resolve_dm_name() is_ignored_file()