INIT(8)

名前
init, telinit - プロセス制御の初期化

書式
/sbin/init [ -a ] [ -s ] [ -b ] [ -z xxx ] [ 0123456Ss ]
/sbin/telinit [ -t sec ] [ 0123456sSQqabcUu ]

説明

  Init
init は全てのプロセスの生みの親である。 その主な役割は、/etc/inittab(inittab(5)参照) ファイル中に記述されたスクリプトによってプロセスを作り出す事にある。 通常このファイルには、initに各コンソール接続ライン上にgettyを 生成させ、ユーザのログインを可能にするためのエントリーが記されている。 また、特殊なシステムに必要な自律性のプロセスの制御も行う。

ランレベル
ランレベル とは、 指定したプロセス群のみが存在する様にするための、 システムに対するソフトウエア的な設定の一つである。 それぞれのランレベルでinitが作り出すプロセスは /etc/inittabファイルで定められている。 init は、0–6及びSまたはsの、 8 つのランレベルのうちの一つを取ることが出来る。 ランレベルは特権ユーザがtelinitを実行することによって 変更される。 その際telinitはinitに適切なシグナルを送る事により、 どのランレベルに変更すべきかを指示する。

ランレベル0, 1, 6は予約されている。 ランレベル 0 はシステムを停止するために、ランレベル 6 はリブートするために 用いられ、ランレベル1はシステムをシングルユーザモードにするのに用いられる。 ランレベルSは直接用いるためのものではなく、 ランレベル1になった時に実行されるスクリプトのために存在する。 この詳細は、shutdown(8)及びinittab(5)の man ページを参照のこと。

文書には書かれてはいないが、ランレベル 7-9 を使用することも出来る。 文書に書かれていないのは、「伝統的な」Unixの変種は ランレベル 7-9 を使用していないからである。 不思議に思うかも知れないが、 ランレベルS及びsに関しても同じである。 これらは内部的には同一のランレベルのエイリアスなのである。

ブート
カーネルブートの最後のステップとしてinitが起動されると、 initは/etc/inittabファイルを検索し、 initdefaultというエントリーが存在するかを調べる (inittab(5)参照)。 initdefault はシステムが最初に取るべきランレベルを定めている。 /etc/inittabファイル中にそのようなエントリーがない場合、 又は/etc/inittabファイル自体が存在しない場合は、 システムコンソールからランレベルを入力しなくてはならない。

ランレベルをSまたはsにするとシステムは シングルユーザモードに入る。 この場合は/etc/inittabファイルは必要としない。 シングルユーザモードでは、/dev/consoleで/sbin/suloginが起動される。

シングルユーザモードに入る際、initは、 /etc/ioctl.saveからコンソールのioctl(2)状態を読み込む。 このファイルが存在しない場合は、initはコンソール接続ラインを 9600 baudでCLOCALの状態(訳注:ローカルに直接接続されている状態) に初期化する。 シングルユーザモードを抜ける際には、 次回のシングルユーザモードセッションでも同じ設定を用いる事が出来る様に、 コンソールのioctl状態を/etc/ioctl.saveファイルに保存する。

最初にマルチユーザモードに入る際は、initは、 ユーザがログイン可能になる前にファイルシステムをマウントする為に、 まずboot及びbootwaitエントリーを実行する。 そして、ランレベルに適合する全てのエントリーを処理する。

新たなプロセスを起動する際には、initは、/etc/initscriptファイルが 存在するかを調べ、 存在する場合はそのスクリプトを用いてプロセスを起動する。

/var/run/utmp及び/var/log/wtmpファイルが存在する場合は、 initは子プロセスが終了する毎に、その旨を終了した理由とともに 上記ファイルに記録する。

