3.1. システムの起動のプロセスとカスタマイズ
3.1.1. ブートからカーネル起動まで
電源起動からシステム化起動するまで以下のようなフローとなる。
BIOS/UEFI => ブートローダ => カーネル
BIOS/UEFI
BIOS/UEFIはマザーボードに焼き付けられた基本的な制御プログラムで、基本的な入出力管理を行う。
重要な動作としては起動デバイスのマスターブートレコードに格納されたブートローダを実行することがある。
- BIOSのブートプロセス … BIOS → MBRのブートローダ → カーネル → init
- UEFIのブートプロセス … UEFI → ESP(のブートローダ) → カーネル → init
UEFI
UEFIは以下の要素から構成される。
| 要素 | 説明 | 
|---|---|
| EFI System Partition (ESP) | UEFIシステムにおける物理的なマシンを起動、ファームウエアが読み込まれた後の起動シーケンスで最初にアクセスされる領域。 /boot/efiにマウントされFAT16またはFAT32でフォーマットされている必要がある | 
| UEFIブートマネージャ | 起動情報(OSをどこからどのようにロードするか)を管理するプログラム | 
| efibootmgr | UEFIブートマネージャーの起動エントリをOS上から操作するコマンド | 
MBR/GPT
BIOSでは起動デバイスの最初のセクタであるMBR(マスターブートレコード)でパーティションを管理する。
UEFIではGPTでパーティションを管理する。
GPTでは起動ドライブに2TB以上割り当てることができる特徴があり、またブートローダはESPに格納される。 UEFIシステムパーティションではFATまたはVFATでフォーマットされる。
ブートローダ
ブートローダはマスターブートレコードに格納されて部分(第1部分)とそこから呼び出される部分(第2部分)に分かれている。
動作としては第1部分が第2部分のブートローダをロードしそれを起動する。また第2部分のブートローダは指定したパーティションからカーネルをロードし制御を移す。
Linuxで使用されるブートローダにはGRUB Legacy、GRUB2がある。
カーネル
カーネルはinit(/sbin/init)を起動するもので、その過程で以下処理を行う。
- 組み込まれたハードウェアの検出
- メモリの初期化
- システムクロックの設定
- IRQの設定
- ルートパーティションのマウント
またカーネル起動中のメッセージはdmesgコマンドで確認可能。
3.1.2. SysVinitの概要
サービスが起動する仕組みはこれまでSysVinitが主流であったが、現在ではSystemdという仕組みが主流となっている。
SysVinit
SysVinitではLinuxシステムで最初に実行されるinitが/etc/inittabに従いシステムに必要なサービスを順次起動するものであった。
initのPIDは1番となりすべてのプロセスはinitの子プロセス/孫プロセスとなる。
起動のプロセスは以下の通り。
- initが/etc/inittabを読み込む
- initが/etc/rc.sysinitを読み込む
- initが/etc/rcを実行する
- /etc/rcが- /etc/rcN.d(Nはランレベル)ディレクトリ以下のスクリプトを実行する
なお/etc/inittabの書式は以下の通り。
1:1245:respawn:/sbin/mingetty tty2- 1 … ID
- 1245 … ランレベル
- respawn … アクション指示子
- /sbin/migetty tty2 … 処理
アクション指示子は以下の通り。
| アクション指示子 | 意味 | 
|---|---|
| boot | システム起動時に実行され、プロセスの終了を待たずに次の処理を実行 | 
| bootwait | システム起動時に一度実行され、プロセスが終了するまで次の処理を行わない | 
| ctrlaltdel | Ctrl,Alt,Deleteキーが同時に押されるSIGINTがinitに送られた場合に実行する | 
| initdefault | デフォルトのランレベルを指定する | 
| once | 指定したランレベルになったときに一度だけ実行され、プロセスの終了を待たずに次の処理を行う | 
| respawn | プロセスが終了すれば再起動させる | 
| sysinit | システム起動時にbootやbootwaitより先に実行 | 
| wait | 指定したランレベルになった時に1度のみ実行し、プロセス終了まで次の処理はしない | 
3.1.3. 起動スクリプトとランレベル
起動されるスクリプトはランレベルごとに異なる。
ランレベルごとに用意されているサービスは/etc/rc[0-6].dで確認できる。
サービスの起動は以下の書式の通り。
/etc/init.d/[サービス名] [コマンド]起動スクリプトの主なコマンドは以下の通り。
| コマンド | 説明 | 
|---|---|
| start | サービスの開始 | 
| stop | サービスの停止 | 
| restart | サービスの再起動 | 
| condrestart | サービスが起動している場合のみ再起動 | 
| status | 情報を表示する | 
なお各ランレベルに応じたスクリプトは/etc/rc[0-6].dに入っており、以下のようなファイル名となる。
S55sshd
K15httpdSは起動、Kは終了を意味する。
数字は実行順序、残りはサービス名を表す。
なおK→Sの順で実行される。
デフォルトのランレベル
SysVinitを採用したシステムでは以下の方法でデフォルトランレベルの指定ができる。
- /etc/inittab
- ブートローダの設定ファイルでのカーネル起動時に渡すコマンドラインパラメータ
serviceコマンド
RedHat系OSやUbuntuでは/etc/init.d/の代わりにserviceコマンドを使用できる場合がある。
具体的にはRed Hat(6.xまで)系ディストリビューションで使用できる。
service [サービス名] [コマンド]LSB
LSB(Linux Standard Base)はLinuxの内部構造を標準化するプロジェクト。
LSBでは以下仕様が決められている。
- コマンド/標準ライブラリ
- ファイルシステム階層構造
- 印刷システム
- X Window System
確認は以下コマンドで可能。
lsb_release -a3.1.4. サービスの自動起動
ランレベルごとにサービスをデフォルトで起動させるもしくはさせないようにするには以下のような手法がある。
- 手動でリンクを作成する
- chconfigコマンドでの設定
- update-rc.dコマンドでの設定
手動でリンクを作成
手動でリンクを作成するには/etc/rc[0-6].d以下に、自動に起動させたいサービスのシンボリックリンクの作成することで設定ができる。
chkconfigコマンド
chkconfigコマンドはRed Hat系(6.xまで)ディストリビューションで使用できるコマンド。
サービスの自動起動を設定することができる。
chkconfig [オプション] [サービス名] [on | off]| オプション | 説明 | 
|---|---|
| –list | サービスの自動起動設定をランレベルごとに表示する | 
| –level レベル | ランレベルを指定する | 
| –add | サービスの追加登録をする | 
| -del | サービスを削除する | 
update-rc.dコマンド
update-rc.dコマンドはDebian系ディストリビューションで使用できるコマンド。
サービスの自動起動を設定することができる。
- 自動起動設定を追加・削除できる
- 優先順位を指定することができる
具体的にはランレベルごとにシンボリックリンクの作成/削除を行うことで実現する。
update-rc.d [オプション] [サービス名] remove
update-rc.d [オプション] [サービス名] [defaults] [NW | SNN kNN]
update-rc.d [オプション] [サービス名] start | stop NN ランレベル| オプション | 説明 | 
|---|---|
| -n | 表示するだけ何もしない | 
| -f | /etc/init.dにスクリプトがあっても強制的にシンボリックリンクを削除する | 
| remove | 起動スクリプトのシンボリックリンクを削除する | 
| defaults | デフォルトのスクリプトを作成する | 
| start | 起動用のスクリプト(S)を作成する | 
| stop | 停止用のスクリプト(K)を作成する | 
| NN | 0~99の数字 | 
intsservコマンド
intsservコマンドはSUSE系やVer6.0以降のDebian系のディストリビューションで使用できるコマンド。
サービスの自動起動を設定することができる。
insserv [オプション] [サービス名] # 自動起動設定
insserv -r [オプション] [サービス名] # 指定したサービスの自動起動を止める3.1.5. systemdの概要
systemdの採用システムではinitプロセスの代わりにsystemdプロセスが起動しサービスを管理する。
systemdでは以下デーモンが連携して動作する。
| プロセス | 説明 | 
|---|---|
| systemd | メインプロセス | 
| systemd-journal | ジャーナル管理プロセス | 
| systemd-logind | ログイン処理プロセス | 
| systemd-udevd | デバイス動的検知プロセス | 
systemdではシステムの処理は多数のUnitという処理単位で別れる。 Unitはいくつか種類があり、以下のような種類がある。
| 種類 | 説明 | 
|---|---|
| service | 各種サービスの起動 | 
| device | 各種デバイスを表す | 
| mount | ファイルシステムをマウントする | 
| swap | スワップ領域を有効にする | 
| target | 複数のUnitをグループ化する | 
systemdの特徴は起動順序関係やサービスの依存関係を処理できることがある。 そのためシステム起動速度もSysVinitより速くなる。
systemdの起動順序
systemdではシステムが起動するとdefault.targetというUnitが処理される。
これは/etc/systemd/system/以下にある。
デフォルトのターゲットにシンボリックリンクを作成することで、デフォルトの起動方法を設定できる。
# グラフィカルログインの起動構成の例
ln -sf /lib/systemd/system/graphical.target /etc/systemd/system/default.target| ランレベル | ターゲット | 
|---|---|
| 0 | poweroff.target | 
| 1 | rescue.target | 
| 2,3,4 | multi-user.target | 
| 5 | graphical.target | 
| 6 | reboot.target | 
systemdのディレクトリ
| ディレクトリ | 説明 | 優先順位 | 
|---|---|---|
| /usr/lib/systemd/system | 永続的なユニット・ターゲットの定義ファイルが置かれるディレクトリ | - | 
| /etc/systemd/system | カスタム用のディレクトリ | 優先度が高い | 
| /run/systemd/system | 再起動されると削除される | /usr/lib/systemd/systemより高い | 
systemctlコマンド
systemdでサービスを管理するコマンドがsystemctlコマンドとなる。
systemctl [サブコマンド] [Unit名] [-t 種類]| サブコマンド | 説明 | 
|---|---|
| start | サービスを起動する | 
| stop | サービスを終了する | 
| restart | サービスを再起動する | 
| reload | サービス設定の再読み込みをする | 
| status | サービス稼働状況の確認 | 
| is-active | サービスが稼働状態か確認する | 
| enable | システム起動時にサービスを自動起動する | 
| disable | システム起動時にサービスを自動起動しない | 
| list-units | 起動しているUnitを表示する | 
| list-unit-files | すべてのUnitを表示する | 
| list-dependencies | 指定したサービスが必要とするUnitを表示する | 
| get-default | デフォルトターゲットを確認 | 
| set-default | デフォルトターゲットを設定する | 
| isolate | 他のUnitを停止して対象のUnitを起動 | 
systemd-deltaコマンド
systemd-deltaコマンドはデフォルトの定義ファイルを上書きしている場合などにどのファイルがどのように影響を受けているか確認できるコマンド。
同じファイル名のユニット、ターゲットの定義ファイルが複数あり、上図のディレクトリの優先度に基づいてファイルを上書きした場合などに使用する。
systemd-deltaUnit設定ファイル
Unit設定ファイルは/etc/systemd/systemディレクトリ以下に配置される。
Unit設定ファイルはUnit、Service、Installのセクションに分かれる。
ファイルの構成は以下例のようになる。
[Unit]
Descriptions=HogeHoge
After=syslog.target network.target
Conflicts=sendmail.service exim.service
[Service]
Type=forking
:
[Install]
WantedBy=multi-user.target主なUnit設定ファイルのパラメータは以下の通り。
| パラメータ | 説明 | 
|---|---|
| Description | Unitの説明 | 
| Documentation | ドキュメントの場所 | 
| After | ここに書かれたUnit以降に起動する | 
| Before | ここに書かれたUnit以前に起動する | 
| Wants | ここに書かれたUnitが必要 | 
| Type | サービスのタイプ(simple, forking, oneshot, notify, dbus) | 
| ExecStartPre | startでの実行前に実行するコマンド | 
| ExecStart | startで実行するコマンド | 
| ExecReload | reloadで実行するコマンド | 
| ExecStop | stopで実行するコマンド | 
| WantedBy | systemctl enable | 
| RequiredBy | systemctl enable | 
systemdのログ
systemdを採用したシステム下ではjournalctlコマンドによりsystemdのログが確認可能。
journalctl [オプション]| オプション | 説明 | 
|---|---|
| -f | 末尾のログを表示し続ける | 
| -n 行数 | 指定した行数だけログの末尾を表示 | 
| -p [priolity] | メッセージがpriority以上のものだけ表示 | 
| -r | ログを新しい順に表示 | 
| -u Unit名 | 指定したUnitを表示 | 
| -full | プレーンテキストで表示 | 
| –no-pager | すべてのログを表示する |