Handbook:Parts/Working/Initscripts/ja

システムの起動
システムが起動すると、たくさんのテキストが流れます. 注意して見ると、(通常) それが毎回同じ内容であることに気づくでしょう. これら全てのアクションの実行はブートシーケンスと呼ばれ、(ほぼ) 静的に定義されます.

まずブートローダーが、ブートローダーの設定で定義されたカーネルイメージを読み込みます. そしてブートローダーはCPUにカーネルを実行するよう指示します. カーネルが読み込まれ実行されると、全てのカーネル内の構造やタスクが初期化され、initプロセスを開始します.

このプロセスではまず ( に書かれた) すべてのファイルシステムをマウントし、使用可能な状態にします. そして に置かれたいくつかのスクリプトを実行します. これらのスクリプトは、システムのブートに必要なサービスを立ち上げます.

全てのスクリプトを実行したら、initは最後に端末 (ほとんどの場合 + や + などの下に隠された仮想端末ですが) を と呼ばれる特別なプロセスに接続します. このプロセスは login を実行することで各端末からユーザーがログオンできるようにします.

Initscripts
ところで、initは 内のスクリプトを適当に実行するわけではありません. それどころか、 内のスクリプトを全て実行するわけでもなく、指示されたスクリプトだけを実行します. 実行するスクリプトは を見て決定しています.

まずinitは にあるスクリプトのうち、 にシンボリックリンクが存在するものを全て実行します. 基本的にはアルファベット順に開始しますが、一部のスクリプトは自身の前に開始しなければならないスクリプトを示す依存情報を持っています.

から参照されている全てのスクリプトを実行すると、続けてinitは にシンボリックリンクが存在するスクリプトを実行します. 繰り返しになりますが、正しい起動シーケンスのために順序を変更する依存情報をスクリプトが持っていない限り、アルファベット順でスクリプトの実行順が決まります. これは Gentoo Linux のインストールで実行した などのコマンドで   を使った理由でもあります.

init の仕組み
もちろん、init 自身がこれらすべてを決定するわけではありません. どのような動作をすべきか指定する設定ファイルが必要です. この設定ファイルが です.

先ほど説明したブートシーケンスを思い出してください - init が最初にする動作はすべてのファイルシステムをマウントすることです. これは の以下の行で定義されています:

この行は init に対し、システムを初期化するために を実行するよう指示します. スクリプトが初期化を処理するので、init はあまり多くのことをしないと言えるかもしれません - システム初期化のタスクは他のプロセスに委譲しているのです.

第二に、init は にシンボリックリンクがあるすべてのスクリプトを実行します. これは以下の行で定義されています:

再び openrc スクリプトが必要なタスクを処理します. openrc に渡されるオプション(boot)が、使用する のサブディレクトリと同じであることに注目してください.

ここで、init はどのランレベルを実行すべきか見るために設定ファイルを調べます. これを決定するために から以下の行が読み込まれます:

この場合(Gentoo ユーザーの多くはこれを使用しています)、ランレベルの id は3です. この情報を使って、init はランレベル3を開始するために何を実行する必要があるかを調べます:

レベル3を定義している行では、サービスを開始するために再度 openrc を(今度は引数  とともに)使用しています. 今回も openrc の引数が のサブディレクトリと同じであることに注目してください.

openrc が終了すると、init はどの仮想コンソールを有効化すべきか、また各コンソールでどのコマンドを実行しなければならないかを決定します:

有効なランレベル
前の節では、init がどのランレベルを有効化するか決めるために番号を用いていることを説明しました. ランレベルはシステムが動作する際の状態であり、ランレベルを開始したり終了したりした時に実行されるスクリプト(ランレベルスクリプトあるいは init スクリプト)の一群を含んでいます.

Gentoo では7つのランレベルが定義されています: 3つの内部ランレベルと4つのユーザー定義ランレベルです. 内部ランレベルはそれぞれ sysinit、shutdown そして reboot と呼ばれており、まさに名前が示す通りに動作します: システムの初期化、システムのパワーオフ、そしてシステムの再起動を行うのです.

ユーザー定義ランレベルはそれぞれ付随する のサブディレクトリーを持ちます: boot、default、nonetwork そして single です. boot ランレベルは、他のランレベルによって使用される、システムに必要なすべてのサービスを起動します. 残りの3つのランレベルは開始するサービスに違いがあります: default は日常的な作業に使われ、nonetwork は一切のネットワーク接続が不要な場合に使われ、そして single はシステムを修復する必要がある時に使われます.