ランレベルの変更
init は、指示された全てのプロセスを生成し終えた後は、 その子孫のプロセスが死ぬか、powerfailシグナルが発せられるか、 telinitからランレベルを変更せよとのシグナルが送られて 来るまで待機している。 上記3条件のいずれかが起きた場合は、/etc/inittabファイルを再度調べる。 いつでもこのファイルに新たなエントリーを追加することが出来る。 しかし、上の3つの条件のどれかが起きるまではinitは待機の状態を続ける。 新たなエントリーに即座に反応させるには、 telinit Qまたはqコマンドを用いてinitを目覚めさせ、 /etc/inittabファイルを再度調べさせればよい。

initは、シングルユーザモードにない時にpowerfail(SIGPWR)シグナルを 受け取ると/etc/powerstatusファイルを読み込む。 そしてこのファイルの内容を基にそれぞれの動作をする。

F(AIL)
    電源供給が途絶え、UPSが電源を供給している。 powerwaitとpowerfailエントリーを実行する。

O(K)
    電源供給が回復している。powerokwaitを実行する。

L(OW)
    電源供給が途絶え、UPSのバッテリー容量が少なくなっている。 powerfailnowエントリーを実行する。

/etc/powerstatus が存在しないか、その内容がF, O, Lの いずれかでない場合、init はFを読み込んだものとして動作する。

SIGPWR と /etc/powerstatus を使うことは推奨されない。 init に何かをしようとする場合は /dev/initctl 制御チャネルを 使うべきである。このことに関する更なる情報はsysvinit パッケージの ソースコードを参照すること。

init は、ランレベルを変更するよう要請を受けると、 先ず新たなランレベルでは定義されていない全てのプロセスに対して 警告シグナルSIGTERMを送る。 その後5秒間待機してから SIGKILLシグナルを送り、それらのプロセスを強制的に終了させる。 init は、それら全てのプロセス(及びそれらの子孫)は 自分がそれらのプロセスのために作り出したプロセスグループに 今なお属している、と仮定していることに注意。 あるプロセスがそのプロセスグループ属性を変えてしまった場合は、 上記のシグナルは受け取らない。 従って、そのようなプロセスは別途終了させる必要がある。

TELINIT
/sbin/telinitは/sbin/initにリンクされている。 /sbin/telinitは一文字の引数を受け取り、 initに適切な動作を行なわせるためのシグナルを送る。 以下に示すような引数を用いて telinitに指示を与えることが出来る:

0,1,2,3,4,5又は6
    指定されたランレベルに変更する様にinitに命令する。

a,b,c
    /etc/inittab中のランレベルa, b, cのいずれかを 含むエントリーだけを実行するようinitに命令する。

Q または q
    /etc/inittabファイルを走査し直すようにinitに命令する。

S または s
    シングルユーザモードへと変更するようinitに命令する。

U or u
    (状態はそのままで)再実行するようにinitに命令する。 /etc/inittabの再読み込みは行なわない。 ランレベルは Ss12345 のいずれかでなければならない。 それ以外の場合は暗黙に無視される。

telinitはinitに、プロセスにTERMシグナルを送ってから KILLシグナルを送る迄の時間を指示することもできる; デフォルトでは 5 秒に設定されているが、-t secオプションを用いて 変更することも出来る。

telinitは適切な特権を持ったユーザのみが実行することが出来る。

initプログラムは自分のプロセスIDを見て、 自分がinitなのかtelinitなのかをチェックする。 本当のinitのプロセス ID は常に1である。 このことにより、telinitを起動するかわりに単にinitを起動してもよい。

環境変数
initは子プロセスのために以下のような環境変数を設定する:

PATH
    /usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin

INIT_VERSION
    名前の通り。 あるスクリプトがinitにより直接実行されたのかどうかを見分ける際に有用。

RUNLEVEL
    システムの現在のランレベル。

PREVLEVEL
    直前のランレベル(ランレベルを変更した際に有用)。

CONSOLE
    システムコンソール。これは実際はカーネルから継承している。 しかし、もしこれが設定されていなかった場合は init は /dev/consoleをデフォルトとして設定する。

ブートフラグ
ブートモニター(例えば LILO)からinitに様々なフラグを渡すことが出来る。 initは以下のようなフラグを受け付ける:

