7.7. ブートスクリプトはどのようにして動くのか

Linux では SysVinit という特別なブート機能があり ランレベル (run-levels) という考え方に基づいています。 ランレベルの扱いはシステムによって異なりますので、ある Linux において動作しているからといって LFS においても全く同じように動くわけではありません。 LFS では独自の方法でこれを取り入れることにします。 ただし標準として受け入れられるような方法を取ります。

SysVinit (これ以降はinitと表現します) はランレベルという仕組みにより動作します。 ランレベルには7つのレベル (0 から 6) があります。 (実際にはランレベルはそれ以上あるのですが、特殊な場合であって普通は利用されません。 詳しくは init(8) を参照してください。) 各レベルは、コンピューターの起動時における処理動作に対応づいており、デフォルトのランレベルは 3 となっています。 ランレベルの詳細を以下に説明します。

0: コンピューターの停止
1: シングルユーザーモード
2: マルチユーザーモード、ネットワークなし
3: マルチユーザーモード、ネットワークあり
4: 将来の拡張用として予約されています。 3 と同じものとして扱われます。
5: 4 と同様。通常 (X の xdm や KDE の kdm のような) GUI ログインに用いられます。
6: コンピューターの再起動

7.7.1. Sysvinit の設定

カーネルの初期化にあたって最初に起動するプログラムは、コマンドラインから指定されるものか、あるいはデフォルトでは init です。 このプログラムは初期設定ファイル /etc/inittab を読み込みます。 そのファイルは以下のようにして生成します。

cat > /etc/inittab << "EOF"
# Begin /etc/inittab

id:3:initdefault:

si::sysinit:/etc/rc.d/init.d/rc S

l0:0:wait:/etc/rc.d/init.d/rc 0
l1:S1:wait:/etc/rc.d/init.d/rc 1
l2:2:wait:/etc/rc.d/init.d/rc 2
l3:3:wait:/etc/rc.d/init.d/rc 3
l4:4:wait:/etc/rc.d/init.d/rc 4
l5:5:wait:/etc/rc.d/init.d/rc 5
l6:6:wait:/etc/rc.d/init.d/rc 6

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now

su:S016:once:/sbin/sulogin

1:2345:respawn:/sbin/agetty --noclear tty1 9600
2:2345:respawn:/sbin/agetty tty2 9600
3:2345:respawn:/sbin/agetty tty3 9600
4:2345:respawn:/sbin/agetty tty4 9600
5:2345:respawn:/sbin/agetty tty5 9600
6:2345:respawn:/sbin/agetty tty6 9600

# End /etc/inittab
EOF

この初期化ファイルに関することは inittab の man ページにて説明されています。 LFS において重要となるコマンドは rc です。 初期化ファイルは rc コマンドに対してスクリプトの実行を指示します。 実行されるスクリプトは /etc/rc.d/rcS.d ディレクトリにて S で始まるスクリプトです。 そしてその後に /etc/rc.d/rc?.d ディレクトリにて、同じく S で始まるスクリプトも実行されます。 ここで ? は、初期化を行う際の数値を示します。

扱いやすさを考慮して、rc スクリプトは /lib/lsb/init-functions ディレクトリにあるライブラリ群を読み込む形にしています。 このライブラリは、さらにオプションで設定ファイル /etc/sysconfig/rc.site を読み込みます。 本節以降に説明している、各種の設定ファイルにおけるパラメーターは、上のファイルにて設定することもできます。 上のファイルは、システム上のパラメーターを1つのファイルに集約して設定できるようになっています。

デバッグがしやすいように、各ライブラリの関数スクリプトは、すべて /run/var/bootlog にログを出力するようになっています。 /run ディレクトリは tmpfs であることから、/run/var/bootlog ファイルはブート前後にて恒常的なファイルではありません。 ただしブート処理の最後には、恒常的なファイルである /var/log/boot.log に情報が出力されます。

7.7.2. ランレベルの変更

ランレベルを変更するには init <runlevel> を実行します。 <runlevel> はランレベルを示す数字です。 例えばコンピューターを再起動するには init 6 コマンドを実行します。 これは reboot コマンドのエイリアスとなっています。 同様に init 0halt のエイリアスです。

/etc/rc.d ディレクトリの配下には複数のサブディレクトリがあります。 そのディレクトリ名は rc?.d のようになっています。 (? はランレベルの数字を表します。) また rcsysinit.d というサブディレクトリもあります。 それらサブディレクトリ内には数多くのシンボリックリンクがあります。 シンボリックリンクの先頭一文字には KS が用いられ、続いて二桁の数値文字がつけられています。 K はサービスの停止 (kill)、S はサービスの起動 (start) を意味します。 二桁の数字はスクリプトの起動順を定めるもので、00 から 99 までが割振られ、小さな数字から順に実行されます。 init コマンドによってランレベルが変更される時は、そのランレベルに応じて必要なサービスが起動するか停止することになります。

スクリプトファイルは /etc/rc.d/init.d ディレクトリにあります。 実際の処理はここにあるファイルが用いられます。 これらに対してはシンボリックリンクが用意されています。 サービスの起動 (S で始まる) と停止 (K で始まる) を行うシンボリックリンクは /etc/rc.d/init.d ディレクトリにあるスクリプトを指し示しています。 このようにしているのは、各スクリプトが startstoprestartreloadstatus といったさまざまなパラメーターにより呼び出されるためです。 K の名前を持つシンボリックリンクが起動されるということは stop パラメーターをつけて該当するスクリプトが実行されるということです。 同様に S の名前を持つシンボリックリンクが起動されるということは start パラメーターをつけて呼び出されるということになります。

上の説明には例外があります。 rc0.d ディレクトリと rc6.d ディレクトリにある、S で始まるシンボリックリンクはサービスを何も起動させません。 stop パラメーターが与えられ、何らかのサービスを停止します。 ユーザーがシステムを再起動したり停止したりする際には、サービスを起動させる必要はないわけで、システムを停止するだけで済むからです。

スクリプトに対するパラメーターは以下のとおりです。

start

サービスを起動します。

stop

サービスを停止します。

restart

サービスをいったん停止し再起動します。

reload

サービスの設定ファイルを更新します。 設定ファイルが変更されたものの、サービスの再起動は必要ではない場合に利用します。

status

サービスがどの PID 値で動いているかを表示します。

ブート機能を動作させる方法は自由に取り決めて設定して構いません。 このシステムはつまるところあなた自身のシステムだからです。 上に示したファイル類はブート機能を定めた一例に過ぎません。