INIT(8)

名称
init - プロセス制御の初期化を行う

書式
init init [ 0 | 1 | 6 | c | q]

解説
init ユーティリティはブート処理の最後に起動されます。 init は通常、 rc(8) で説明されている自動リブートシーケンスを実行します。それが成功すると、 システムはマルチユーザモードになります。 リブートスクリプトの実行に失敗すると、 init はスーパユーザが使うシェルを起動してシングルユーザモードを 開始させます。 init ユーティリティは、ブートプログラムからのパラメータの指示を受けて、 マルチユーザモードに移行せず、 一般のデーモンを起動することなくシングルユーザモードの シェルを起動させることができます。 その場合、システムはメンテナンスのためのモードになり、 シェルを抜ける (^D を入力する) ことで シングルユーザモードからマルチユーザモードになります。 これによって、 init は /etc/rc をファストブートモード (ディスクチェック省略) で実行します。

もし ttys(5) ファイルの console のエントリが “insecure” にマークされていた場合には、 init はシングルユーザモードのシェルを起動する前に、スーパユーザのパスワードを 要求します。 パスワードチェックは、 console が “secure” にマークされていればスキップされます。

カーネルは 4 種類のセキュリティレベルで走行します。どのスーパユーザ プロセスもセキュリティレベルを上げることができますが、レベルを下げることが できるプロセスはありません。 セキュリティレベルは以下のように定義されます:

-1  常に危険なモード - システムは常にレベル 0 モードで走行します。 これは初期値のデフォルトです。

0   危険なモード - 変更不可 (immutable) フラグや追加のみ (append-only) フラグは オフにできます。 全てのデバイスは、そのパーミッションに従って読み書きされます。

1   安全なモード - 変更不可フラグや追加のみのフラグはオフにできません。 マウントされたファイルシステムのディスクおよび /dev/mem や /dev/kmem や (プラットフォームにあれば) /dev/io は read-only となります。 カーネルモジュール (kld(4) 参照) は、ロードおよびアンロードできません。

2   安全度の高いモード - レベル 1 のモードの効果に加え、ディスクは マウントされていようといまいと、 (mount(2) を除き) 常に read-only となります。 このレベルは、ファイルシステムをアンマウントして変更を加えることを不可能に します。また、システムがマルチユーザで走行中に newfs(8) を実行することも出来なくなります。

    更に、カーネル時間の変更は 1 秒以内に制限されています。 これ以上変更しようとすると、 “Time adjustment clamped to +1 second” というメッセージをログします。

3   ネットワークの安全モード - 安全度の高いモードに加え、 IP パケットフィルタルール (ipfw(8), ipfirewall(4), pfctl(8) 参照) を変更不可能とし、 dummynet(4) や pf(4) の設定を修正不可能とします。

初期のセキュリティレベルが非 0 だった場合、 init はセキュリティレベルを変更しません。 それ以外の場合、 init は、最初にレベル 1 に上げます。 レベルは減らすことはできませんので、 その後の操作においてはレベルは最低 1 であり、 これはシングルユーザモードに戻る場合においても成立ちます。 マルチユーザモードにおいてレベル 2 で システムを走らせたい場合は、シングルユーザの状態の間に、 sysctl(8) を使って、変数 kern.securelevel に必要なセキュリティレベルの値を設定します。

init が jail 中で実行される場合、 “ホストシステム” のセキュリティレベルは影響しません。 jail をサポートするためにカーネル中に設定される情報の一部に、jail 毎の “セキュリティレベル” 設定があります。 これにより、ホストシステムよりも高いセキュリティレベルで jail 内を実行することが可能となります。 jail に関する更なる詳細は jail(8) を参照してください。

マルチユーザモードの場合、 init は ttys(5) ファイルで指示された端末ポートのためのプロセスを管理します。 init ユーティリティはこのファイルを読み込み、 2 番目のフィールドに指示されたコマンドを 実行します。 ただし、1 番目のフィールドが /dev 中のデバイスを参照し、そのデバイスが設定されていない場合は例外です。 1 番目のフィールドは、コマンドへ渡される最後の引数になります。 そのコマンドは通常、 getty(8) で、 getty は tty をオープン、初期化し、 login(1) プログラムを実行します。 login プログラムは、ユーザがログインするとシェルを起動します。 ユーザがログアウトするか異常終了するなどして、そのシェルが終了すると、 init ユーティリティが起こされ、 utmp(5) ファイルからユーザを消し、 wtmp(5) ファイルにログアウトを記録します。 このサイクルは、 init プログラムがその端末に新しい getty を実行することで繰り返されます。

init ユーティリティは任意のデーモンを走行させ続けるためにも使用可能であり、 デーモンが死んだ場合には自動的に再開します。 この場合、 ttys(5) ファイルの 1 番目のフィールドは、 設定されたデバイスノードへのパスを参照してはならず、 デーモンに対する最後のコマンドライン引数として渡されます。 これは AT&T UNIX /etc/inittab にある機能と同様です。