-s, S, single
    シングルユーザモードでブートする。 このモードでは/etc/inittabを参照する。 また、ブート時のrcスクリプトはシングルユーザモードのシェルが 起動される前に実行される。

1-5 ブート時に入るべきランレベル。

-b, emergency
    他の起動用スクリプトは実行せず直接シングルユーザシェルへとブートする。

-a, auto
    LILO ブートローダーはカーネルからデフォルトのコマンドラインで (ユーザーの介入なしに)起動された場合、コマンドラインに ``auto'' の単語を追加する。 initはこの単語を見つけると、``AUTOBOOT''環境変数に``yes''を設定する。 これはセキュリティ関係のことには使えないことに注意。 当然のことながら、ユーザーは``auto''や -a を手動で コマンドラインに追加することもできる。

-z xxx
    -z 引数は無視される。これを使ってコマンドラインを少し拡張することができ、 そのためにスタックを若干余分に使用する。 init はコマンドラインを操作するので、 ps(1) は現在のランレベルを表示できる。

インターフェース
init は メッセージのやりとりのために/dev にある FIFOである /dev/initctlを listen している。 telinit はこれを init との通信に用いる。 このインターフェースは十分に文書化されていない。 興味を持ったなら、initソースコード tar アーカイブのsrc/ サブディレクトリにあるinitreq.hを見て研究してほしい。

シグナル

SIGHUP
    init は /etc/initrunlvl と /var/log/initrunlvl を探す。 もしこれらのどちらかのファイルがあり、ランレベルが ASCII コードで書かれていたら、 init はそのランレベルに変更する。 これは従来との互換のためだけに存在する! 通常の場合(これらのファイルがない場合)、init はtelinit qが 実行されたのと同様の動作をする。

SIGUSR1
    このシグナルを受け取ると、init は制御用 FIFO である/dev/initctlを 一旦クローズして再オープンする。 ブートスクリプトが /dev を再マウントした時に便利である。

SIGINT
    カーネルは普通 CTRL-ALT-DEL が押されるとこのシグナルを init に送る。 これによりctrlaltdelアクションが実行される。

SIGWINCH
    カーネルはKeyboardSignalキーが押されるとこのシグナルを送る。 これによりkbrequestアクションが実行される。

準拠
initは System V の init と互換である。 initは /etc/init.d及び/etc/rc{runlevel}.dディレクトリ中のスクリプト と密な連係の下に一緒に実行される。 使用しているシステムがこのディレクトリ構造をとっているなら、 /etc/init.dディレクトリ中にREADMEがあり、 スクリプトがどのように動作するか説明されているはずである。

ファイル
/etc/inittab
/etc/initscript
/dev/console
/etc/ioctl.save
/var/run/utmp
/var/log/wtmp
/dev/initctl

警告
init は、 生成したプロセス及びその子孫が、 それらのために作ったプロセスグループに現在も 属したままでいる、と仮定している。 プロセスグループが元々のものと変わっている場合は、 init はそのプロセスを kill 出来ないので、 異なる二つのプロセスが同一の端末ラインから入力を読み込む等といった現象が 起きてしまう可能性がある。

返り値
init は、あるエントリーが 2 分間に 10 回以上繰り返して 再生成されるのを発見すると、 コマンド文字列に誤りがあると仮定してシステムコンソールにエラーメッセージを 表示し、5 分以上経過するかシグナルを受け取るまでそれ以上そのエントリーを 再生成する事を拒否する。 こうすることによって、/etc/inittab中に綴り間違いが有る場合 や、そのエントリーで使用するプログラムが削除されている場合に、 システム資源を使い尽くしてしまうことを防いでいる。

著者
Miquel van Smoorenburg (miquels@cistron.nl), マニュアルページの最初の版は Michael Haardt (u31b3hs@pool.informatik.rwth-aachen.de) による。

関連項目
getty(1), login(1), sh(1), who(1), shutdown(8), kill(1), inittab(5), initscript(5), utmp(5)