c/fe

http://d.hatena.ne.jp/uzulla から移行しました。

デーモンの起動 ……と終了

http://d.hatena.ne.jp/milk1000cc/20080312/1205275645
/etc/rc.d/rc.localに色々書いてデーモンを起動させておくのは定番です。

できればこのコマンドの標準出力をどっかに繋いでおいた方がいいのではないかと
たとえば >> /tmp/monglog 2>&1 ってお尻に付けて。

それくらいで大丈夫かと思います。


後、rootで実行されちゃうのはいいのかな?とか位?*1

あれ?sysvinitは?って思った人挙手 ノシ

そう、本当はデーモンを起動する由緒正しい方法が有ります。

でもさー、実際、正しくsysvinitに従ってinitscript書いても(後述します)、いまどきランレベルなんて3とか5で固定で、initコマンドなんて使ったことないでしょ?気付かずに0とか6とか、緊急時に1とか使ってるだけで…。

じゃあまったく問題はないのか?

もしかすると、何も考えずにシステムのシャットダウンをすると、問題が発生する可能性が有ります。

具体的には?

デーモンプロセスが起動したままshutdown -h nowを叩いたらどうなるでしょうか?


SystemがHaltする前にはまずsysvinitの仕組みで各デーモンの終了コマンドが呼ばれます。
よく起動時や終了時に

Starting sshd:[ OK ]

とかずらずら出力されますけど、アレです。
裏では

/etc/init.d/hogehoge stop
(またはservice hogehoge stop 相当)

と順番に(後述)実行されてます


で、sysvinitに登録されたプログラムが順番に終了された「後」に、残った全てのプロセスTERMのシグナルが飛び、次にKILLのシグナルが飛び、sysvinitで記載されていないプログラムも無事終了します*2


そう、最後には全部のプログラムは終了される、これは間違いない


でも、もしsysvinitでMysqlが起動されている場合、DBとかが先に終了しちゃうかもしれないんですよね(最初っから入ってるMysqlとかはそうでしょ?)。
コレを気持ち悪いとか、どうかなーとかおもうかおもわないかだと思います。


DB > Rails
って起動したら
Rails > DB
って終了したほうがいいと思いません?
実際RailsでDB操作中にDBが終了したら問題が発生するかも。


railsならDBに接続することが多いと思われるので、DBより前に終了してあげたほうがいいとおもいません?うっかりなにかやってたら面倒な事になりそうですよ?長いクエリが走ってるとか。


後はApacheをフロントに使ってるなら、まあ一応Apacheを先に落としたいですよね。
(まあ一瞬の遅かれ早かれなんだけれども)


そういう要望の為にsysvinitの仕組みで、終了する順番(起動時には起動する順番)がきちんと設定出来るようになっているのです。

終了の順番以外にも

通常どのサーバーも規定の操作で終了することを要求します、Apacheならapachectl stopとか。
実際シグナル送っての終了も(kill hogehogeとか、フォアグラウンドのプロセスをCtrl-Cで終了)、大抵のデーモンでは正しい操作の筈なんで問題はないはずですけどね。
できればちゃんとしたほうがいいことは間違いない。


後は終了処理とかしこめます、テンポラリファイル消すとかね。

じゃあどうやるの?

chkconfigとかinitscriptでググれ、

ググれ厨UZEEEEE!

init.dに入れるinitscriptスクリプト*3を作り、手またはchkconfigコマンドで登録してあげることで実現出来ます。
chkconfigコマンドがない場合には、手で/etc/rc.d/rc3.d等に入れてあげる必要がありますが、ここでは割愛。

じゃあ、initscriptはどう書くの?

これって結構みんなバラバラだと思うんですけど、dovecotがみじかかったんで、それをベースにhogehogeってプログラムを書いてみた、適当に置換とかしてみて。

#!/bin/bash
#
#       /etc/rc.d/init.d/hogehoge
#
# Starts the hogehoge daemon
#
# chkconfig: 35 98 02
#
# description: hogehoge program
# processname: hogehoge
# Source function library.
. /etc/init.d/functions

#この辺りで色々チェックとかやって
test -x /path/to/hogehoge || exit 0
test -x /path/to/hogehoge.conf || exit 0

RETVAL=0
#画面に表示する事書いちゃって
prog="Super Ultra Monster hogehoge server."

start() {
        echo -n $"Starting $prog: "
        #↓この行でプログラム起動させて
        daemon /path/to/hogehoge
        RETVAL=$?
        #↓起動できたらロックファイルをtouch(作成)して
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/hogehoge
        echo
}

stop() {
        echo -n $"Stopping $prog: "
        #停止して
        killproc /usr/sbin/hogehoge
        RETVAL=$?
        #ちゃんと終了できたらロックファイルを削除して
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/hogehoge
        echo
}

#
#       See how we were called.
#
case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  reload|restart)
        stop
        start
        RETVAL=$?
        ;;
  condrestart)
        if [ -f /var/lock/subsys/hogehoge ]; then
            stop
            start
        fi
        ;;
  status)
        status /path/to/hogehoge
        RETVAL=$?
        ;;
  *)
        echo $"Usage: $0 {condrestart|start|stop|restart|reload|status}"
        exit 1
esac

exit $RETVAL

詳細は解説しませんが、単純なので何やってるのかは一目瞭然だと思います。


まあ、Bashスクリプトなんですけど、最低startとstopって引数で望む動作(開始と終了)すればなんだっていい(chkconfigはつかえなくなるけど)。


daemonやstatus、killprocってなによ?という人は/etc/rc.d/init.d/functionを参照する。


作った後、
/etc/init.d/hogehoge start
とかで正しく動作する事を確認して、次へ進む。

書いたけど。で、どう登録するの?

chkconfig --add hogehoge
で登録されます。
chkconfig --del hogehoge
で削除できます。
詳しくはchkconfigを引数無しで起動してみる。
またはmanを読む。

initscriptの

# chkconfig: 35 98 02

って部分を弄ると起動順序とか修正できる、コレの意味など詳しくは
man chkconfig
で。

こんなめんどくせーことしたくねーよ、データ破損上等じゃん!

まあ解る、でもこれを設定すると、


service hogehoge stop
とか
/etc/init.d/hogehoge restart
とか
でデーモンを制御できるので、職場の女の子にモテモテになれます*4

じゃーさー、あなたは実際にinitscriptでrailsとか起動させてるの?

いいえwしてませんけど?w

(仕事では Apache-Tomcat-Postgresql みたいなチェーンをきちんと書いてますけどね)

*1:イヤならsudoコマンドとかを指定してあげるとか

*2:たまーにあるけどね、KILLでも死なないとか

*3:頭痛が痛い

*4:何か操作するとき、無駄にたくさんタイプしている方が「くわしそう!」とか思われますけど、実際の所逆だよね…