chkconfigに登録されていないデーモンのランレベルをいきなり変えてはいけない | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

いまさらなネタでもあるんですが、RedHatとかのデーモンの自動起動・自動停止の管理はchkconfigを使うというのが一般的ですが、後で追加したパッケージの起動のランレベルをいきなり変えるとサーバーの再起動や停止時にちゃんと自動停止してくれないかもよ、ってお話です。



chkconfigの仕組み


この辺は、ググれば情報はたくさん出てくるので簡単にしか書きませんが、init.dの下に配置されている各デーモン用のスクリプトのヘッダ部分で起動するランレベルが定義されています。


#!/bin/bash
#
# httpd        Startup script for the Apache HTTP Server
#
# chkconfig: 345 85 15
# description: Apache is a World Wide Web server.  It is used to serve \
#          HTML files and CGI.
# processname: httpd


「chkconfig:」って書かれた箇所が該当のところで、「起動するランレベル」「起動時のプライオリティ」「停止時のプライオリティ」の順番で書いていきます。
ランレベル345の時に起動させ、起動する際のプライオリティは85、停止時のプライオリティは15としています。

この設定でchkconfigに登録されていれば、


# chkconfig --list httpd
httpd           0:off   1:off   2:off   3:on    4:on    5:on    6:off

って状態になり、rc3.d~rc5.dの中にシンボリックリンクが作成されます。


# ls -la /etc/rc3.d/S85httpd
lrwxrwxrwx 1 root root 15  8月 22 09:51 /etc/rc3.d/S85httpd -> ../init.d/httpd

停止の場合はランレベル0なのでrc0.dですね。


# ls -la /etc/rc0.d/K15httpd
lrwxrwxrwx 1 root root 15  8月 22 09:51 /etc/rc0.d/K15httpd -> ../init.d/httpd

同様に再起動した場合はランレベル6なのでrc6.dの下に自動停止用のスクリプト(シンボリックリンク)が作成されます。

chkconfigの起動するデーモンの管理は、rcX.dの下にシンボリックリンクが存在しているかどうかで管理しています。
コマンド実行時に毎回見に行っているようです。
ですので、このシンボリックリンクを消すことでも起動するランレベルを変更することができます。


# rm S85httpd
rm: remove シンボリックリンク `S85httpd'? y
# chkconfig --list httpd
httpd           0:off   1:off   2:off   3:off   4:on    5:on    6:off

は、

# chkconfig --level 3 httpd off

と、同義になります。



chkconfigに登録していないデーモンのランレベルをいきなり変えると自動停止してくれない


で今回の問題ですが、新しく追加したパッケージなどをデーモンとして自動起動させたいような場合、chkconfigに登録されていない状況で起動するランレベルをいきなり変更すると、自動起動はするようになるのですが自動停止はしてくれません。


# chkconfig --del httpd
# chkconfig --list httpd
サービス httpd は chkconfig をサポートしますが実行レベルで参照されていません (run 'chkconfig --add httpd')
# chkconfig --level 345 httpd on
# cd /etc/rc3.d/
# ls -la S85httpd
lrwxrwxrwx 1 root root 15  8月 22 10:13 S85httpd -> ../init.d/httpd
# chkconfig --list httpd
httpd           0:off   1:off   2:off   3:on    4:on    5:on    6:off


上記のように自動起動はちゃんと行えていますが、rc0.dの下を覗いてみると自動停止のスクリプトが配置されていません。


# ls -la /etc/rc0.d/S15httpd
ls: /etc/rc0.d/S15httpd: そのようなファイルやディレクトリはありません

ってことで、Apacheの自動停止が正常に行われません。
まぁ、最終的にはkillallでプロセスが殺されますけどお行儀のいいやりかたではありませんし、場合によっては障害となる可能性もあります。

で、正式なやり方としてはちゃんとchkconfigにaddしてから起動するランレベル変えましょうねってやり方になります。


# chkconfig --add httpd
# ls -la /etc/rc0.d/K15httpd
lrwxrwxrwx 1 root root 15  8月 22 10:30 /etc/rc0.d/K15httpd -> ../init.d/httpd

または、resetオプションを実行しても問題ありません。


# chkconfig --del httpd
# chkconfig --level 345 httpd on
# ls -la /etc/rc0.d/K15httpd
ls: /etc/rc0.d/K15httpd: そのようなファイルやディレクトリはありません
# chkconfig httpd reset
# ls -la /etc/rc0.d/K15httpd
lrwxrwxrwx 1 root root 15  8月 22 10:34 /etc/rc0.d/K15httpd -> ../init.d/httpd


resetオプションを実行するとinitスクリプトのヘッダを読み直してその通りに設定しなおしてくれます


こう考えると、よくサーバー立てたら不要なデーモンは動かさないようにしましょうとか言われますけど、chkconfigコマンドで指定のレベルでOn/Offするよりは、initスクリプトのヘッダで本当に必要なレベルで動かすように定義しておいた方がadd/del/resetで管理できるので確実なのかもしれません。
まぁ、スクリプトの数は多いので手間といえば手間なのですが。


不安があるのであれば一旦各スクリプトをresetさせるのも良いかと思います。