initとは
initは、
UNIXおよび
Unix系システムにおける最初の
プロセスであり、システム起動時に
カーネルによって実行されます。PID(
プロセスID)1を付与され、他の全ての
プロセスを起動する役割を担います。
ブートローダーが
カーネルを起動し、
カーネルがinitを起動するという流れです。もしinitが適切に動作しない場合、システムは
カーネルパニックに陥り、正常な起動ができなくなる可能性があります。
initの機能は、大きく分けてBSD系とSystem V系の2つに分類されます。どちらのシステムを使用しているかは、ユーザーがマニュアルなどを参照して確認する必要があります。多くの
LinuxディストリビューションではSystem V系のinitが採用されていましたが、
SlackwareのようにBSD系のinitを使用しているものや、Gentoo Linuxのように独自のinitを使用しているものもあります。また、Linux Standard Baseではinitの仕様が定義されています。
近年では、initの設計上の限界に対処するために、systemdやUpstartといった代替システムが登場し、
Ubuntuなどの
Linuxディストリビューションで採用されています。
System V系のinit
System V系のinitは、`/etc/inittab`ファイル内の`:initdefault:`エントリをチェックして、デフォルトのランレベルを決定します。デフォルトのランレベルが設定されていない場合、コンソールにメッセージが表示され、ユーザーが手動でランレベルを入力する必要があります。
利点: 柔軟で拡張性が高い。
欠点: 複雑である。
ランレベル
System Vのランレベルとは、マシンの状態を、実行される
プロセス群によって分類したものです。通常、0から6までの数字と、Sまたはsの計8段階があります。Sとsは同じランレベルを指します。このうち、以下の3つは予約されたランレベルです。
0: 停止 (Halt)
1: シングルユーザーモード
6: 再起動 (Reboot)
残りのランレベルの意味は、システムによって異なります。通常、`/etc/inittab`ファイルで各ランレベルで実行する内容が定義されています。
デフォルトのランレベル
例えば、デフォルトのランレベルが5に設定されているLinuxディストリビューションでは、ランレベル5はマルチユーザーのグラフィカル環境を意味します。具体的には、X Window Systemやディスプレイマネージャが起動します。一方、Solarisではランレベル5はシステムのシャットダウンと電源オフを自動化するために予約されています。
現在のランレベルは以下のコマンドで確認できます。
bash
$ runlevel
$ who -r
通常、ランレベルの変更はrootユーザーが`telinit`または`init`コマンドを使って行います。デフォルトのランレベルは`/etc/inittab`ファイルの`:initdefault:`エントリで確認できます。
BSD系のinit
BSD系のinitは、`/etc/rc`にある初期化用のシェルスクリプトを実行し、`/etc/ttys`で制御されるテキストベースの端末用`getty`や、グラフィカル端末用のXなどを起動します。ランレベルの概念はなく、`/etc/rc`ファイルでinitの動作が定義されます。
利点: 手動での変更や修正が容易である。
欠点: ブート時にサードパーティ製の初期化スクリプトを実行する場合、`/etc/rc`ファイルなどを編集する必要があるため、設定を誤るとシステムが起動しなくなる危険性がある。
BSD系システムでは、起動処理の最後に`/etc/rc.local`ファイルを実行することで、この問題を緩和しようとしていました。NetBSD 1.5以降では、完全にモジュール化されたシステムが導入され、FreeBSD 5.0以降にも移植されています。このシステムでは、`/etc/rc.d`ディレクトリ内のスクリプトが実行されます。System V系ではスクリプトのファイル名順に実行されるのに対し、BSD系では各スクリプトに依存関係を示すタグを記述し、`rcorder`スクリプトがそのタグを基に実行順序を決定します。
initをスキップする
initはシステム起動の唯一の方法ではありません。最近のブートローダ(LILOやGRUBなど)では、カーネル起動後にどのプログラムを実行するかを指定できます。通常は`/sbin/init`が実行されますが、ブートローダのプロンプトで`init=/foo/bar`のように指定することで、他のプログラムを実行できます。例えば、`init=/bin/bash`と指定すると、シェルが起動し、パスワードなしでシステムにアクセスできます。セキュリティ上の懸念がある場合は、ブートローダにパスワードを設定することで保護できます。
BSD系システムでは、起動処理を中断してシングルユーザーモードで起動できます。`boot -s`コマンドで起動すると`/sbin/init`は実行されますが、`exec()`に渡すプログラムのパスを入力するよう求められます。デフォルトでは`/bin/sh`が指定されます。
また、起動に使われる端末が`/etc/ttys`ファイルで「insecure」と定義されている場合、またはセキュリティレベルによっては、initはrootパスワードを要求します。もしここでパスワードを入力せずに処理を中断すると、カーネルはマルチユーザーモードで再起動します。
カーネルの起動後、initが起動できない場合はシステムがパニックになり、使用できなくなります。initのパス指定方法はOSによって異なります。例えば、NetBSDでは`boot -a`、FreeBSDでは`init_path`ローダー変数を使用します。
initの代替
initにはいくつかの設計上の限界があるため、様々な代替システムが開発されています。
GoboLinuxのBootScripts
eINIT: 非同期なプロセス起動が特徴で、シェルスクリプトを使用しないことも可能。
Initng: 非同期な
プロセス起動が特徴。
launchd: macOSで採用されているプロセス起動システム。macOS 10.4以降で使用され、それ以前はinitが使用されていた。古いrc.localはSystemStarterが扱う。
Mudur: Pardus Linuxで採用されている
Python製のinit代替システム。
OpenRC: Gentoo Linuxでデフォルトで使用されているinitシステム。
Service Management Facility: Solaris 10以降で導入されたinitの代替。
systemd: Fedora 15以降でデフォルトとして採用されており、サービスの並列起動とシェルのオーバーヘッド削減を特徴とする。
Upstart: 非同期な
プロセス起動が特徴で、
Ubuntuが起源。
これらの代替システムは、initの持つ問題を解決し、システムの起動速度や柔軟性を向上させることを目指しています。
関連項目
pidof
外部リンク
man pages for init
init(8) – FreeBSD System Manager's Manual Pages (en)
Paper summarizing Unix init schemes
runit
minit
rc.d
busybox