init スクリプトの使い方
openrc プロセスが開始するスクリプトは init スクリプトと呼ばれます. 内の各スクリプトは 、 、 、 、 、 、 、 、 、  あるいは   という引数で実行することができます.

サービス(およびすべての依存サービス)を開始、停止、あるいは再起動するには、 、 および   引数を使います:

あるサービスを停止するが依存サービスは停止させたくない場合には、 引数とともに   オプションも使用します:

サービスがどのような状態にあるか(started、stopped、 ...)見るには  引数を使用します:

サービスが実行中であるというステータス情報が表示されたのに実際はそうでない場合には、 引数を使用してステータス情報を "stopped" にリセットします:

サービスがどのような依存関係を持っているか問い合わせるには、 、 あるいは   引数を使用します. を使うとそのサービスが正しく機能するために本当に必要なサービスが表示されます. 一方  や   は、そのサービスから使用することができるけれども、正しく機能する上で必要というわけではないサービスを表示します.

同じように、そのサービスを必要としているサービスやそのサービスを使用できるサービス( または  )を問い合わせることもできます:

rc-update
Gentoo の init システムはまずどのサービスを開始する必要があるかを決めるために依存関係ツリーを使用しています. これはユーザーに手動でやってもらうには退屈な作業なので、ランレベルや init スクリプトの管理を簡略化するツールが作成されました.

を使って init スクリプトをランレベルに追加したり削除することができます. ツールはその後自動的に スクリプトを使って依存関係ツリーを再構築します.

サービスの追加と削除
これまでの説明では init スクリプトはすでに "default" ランレベルに追加されていました. "default" の意味するところはこの文書の前の方で説明しました. ランレベルの他に、 スクリプトは動作を定義する第二の引数を必要とします: 、  または   です.

init スクリプトを追加または削除するには、 に  または   引数、その後に init スクリプトとランレベルを渡します. 一例:

コマンドは利用可能なすべての init スクリプトと、それらが実行されるランレベルの一覧を出力します:

を( 引数なしで)実行して有効になっている init スクリプトとそのランレベルのみを表示させることもできます.

追加の設定が必要な理由
init スクリプトはとても複雑です. したがって、ユーザーに init スクリプトを直接編集してもらうのは間違いを起こしやすくなり必ずしも合理的ではありません. しかしながら、サービスを設定できるということは重要です. たとえば、ユーザーがサービス自体により多くのオプションを渡したい場合があるでしょう.

A second reason to have this configuration outside the init script is to be able to update the init scripts without the fear that the user's configuration changes will be undone.

conf.d ディレクトリ
Gentoo provides an easy way to configure such a service: every init script that can be configured has a file in. For instance, the initscript (called ) has a configuration file called, which can contain the options to give to the Apache 2 server when it is started:

Such a configuration file contains only variables (just like does), making it very easy to configure services. It also allows us to provide more information about the variables (as comments).

Is it necessary?
No, writing an init script is usually not necessary as Gentoo provides ready-to-use init scripts for all provided services. However, some users might have installed a service without using Portage, in which case they will most likely have to create an init script.

Do not use the init script provided by the service if it isn't explicitly written for Gentoo: Gentoo's init scripts are not compatible with the init scripts used by other distributions! That is, unless the other distribution is using OpenRC!

レイアウト
The basic layout of an init script is shown below.

Every init script requires the  function or   variable to be defined. All other sections are optional.

依存関係
There are three dependency-alike settings that can be defined which influence the start-up or sequencing of init scripts:,   and. Next to these, there are also two order-influencing methods called  and. These last two are no dependencies per se - they do not make the original init script fail if the selected one isn't scheduled to start (or fails to start).


 * The  settings informs the init system that this script uses functionality offered by the selected script, but does not directly depend on it. A good example would be   or  . If those services are available, they will be put in good use, but if the system does not have a logger or DNS server the services will still work. If the services exist, then they are started before the script that uses them.
 * The  setting is similar to   with one exception.    only considers services which were added to an init level.   will try to start any available service even if not added to an init level.
 * The  setting is a hard dependency. It means that the script that is needing another script will not start before the other script is launched successfully. Also, if that other script is restarted, then this one will be restarted as well.
 * When using, then the given script is launched before the selected one if the selected one is part of the init level. So an init script xdm that defines   will start before the alsasound script, but only if alsasound is scheduled to start as well in the same init level. If alsasound is not scheduled to start too, then this particular setting has no effect and xdm will be started when the init system deems it most appropriate.
 * Similarly,  informs the init system that the given script should be launched after the selected one if the selected one is part of the init level. If not, then the setting has no effect and the script will be launched by the init system when it deems it most appropriate.