ラインの状態 (on, off, secure, getty, ウィンドウの情報) は、 ttys(5) ファイルを書き換えて “kill -HUP 1” によってシグナル SIGHUP を init に送ることで、リブートせずに変更できます。 このシグナルを受け取ると init は ttys(5) ファイルを再度読み込みます。 ttys(5) でラインがオフにされると、 init はそのラインに関係するセッションの制御プロセスに SIGHUP シグナルを送ります。 オフであったラインが ttys(5) ファイルでオンにされると、 init は 2 番目のフィールドで指定されるコマンドを起動します。 ラインのコマンドやウィンドウフィールドが変更された場合、その変更は現在 のログインセッションが終了するまで有効にはなりません。 (例えば、 init によって新しいプロセスが起動されるまで有効にならない。) ttys(5) 中のあるラインをコメントアウトあるいは削除した場合は、 init はそのラインに関しては何も実行しません。 しかしこの場合、 ttys(5) ファイルと utmp(5) ファイル内の記録情報が一致しなくなるため、試すことはお勧めしません。

“kill -TERM 1” などによって terminate シグナル (TERM) を受けると、 init ユーティリティはマルチユーザモードを終了し、シングルユーザモードに復帰します。 ハードウェアまたはソフトウェアの問題でデッドロックしたプロセスがある場合、 init はすべてのプロセスの終了を待たず (これは無限に終らないかも知れません)、 30 秒間でタイムアウトして警告のメッセージを出力します。

terminal stop シグナル (TSTP) を送ると ( “kill -TSTP 1” )、 init ユーティリティは新しい プロセス を起動するのをやめ、徐々にシステム停止可能な状態にします。 その後、hangup シグナルで完全なマルチユーザモードに戻り、terminate シグナル でシングルユーザモードに移ります。 この hook は reboot(8) と halt(8) で使われています。

interrupt シグナル (INT) を送ると ( “kill -INT 1” )、 init ユーティリティはすべてのプロセスを (デッドロックプロセスを待たずに) 終了させ、 リブートを実行します。 この操作は、マシンがハングした時に、カーネルの中から、あるいは、X から、 システムを安全にシャットダウンするのに便利です。

init ユーティリティは同様に、ユーザ定義シグナル 1 (USR1) を送られた場合はマシンを停止し、 ユーザ定義シグナル 2 (USR2) を送られた場合はマシンを停止してから電源を切ります (ハードウェアが許す場合)。

マシンをシャットダウンする時、 init は /etc/rc.shutdown スクリプトを実行しようとします。 このスクリプトは innd (インターネットニュースサーバ) のような特定のプログラムを綺麗に終了させるために使用可能です。

init の役割は非常に重要で、もし init が死ぬとシステムが自動的にリブートされます。 もしブート時に init プログラムを見つけられなければ、システムは “panic: init died (signal %d, exit %d)” のようなメッセージを出力して panic で終了します。

2 番目の書式行のようにユーザプロセスとして実行する場合、 init は AT&T UNIX の動作をエミュレートします。すなわち、スーパユーザがコマンドラインで ランレベル を指定可能であり、 init はオリジナルの (PID 1) init に次のようなシグナルを送ります:
ランレベル | シグナル | 動作
0 | SIGUSR2 | 停止して電源切断
1 | SIGTERM | シングルユーザモードへ移行
6 | SIGINT | マシンを再起動
c | SIGTSTP | 更なるログインを抑止
q | SIGHUP | ファイル
ttys(5) を再スキャン

診断

getty repeating too quickly on port %s, sleeping. ラインにサービスを提供するプロセスが、起動されるたびにすぐ終了してしまう。 これは、端末ラインに着信があるかノイズが大きい場合にしばしば起こります。 init は 30 秒間スリープし、 その後、プロセスを開始させようとし続けます。

some processes would not die; ps axl advised. シャットダウンの際、ハングしていて終了させられないプロセスがあります。 この状態は、通常、デバイスに異常があるときにデバイスドライバで貼り付い てしまうことにより起こります。

関連ファイル
/dev/console
    システムのコンソールデバイス
/dev/tty*
    ttys(5) 内にある端末ポート
/var/run/utmp
    現在ログインしているのユーザの情報
/var/log/wtmp
    すべてのログイン・ログアウトの情報
/etc/ttys
    端末の初期化情報が書かれたファイル
/etc/rc
    システム立ち上げ用スクリプト
/etc/rc.shutdown
    システムシャットダウン用スクリプト

関連項目
kill(1), login(1), sh(1), dummynet(4), ipfirewall(4), kld(4), pf(4), ttys(5), crash(8), getty(8), halt(8), ipfw(8), jail(8), pfctl(8), rc(8), reboot(8), shutdown(8), sysctl(8)

歴史
init ユーティリティは AT&T UNIX から登場しました。

警告
sysctl(8) を持たないシステムは、セキュリティレベル -1 で動作します。

ブートシーケンスにおいて、セキュリティレベルを 1 より高く設定するのが あまりにも早すぎると、 fsck(8) が一貫性のないファイルシステムを補修することを妨げてしまう可能性があります。 セキュリティレベル設定を行う場所として適切なところは、 全てのマルチユーザ立ち上げ処理が完了した後である、 /etc/rc の末尾です。