いうinitデーモンで置き換えられている。Linux』の抜粋である。SysVinitに代わるものはほかにもいくつかある。有名なものとして挙げられるのがinitngであり、DebianやUbuntuで動作する。OSではlaunchdが使われている。そのうちにUbuntuでは、これら各システムの機能がUpstartに取り込まれることになるだろう。実行レベル(runlevel、ランレベル)ベースのSysVinitデーモン(sysvinitパッケージ)では、各実行レベル(シングルユーザモード、マルチユーザモードなど)と、/etc/rc?.dディレクトリから/etc/init.d内のinitスクリプトへのリンクを利用して、システムサービスの起動および停止を行っている。イベントベースinitデーモンであるUpstart(upstartパッケージ)はイベントを利用して、システムサービスの起動と停止を行う。UbuntuではFeistyリリースでinitデーモンがUpstartに切り替えられ、SystemVの設定からUpstartの設定への移行が開始された。本稿では、Upstartに加えてSysVinitの残存部分(/etc/rc?.dおよび/etc/init.dの各ディレクトリと実行レベルの概念)についても解説する。Upstartのinitデーモンはイベントベースであり、システム上のなんらかの変化を捉えて指定されたプログラムを実行する。サービスの起動と停止を行うこれらのプログラムのほとんどは、スクリプトである。した設定は、システムが実行レベルに入る際にリンクを用いてinitスクリプトを呼び出すというSysVinitの考え方によく似ている。Upstartのほうが柔軟性に優れている。実行レベルの変化時に限ってサービスを起動/停止するわけではなく、システムの変化を表す情報を受け取った時点でサービスを起動/停止できる。そのような変化をイベントと呼んでいる。Upstartは実行中のシステムに対してファイルシステム、プリンタといったデバイスの追加または削除が行われたという通知をudevから受け取ったときにアクションを起こすことができる。システムの起動、シャットダウン、ジョブの状態変化によってもサービスの起動/停止が可能だ。今後のUpstartSysVinitからUpstartへの移行には、Linuxシステムの多くの部分が関係する。切り換えを円滑なものにすると共にエラーの発生を極力抑えるために、Upstartチームは何回かのリリースに分けて移行を行うことを選んだ。UbuntuにおけるUpstartデーモンの利用はFeisty(6.10)から始まっている。FeistyからGutsy(7.10)+2リリースの間に、UbuntuはSysVinitの環境から離れ、より簡潔で柔軟なUpstartの環境に移行する。Upstartの管理下に置かれるシステムサービスが増えるにつれ、/etc/init.dおよび/etc/rc?.dディレクトリの中身は/etc/event.dディレクトリのエントリで置き換えられていくことになる。実行レベルはもはやUbuntuの正式な機能ではなくなるが、サードパーティ製ソフトウェアとの互換性のために残される。最終的にはcrondも置き換えられるだろう。Upstartシステムは5つのパッケージで構成され、すべてがデフォルトでインストールされている。ttyサービス用のジョブ定義ファイル定義ここでは、initの説明をわかりやすくするために、いくつかの用語を定義する。イベントとはinitに通知できる状態の変化である。イベントは、それがシステム内部の状態であれ外部のものであれ、ほぼどんな状態の変化によっても発生させることができる。2というイベントを、ファイルシステムのマウントはpath-mountedイベントを発生させる。ホットプラグデバイスやUSBデバイス(プリンタなど)の取り外しやインストールでイベントが発生することもある。initctlのemitコマンドを使えば手動でイベントを発生させることも可能だ。ジョブとはinitが読み込む一連の命令である。通常、こうした命令にはプログラム(バイナリファイルまたはシェルスクリプト)とイベントの名前が含まれている。イベントが発生すると、対応するプログラムがUpstartのinitデーモンによって実行されるわけだ。ジョブの実行と停止は、それぞれinitctlのstartおよびstopコマンドを使って手動で行うことができる。各ジョブはタスクやサービスごとに分けられている。タスクとはその作業を実行したうえで待ち状態に戻るジョブである。サービスとはそれ自身では正常に終了しないジョブである。logdデーモンやgettyはサービスとして実装されている。initデーモンは各サービスを監視していて、障害が発生したものを再起動し、イベントや手動操作によって停止したものを抹消する。/etc/event.dディレクトリには、ジョブ定義ファイル(Upstartのinitデーモンが実行するジョブを定義したファイル)が収められる。最初は、このディレクトリにUpstartのソフトウェアパッケージ群が入っている。Feisty以降のUbuntuリリースでは、なんらかのサービスをインストールすると、/etc/rc?.dおよび/etc/init.dの各ディレクトリに置かれていた管理用ファイルに代わって、そのサービスの新たな管理用ファイルがこのディレクトリに追加されるようになっている。基本的に、Upstartのinitデーモンはステートマシンである。各ジョブの状態を記憶していて、イベント発生に伴うジョブの状態変化を追跡する。initは、あるジョブの状態の変化を捉えてそのコマンドを実行したりジョブを終了させることができる。Vのinitデーモンでは、実行レベルの変化を利用してプロセスの起動/終了を行うタイミングが決められていた。Upstartのinitデーモンを使用するUbuntuシステムには、実行レベルの概念がない。実行レベルベースのシステムからイベントベースのシステムへの移行を容易にし、ほかのディストリビューション向けに作られたソフトウェアとの互換性を維持するために、UbuntuではUpstartを使って実行レベルのエミュレーションを行っている。/etc/event.d/rc?ファイル群によって定義されるrc?ジョブは、/etc/init.d/rcというスクリプトを実行する。このスクリプトは/etc/rc?.dディレクトリ内のリンクをたどって/etc/init.d内の対応するinitスクリプトを実行することで、SysVinit環境におけるこれらのリンクの機能をエミュレートしている。rc?の各ジョブはシステムがある実行レベルに移る際にこれらのスクリプトを実行する。システムがある実行レベルから抜ける際には一切動作しない。Upstartでは、SysVinitシステムとの互換性を考えてrunlevelおよびtelinitの各ユーティリティが実装されている。controlの意)を使えば、システム管理者はroot権限でUpstartのinitデーモンと通信できる。このユーティリティではジョブの開始、終了、レポート表示が行える。list」コマンドはジョブとその状態を一覧表示してくれる。4727なお、このセクションで紹介している例の詳細については、initctlのmanページを参照してもらいたい。help」(helpの前にハイフンは不要)というコマンドが使える。--help」とすればlistコマンドの詳細が表示され、「list」の部分をinitctlのほかのコマンドに置き換えればそのコマンドのヘルプ情報が表示される。start、stop、statusの各ユーティリティは同名のinitctl用コマンドを実行するinitctlへのリンクになっている。ジョブ/etc/event.dディレクトリ内の各ファイルは1つのジョブを定義したもので、その定義には通常、イベントとコマンドが最低1つずつ含まれている。イベントが発生するとinitによってそのコマンドが実行される。ここでは、管理者が定義したジョブとUpstartパッケージに付随するジョブの双方を例にとって解説を行う。管理者によって定義された次のジョブは、execキーワードを使ってシェルコマンドを実行している。このキーワードは、ファイル内に記述されたシェルスクリプトや実行可能なバイナリファイルの実行にも使える。2)に入ったときにシェルコマンドechoを実行するというタスクが定義されている。このコマンドにより、その時点の日時を含むメッセージが/tmp/mudat.outファイルに書き込まれる。シェル側は、substitutionコマンドを使ってdateユーティリティを実行する。このジョブの実行が終わると、mudatタスクは停止し、待ち状態に入る。list」コマンドによってこのタスクに関するレポートを表示するものだ(同様の情報はstatusユーティリティでも表示される)。waitingexecのコマンド行にシェルの特殊文字が含まれている場合、initは/bin/sh(dashにリンクされている)を実行したうえでコマンド行をこのシェルに渡す。その他の場合は、execによってコマンド行が直接実行される。script」(後述)を使用する。Upstartのinitデーモンで監視できるのは、execを使ってプログラムを実行するジョブ(サービス)だけである。script」を使って実行されているジョブは監視できない。サービスではexecを使う必要があるが、タスクではどちらの方法でもプログラムを実行できるわけだ。myjobサンプルイベントを定義し、そのイベントによってトリガされるジョブを設定することもできる。次のmyjobというジョブ定義ファイルは、hithereイベントによってトリガされるジョブを定義したものだ。scriptmyjobファイルは、複数のコマンドを実行するもう1つの方法を示している。script」の両キーワードの間に2つのコマンドが記されている。これらのキーワードを使うと、initは必ず/bin/shを実行する。その間に記されているコマンドは、メッセージと日付を/tmp/myjob.outというファイルに書き込むものだ。このジョブをトリガするには、initctlのemitコマンドが使える。次のinitctlは、このジョブをトリガした際にmyjobが通過する各段階を表示している。waitingこの例では、catがmyjobの生成する情報を出力し、initctlがそのジョブの状態を表示している。myjob」)というコマンドでも実行できる。initctlの「start」コマンドは、イベントを発生させずにジョブを実行したい場合に役立つ。2イベントを発生させることなく先ほどのmudatジョブを実行できるわけだ。イベントを発生させる。2というイベントを発生させる。これらのイベントは、次の構文を使ってジョブ定義の内部でマッチングを行うことができる。[arg]ここで「event」は「runlevel」のようなイベント、「arg」は省略可能な引数である。[!2]」は2を除くすべての実行レベルにマッチする。Upstartではイベント指定時に引数を省略することはできるが、ジョブ定義ファイルにおけるイベントの引数は実際にそのイベントに存在するものでなければならない。arg2」はどのrunlevelイベントにもマッチしない。runlevelイベントは1つしか引数を取らないからだ。initへの移行に伴い、/etc/event.dディレクトリに定義されるジョブの数は増えることになる。ここでは、Upstartパッケージによってこのディレクトリに置かれたジョブのいくつかを説明する。/etc/event.d/rc2というジョブ定義ファイルは、その他のrc?タスクによく似たrc2タスクを定義したものだ。[!2]」)に移ると停止する。スクリプトの最初の部分は、runlevelユーティリティを呼び出している。これにより、システムを実行レベル2に移行させ(Upstartには実際の実行レベルは存在しない)、2つの変数に値が割り当てられる。実際に作業を行うのはexecコマンドであり、2という引数を用いて/etc/init.d/rcスクリプトが実行される。このスクリプトは、/etc/rc?.dディレクトリから引数に対応したリンク先を呼び出す。この場合はrc2のタスクによって、/etc/rc2.dディレクトリ内のリンク先にあたるinitスクリプトが実行される。scriptttyサービス以下に示すのは、tty1のgettyプロセスを起動して監視するサービスのためのジョブ定義ファイルである。tty1このサービスは、実行レベルが2~5のいずれかのイベント発生時(つまり、システムがマルチユーザモードに入ったとき)にgettyプロセスを起動し、実行レベルが0、1、6のいずれかになったとき(つまり、システムのシャットダウン、シングルユーザモードへの移行、リブートが行われたとき)に停止する。「respawn」キーワードは終了時にジョブを再起動するようにinitに指示するものであり、「exec」はtt1のgettyプロセスをボーレート38,400で実行する。以下のinitctlはtty1サービスが起動されてプロセス4747として稼動中であることを、psはこのプロセスに関する情報をそれぞれ示している。tty1rc-defaultタスクとinittabSysVinitでは、/etc/inittabファイルの「initdefault」エントリを使って、システムの起動時にどの実行レベルに移るかをinitに対して指定する。Ubuntuではデフォルトの状態でinittabファイルが存在せず、Upstartのinitデーモンはブートしたシステムを(rc-defaultタスクを利用して)マルチユーザモード(デフォルトの実行レベル2)に移す。システムを別の実行レベルでブートさせたい場合には、inittabファイルを作成する。次のようにすれば、システムはシングルユーザモード(実行レベルS)でブートする。:id:S:initdefault:システムがシングルユーザ(リカバリ)モードになっていてrootアカウントのロックが解除されている場合は、initがrootプロンプトの表示前にrootパスワードの入力を求めてくる。それ以外の場合は、パスワードを入力しなくてもrootプロンプトが表示される。実行レベル0(停止)または6(再起動)ではシステムが正常に起動しないため、そのようなブート設定は行わないこと。マルチユーザモード(実行レベル2)でブートさせるには、inittabファイル(存在する場合)を削除するか、先ほどの例の「S」の部分を「2」で置き換えたinittabファイルを作成すればよい。