It should be clear from the above that  is the only "true" dependency setting as it affects if the script will be started or not. All the others are merely pointers towards the init system to clarify in which order scripts can be (or should be) launched.

Now, look at many of Gentoo's available init scripts and notice that some have dependencies on things that are no init scripts. These "things" we call virtuals.

A virtual dependency is a dependency that a service provides, but that is not provided solely by that service. An init script can depend on a system logger, but there are many system loggers available (metalogd, syslog-ng, sysklogd, ...). As the script cannot need every single one of them (no sensible system has all these system loggers installed and running) we made sure that all these services provide a virtual dependency.

For instance, take a look at the postfix dependency information:

As can be seen, the postfix service:


 * Requires the (virtual) net dependency (which is provided by, for instance, ).
 * Uses the (virtual) logger dependency (which is provided by, for instance, ).
 * Uses the (virtual) dns dependency (which is provided by, for instance, ).
 * Provides the (virtual) mta dependency (which is common for all mail servers).

順序の制御
As described in the previous section, it is possible to tell the init system what order it should use for starting (or stopping) scripts. This ordering is handled both through the dependency settings use and need, but also through the order settings before and after. As we have described these earlier already, let's take a look at the portmap service as an example of such init script.

It is possible to use the "*" glob to catch all services in the same runlevel, although this isn't advisable.

If the service must write to local disks, it should need localmount. If it places anything in such as a pidfile, then it should start after bootmisc:

標準関数
Next to the  functionality, it is also necessary to define the   function. This one contains all the commands necessary to initialize the service. It is advisable to use the  and   functions to inform the user about what is happening:

Both  and   should be used in start and stop functions. If the service does not create a pidfile, then use  if possible, though it is recommended to test this to be sure. Otherwise, don't use pidfiles. It is also possible to add  to the start-stop-daemon options, but this is not recommended unless the service is extremely verbose. Using  may hinder debugging if the service fails to start.

Another notable setting used in the above example is to check the contents of the RC_CMD variable. Unlike the previous init script system, the newer OpenRC system does not support script-specific restart functionality. Instead, the script needs to check the contents of the RC_CMD variable to see if a function (be it  or  ) is called as part of a restart or not.

For more examples of the  function, please read the source code of the available init scripts in the  directory.

Another function that can (but does not have to) be defined is. The init system is intelligent enough to fill in this function by itself if start-stop-daemon is used.

If the service runs some other script (for example, Bash, Python, or Perl), and this script later changes names (for example, to foo), then it is necessary to add   to start-stop-daemon. This must specify the name that the script will be changed to. In this example, a service starts, which changes names to foo:

start-stop-daemon has an excellent man page available if more information is needed:

Gentoo's init script syntax is based on the POSIX Shell so people are free to use sh-compatible constructs inside their init scripts. Keep other constructs, like bash-specific ones, out of the init scripts to ensure that the scripts remain functional regardless of the change Gentoo might do on its init system.

カスタムオプションの追加
If the initscript needs to support more options than the ones we have already encountered, then add the option to one of the following variables, and create a function with the same name as the option. For instance, to support an option called :


 * extra_commands - Command is available with the service in any state
 * extra_started_commands - Command is available when the service is started
 * extra_stopped_commands - Command is available when the service is stopped

Service configuration variables
In order to support configuration files in, no specifics need to be implemented: when the init script is executed, the following files are automatically sourced (i.e. the variables are available to use):



Also, if the init script provides a virtual dependency (such as net), the file associated with that dependency (such as ) will be sourced too.

Who might benefit
Many laptop users know the situation: at home they need to start net.eth0, but they don't want to start net.eth0 while on the road (as there is no network available). With Gentoo the runlevel behaviour can be altered at will.

For instance, a second "default" runlevel can be created which can be booted that has other init scripts assigned to it. At boottime, the user can then select what default runlevel to use.

softlevel を使う
First of all, create the runlevel directory for the second "default" runlevel. As an example we create the offline runlevel:

Add the necessary init scripts to the newly created runlevel. For instance, to have an exact copy of the current default runlevel but without net.eth0:

Even though net.eth0 has been removed from the offline runlevel, udev might want to attempt to start any devices it detects and launch the appropriate services, a functionality that is called hotplugging. By default, Gentoo does not enable hotplugging.

To enable hotplugging, but only for a selected set of scripts, use the rc_hotplug variable in :

Edit the bootloader configuration and add a new entry for the offline runlevel. In that entry, add  as a boot parameter.

bootlevel を使う
Using bootlevel is completely analogous to softlevel. The only difference here is that a second "boot" runlevel is defined instead of a second "default" runlevel.