SysVinit
SysVinit を使用するシステムでは、Linux カーネルがロードされたあと init が一番最初のプロセスとして起動します。カーネルによって使われるデフォルトの init プログラムは /sbin/init
であり systemd-sysvcompat (新しい環境でのデフォルト、systemd) や sysvinitAUR に含まれています。この記事において init という言葉は sysvinit のことを指します。
inittab は /etc
に置かれた init の起動設定ファイルのことです。特定のランレベルに入ったときにどのプログラムやスクリプトを実行すればいいのか init に指定します。
SysVinit ベースでありながら Arch のシステムでは init は使用せず、ほとんどの作業は実際にはメインのブートスクリプトが担っています。この記事では init と inittab について取り上げます。
目次
init と inittab の概要
init はいつでもプロセス1であり、スワップ領域の管理を除いて、全ての他のプロセスの親プロセスになります。pstree
を使うことでシステムのプロセス階層のどこに init があるか知ることができます:
$ pstree -Ap
init(1)-+-acpid(3432) |-crond(3423) |-dbus-daemon(3469) |-gpm(3485) |-mylogin(3536) |-ngetty(3535)---login(3954)---zsh(4043)---pstree(4326) |-polkitd(4033)---{polkitd}(4035) |-syslog-ng(3413)---syslog-ng(3414) `-udevd(643)-+-udevd(3194) `-udevd(3218)
(名前の通り) システムの初期化をする他に、init は再起動やシャットダウン、リカバリモード (シングルユーザーモード) での起動も管理します。これらに対応するために、inittab はエントリを異なるランレベルにグループ化しています。Arch が使用するランレベルはそれぞれ、halt には 0、シングルユーザーモードには 1 (エイリアスで S)、通常の起動時 (マルチユーザーモード) には 3、X には 5、再起動には 6 です。別のディストロではランレベルが異なっている可能性がありますが 0, 1, 6 については全てのディストロで共通です。
起動時に、init は inittab を見て適切なアクションを実行します。inittab のエントリは以下のような形式を取ります:
id:runlevels:action:process
id
はエントリのユニークな識別子 (ただの名前で、init に影響は与えません) で、runlevels
はランレベルの文字 (区切りなし) です。init のランレベルが runlevels
になると、action
が実行され、適当なときに process
が実行されます。特殊な action
を指定すると init は runlevels
を無視して特殊なマッチング方法を使います。詳しい説明は次のセクションにあります。
man 5 inittab
や man 8 init
も参照してください。
ランレベルの切り替え
ブートローダー
システムが起動するときのランレベルを変更するには、ブートローダーの適当な設定行に起動したいランレベル n
を追加します。一度だけ別のランレベルで起動したいときは、ランレベルの数字をカーネルパラメータに追加してください (例: ランレベル 3 の場合 3
)。
ランレベルは一番最後に付けることでカーネルが起動するべきランレベルを知ることができます。別の init プログラムを使うには (例: systemd)、init=/bin/systemd
などを追加します。
起動後
システムが起動した後は、telinit n
を実行することで init にランレベルを n
に変更するように要求できます。init は inittab を読み込んでランレベル n と現在のランレベルを比較して、新しいランレベルには存在しないプロセスを終了して、古いランレベルに存在しないアクションを実行します。両方のランレベルに存在するプロセスはそのままで手をつけられません。実際には、終了の方法はもう少し複雑です。技術的な詳細は init の man ページにあります。
init は inittab を監視しません。inittab に変更を加えて、その変更を適用するには telinit
を明示的に呼び出す必要があります。telinit q
コマンドは init に inittab を再調査させますがランレベルは変更しません。
inittab
このセクションでは inittab の一般的なエントリについて考察します。Arch で使用されるデフォルトの inittab のエントリと同じ順番で説明します。その後、各自で inittab エントリを作成するのに役立つ例をあげます。
デフォルトのランレベル
デフォルトのランレベルは 3 です。デフォルトで (X で使用することになっている) ランレベル 5 で起動したい場合は以下をアンコメントまたは追加してください:
id:5:initdefault:
メインのブートスクリプト
以下がメインの Arch init スクリプトです。
rc::sysinit:/etc/rc.sysinit rs:S1:wait:/etc/rc.single rm:2345:wait:/etc/rc.multi rh:06:wait:/etc/rc.shutdown
シングルユーザーブート
キーファイルが見つからなかったり、ハードドライブやファイルシステムが破損したり死亡するなどして、カーネルが途中で起動しなくなることがあります。そのような場合、init イメージは自動的にシングルユーザーモードに移行して root ログインができるようになり、/sbin/login
の代わりに /sbin/sulogin
を使ってログインプロセスを制御します。GRUB, LILO, Syslinux などの設定のカーネルコマンドラインに S
という文字を追加することでもシングルユーザーモードで起動できます。sulogin 以外を実行させたい場合は、以下の部分に記述してください。
su:S:wait:/sbin/sulogin -p
Getty とログイン
以下はターミナルで getty を実行する重要なエントリです。デフォルト設定では複数の getty が tty1-6 で動作するようになっており、ログインプロンプトで画面に表示されます。openvt, chvt, stty, ioctl なども参照してください。
c1:234:respawn:/sbin/agetty 9600 tty1 xterm-color c5:5:respawn:/sbin/agetty 57600 tty2 xterm-256color
Ctrl+Alt+Del
特殊なキーシーケンス Ctrl+Alt+Del
が押されると、以下が実行されます。
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
X プログラム
デバッグを厭わない場合は、inittab からあらゆる種類のプログラムを起動する方法を見つけ出すことができます。有用なプログラムのタイプとしてはランレベルが 5 で、multi-user-x-mode のときにログインマネージャを起動することが挙げられます。以下の例ではランレベルが 5 になったときに SLiM を起動する方法がわかります。
x:5:respawn:/usr/bin/slim >/dev/null 2>&1 #x:5:respawn:/usr/bin/xdm -nodaemon -confi /etc/X11/xdm/archlinux/xdm-config
電源検出スクリプト
Init は UPS デバイスを照会して UPS の状態にあわせてプロセスを実行することができます。例えば:
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down" pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
カスタムキーボードリクエスト
以下の行は特別なキーシーケンスが押された時のカスタム関数を追加します。Ctrl+Alt+Del
と同じようにこの特別なキーシーケンスは自由に修正することができます。
kb::kbrequest:/usr/bin/wall "Keyboard Request -- edit /etc/inittab to customize"
kbrequest のトリガー
init プロセス (1) に root で (sudo を使って) WINCH シグナルを送信することで特殊なキーシーケンス kbrequest を起こすことができます。以下の例では、次のコマンドによって wall
が全ての tty に書き込みを行います:
kill -WINCH 1
Broadcast message from root@askapachehost (console) (Wed Oct 27 14:02:26 2010): Keyboard Request -- edit /etc/inittab to customize
systemd への移行
systemd#SysVinit/initscripts からの移行を参照。