第3章 システムの初期化

目次

3.1. ブートストラッププロセスの概要
3.1.1. 1段目: UEFI
3.1.2. 2段目: ブートローダー
3.1.3. 3段目: ミニ Debian システム
3.1.4. 4段目: 通常の Debian システム
3.2. Systemd init
3.2.1. ホスト名
3.2.2. ファイルシステム
3.2.3. ネットワークインターフェースの初期化
3.3. カーネルメッセージ
3.4. システムメッセージ
3.5. System management
3.6. Other system monitors
3.7. systemd のカスタム化
3.7.1. ソケットの起動
3.8. udev システム
3.8.1. カーネルモジュール初期化

Debian システムが以下に起動され設定されるかの知っていることはシステム管理者として賢明です。正確で詳細な情報がインストールされたパッケージのソースや文書中にあるとは言え、我々の大部分にとってはちょっと大変過ぎます。

Here is a rough overview of the key points of the Debian system initialization. Since the Debian system is a moving target, you should refer to the latest documentation.

コンピューターシステムは、電源投入イベントからユーザーに機能の完備したオペレーティングシステム (OS) を提供するまでブートストラッププロセスを数段通過します。

単純化のため、デフォールトのインストールをした典型的な PC プラットフォームに限定し議論します。

典型的なブートストラッププロセスは4段ロケットのようです。各段のロケットは次の段のロケットにシステムのコントロールを引き継ぎます。

もちろん、これらに関して異なる設定をすることはできます。例えば、自分自身で専用カーネルをコンパイルした場合、ミニ Debian システムのステップをスキップできます。自分自身で確認するまでは、あなたのシステムがこの様になっていると決めつけないで下さい。

The Unified Extensible Firmware Interface (UEFI) defines a boot manager as part of the UEFI specification. When a computer is powered on, the boot manager is the 1st stage of the boot process which checks the boot configuration and based on its settings, then executes the specified OS boot loader or operating system kernel (usually boot loader). The boot configuration is defined by variables stored in NVRAM, including variables that indicate the file system paths to OS loaders or OS kernels. An EFI system partition (ESP) is a data storage device partition that is used in computers adhering to the UEFI specification. Accessed by the UEFI firmware when a computer is powered up, it stores UEFI applications and the files these applications need to run, including operating system boot loaders. (On the legacy PC system, BIOS stored in the MBR may be used instead.)

ブートローダーは UEFI によって起動されるブートプロセスの2段目です。それはシステムのカーネルイメージと initrd イメージをメモリーにロードし、それらにコントロールを引き継ぎます。この initrd イメージはルートファイルシステムイメージで、そのサポートは使われるブートローダーによります。

The Debian system normally uses the Linux kernel as the default system kernel. The initrd image for the current 5.x Linux kernel is technically the initramfs (initial RAM filesystem) image.

多くのブートローダと設定オプションが利用可能です。


[警告] 警告

grub-rescue-pc パッケージのイメージから作ったブート可能なレスキューメディア (CD かフロッピー) 無しにブートローダーを試してはいけません。これさえあると、ハードディスク上に機能するブートローダーが無くともシステムの起動ができます。

For UEFI system, GRUB2 first reads the ESP partition and uses UUID specified for search.fs_uuid in "/boot/efi/EFI/debian/grub.cfg" to determine the partition of the GRUB2 menu configuration file "/boot/grub/grub.cfg".

The key part of the GRUB2 menu configuration file looks like:

menuentry 'Debian GNU/Linux' ... {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        search --no-floppy --fs-uuid --set=root fe3e1db5-6454-46d6-a14c-071208ebe4b1
        echo    'Loading Linux 5.10.0-6-amd64 ...'
        linux   /boot/vmlinuz-5.10.0-6-amd64 root=UUID=fe3e1db5-6454-46d6-a14c-071208ebe4b1 ro quiet
        echo    'Loading initial ramdisk ...'
        initrd  /boot/initrd.img-5.10.0-6-amd64
}

For this part of /boot/grub/grub.cfg, this menu entry means the following.


[ヒント] ヒント

You can enable to see kerrnel boot log messages by removing quiet in "/boot/grub/grub.cfg". For the persistent change, please edit "GRUB_CMDLINE_LINUX_DEFAULT="quiet"" line in "/etc/default/grub".

[ヒント] ヒント

You can customize GRUB splash image by setting GRUB_BACKGROUND variable in "/etc/default/grub" pointing to the image file or placing the image file itself in "/boot/grub/".

"info grub" と grub-install(8) を参照下さい。

ミニ Debian システムはブートローダーによって起動されるブートプロセスの3段目です。メモリー上でルートファイルシステムとともにシステムカーネルを実行します。これはオプションの起動プロセスの準備段階です。

[注記] 注記

"ミニ Debian システム" は著者がこの3段目のブートプロセスを本文書中で記述するために作った言葉です。このシステムは一般に initrd とか initramfs システムと呼ばれています。類似のメモリー上のシステムは Debian インストーラーでも使われています。

"/init" スクリプトはこのメモリー上のルートファイルシステムで最初に実行されるプログラムです。それはユーザー空間でカーネルを初期化し次の段階にコントロールを引き継ぐプログラムです。このミニ Debian システムは、メインのブートプロセスが始まる前にカーネルモジュールを追加したり、ルートファイルシステムを暗号化されたファイルシステムとしてマウントする等のブートプロセスの柔軟性を提供します。

  • initramfs-tools で initramfs が作成された場合には "/init" プログラムはシェルプログラムです。

    • "break=init" 等をカーネルブートパラメーターとして与えると、本部分のブートプロセスに割り込み root シェルを獲得できます。この他の割り込み条件は "/init" スクリプトを参照下さい。このシェル環境はあなたの機器のハードウエアーを詳細に検査できるだけ十分洗練されています。

    • このミニ Debian システムで利用可能なコマンドは機能を削ったコマンドで、主に busybox(1) という GNU ツールで提供されます。

  • dracut で initramfs が作成された場合には "/init" プログラムはバイナリーの systemd プログラムです。

    • このミニ Debian システムで利用可能なコマンドは機能を削った systemd(1) 環境です。

[注意] 注意

読出しのみのルートファイルシステム上では、mount コマンドには "-n" オプションを使う必要があります。

通常の Debian システムはミニ Debian システムによって起動されるブートプロセスの4段目です。ミニ Debian システムのシステムカーネルはこの環境ででも実行され続けます。ルートファイルシステムはメモリー上から本当にハードディスク上にあるファイルシステムに切り替えられます。

多くのプログラムを起動する主ブートプロセスを行う init プログラムは、PID=1 で最初のプログラムとして実行されます。init プログラムのデフォールトのファイルパスは "/sbin/init" ですが、"init=/path/to/init_program" のようなカーネルブートパラメーターにより変更できます。

Debian 8 jessie (2015年リリース) 以降では "/sbin/init" は "/lib/systemd/systemd" にシムリンクされています。

[ヒント] ヒント

あなたのシステム上の実際の init コマンドは "ps --pid 1 -f" コマンドで確認できます。


[ヒント] ヒント

ブートプロセスを高速化する最新のティップは Debian wiki: BootProcessSpeedup を参照下さい。

このセクションは PID=1 (詰まり、init プロセス)の systemd(1) プログラムがどのようにシステムを起動するのかを説明します。

The systemd init process spawns processes in parallel based on the unit configuration files (see systemd.unit(5)) which are written in declarative style instead of SysV-like procedural style.

The spawned processes are placed in individual Linux control groups named after the unit which they belong to in the private systemd hierarchy (see cgroups and 「Linux のセキュリティ機能」).

The unit configuration files are loaded from a set of paths (see systemd-system.conf(5)) as follows:

  • "/lib/systemd/system": OS のデフォルトの設定ファイル

  • "/etc/systemd/system": OS デフォルト設定ファイルをオーバーライドするシステム管理者設定ファイル

  • "/run/systemd/system": OS デフォルト設定ファイルをオーバーライドする実行時生成される設定ファイル

相互依存関係は "Wants="、"Requires="、"Before="、"After="、 … ("MAPPING OF UNIT PROPERTIES TO THEIR INVERSES" in systemd.unit(5) 参照) 等の指示定義によって規定される。リソースのコントロールは (systemd.resource-control(5) 参照)によっても定義される。

unit 設定ファイルのサッフィックスにそのタイプを折込みます:

  • *.servicesystemd がコントロールしたりスーパーバイズするプロセスを記述します。systemd.service(5) 参照ください。

  • *.devicesysfs(5) 中に udev(7) デバイスツリーとして暴露されるデバイスを記述します。See systemd.device(5) を参照ください。

  • *.mountsystemd がコントロールしたりスーパーバイズするファイルシステムのマウントポイントを 記述します。systemd.mount(5) を参照ください。

  • *.automountsystemd がコントロールしたりスーパーバイズするファイルシステムの自動マウントポイントを 記述します。systemd.automount(5) を参照ください。

  • *.swapsystemd がコントロールやスーパーバイズするスワップデバイスやファイルを 記述します。systemd.swap(5) を参照ください。

  • *.pathsystemd がパス基準で起動するために監視するパスを 記述します。systemd.path(5) を参照ください。

  • *.socketsystemd がソケット基準で起動するためにコントロールしたりスーパーバイズするソケットを 記述します。systemd.socket(5) を参照ください。

  • *.timersystemd がタイマー基準で起動するためにコントロールしたりスーパーバイズするタイマーを 記述します。systemd.timer(5) を参照ください。

  • *.slicecgroups(7) でリソースを管理します。systemd.slice(5) を参照ください。

  • *.scope はシステムプロセスの集合を systemd のバスインターフェースを用いて管理するためにプログラムで作られます。systemd.scope(5) を参照ください。

  • *.target は他の unit設定ファイルを組み合わせて始動時同期点を作ります。systemd.target(5) を参照ください。

システムの始動 (init) されると systemd プロセスは (通常 "graphical.target" にシムリンクされている) "/lib/systemd/system/default.target を起動しようとします。. 最初に、"local-fs.target" や "swap.target" や "cryptsetup.target" 等のいくつかの特殊ターゲット unit (systemd.special(7) 参照) が引き込まれファイルシステムをマウントします。そして、他のターゲット unit が、ターゲット unit の依存関係で引き込まれます。詳細に関しては bootup(7) を読んで下さい。

systemd はバックワードコンパティビリティー機能を提供します。"/etc/init.d/rc[0123456S].d/[KS]name" 中の、SysV-スタイルのブートスクリプトは依然として読み込まれ処理されますし、telinit(8) は systemd の unit 有効化要求に変換されます。

[注意] 注意

擬似実装された runlevel の 2 から 4 は、すべて同じ "multi-user.target" にシムリンクされます。

通常のディスクやネットワークのファイルシテムのマウントオプションは "/etc/fstab" で設定されます。fstab(5) と 「マウントオプションによるファイルシステムの最適化」を参照下さい。

暗号化されたファイルシステムの設定は "/etc/crypttab" で設定されます。crypttab(5) を参照ください。

mdadm(8) を用いるソフトウエアー RAID は "/etc/mdadm/mdadm.conf" で設定されます。mdadm.conf(5) を参照ください。

[警告] 警告

各ブートアップごとに、全てのファイルシステムをマウントした後で、"/tmp" と "/var/lock" と "/var/run" 中の一時ファイルはクリーンされます。

コンソールに表示されるカーネルのエラーメッセージは、その閾値て設定できる。

# dmesg -n3

Under systemd, both kernel and system messages are logged by the journal service systemd-journald.service (a.k.a journald) either into a persistent binary data below "/var/log/journal" or into a volatile binary data below "/run/log/journal/". These binary log data are accessed by the journalctl(1) command. For example, you can display log from the last boot as:

$ journalctl -b

Under systemd, the system logging utility rsyslogd(8) may be uninstalled. If it is installed, it changes its behavior to read the volatile binary log data (instead of pre-systemd default "/dev/log") and to create traditional permanent ASCII system log data. This can be customized by "/etc/default/rsyslog" and "/etc/rsyslog.conf" for both the log file and on-screen display. See rsyslogd(8) and rsyslog.conf(5). See also 「ログアナライザー」.

The systemd offers not only init system but also generic system management operations with the systemctl(1) command.

表3.6 List of typical systemctl command snippets

操作 コマンド断片
全ターゲットユニット設定をリスト "systemctl list-units --type=target"
全サービスユニット設定をリスト "systemctl list-units --type=service"
全ユニット設定タイプをリスト "systemctl list-units --type=help"
メモリー中の全ソケット unit のリスト "systemctl list-sockets"
メモリー中の全タイマー unit のリスト "systemctl list-timers"
"$unit" 始動 "systemctl start $unit"
"$unit" 停止 "systemctl stop $unit"
サービス特定の設定の再ロード "systemctl reload $unit"
"$unit" 停止と始動 "systemctl restart $unit"
"$unit" 始動と、他全ての停止 "systemctl isolate $unit"
"graphical" に切り替え(GUI システム) "systemctl isolate graphical"
"multi-user" に切り替え(CLI システム) "systemctl isolate multi-user"
"rescue" に切り替え(シングルユーザー CLI システム) "systemctl isolate rescue"
"$unit" に kill 信号を送る "systemctl kill $unit"
"$unit" サービスがアクティブかを確認 "systemctl is-active $unit"
"$unit" サービスが失敗かを確認 "systemctl is-failed $unit"
"$unit|$PID|device" の状態を確認 "systemctl status $unit|$PID|$device"
"$unit|$job" の属性を表示 "systemctl show $unit|$job"
失敗した "$unit" をリセット "systemctl reset-failed $unit"
全ての unit サービスの依存関係をリスト "systemctl list-dependencies --all"
システムにインストールされた unit ファイルをリスト "systemctl list-unit-files"
"$unit" を有効にする(symlink 追加) "systemctl enable $unit"
"$unit" を無効にする(symlink 削除) "systemctl disable $unit"
"$unit" のマスクを外す("/dev/null" へのsymlink を削除) "systemctl unmask $unit"
"$unit" にマスクをかける("/dev/null" へのsymlink を追加) "systemctl mask $unit"
デフォールトのターゲット設定を取得 "systemctl get-default"
"graphical" にデフォールトのターゲットを設定 (GUI システム) "systemctl set-default graphical"
"multi-user" にデフォールトのターゲットを設定 (CLI システム) "systemctl set-default multi-user"
ジョブ環境の表示 "systemctl show-environment"
ジョブ環境 "variable"(変数)を "value(値)に設定する" "systemctl set-environment variable=value"
ジョブ環境 "variable" (変数)の設定を解除する "systemctl unset-environment variable"
全 unit ファイルとデーモンを再起動 "systemctl daemon-reload"
システムをシャットダウンする "systemctl poweroff"
システムのシャットダウンと再起動 "systemctl reboot"
システムのサスペンド "systemctl suspend"
システムのハイバーネート "systemctl hibernate"

ここで、上記の例の中の "$unit" は単一の unit 名 (.service.target といったサフィックスは任意) とか、多くの場合、現在メモリー中の全 unit の主名称に対して fnmatch(3) を用いて"*" や "?" や "[]" 等のシェルスタイルのグロブによる複数 unit 指定であっても良い。

上記例中のシステムの状態を変えるコマンドは必要な管理特権を獲得させるべく "sudo" を通常前置する。

"systemctl status $unit|$PID|$device" の出力は色付きドット ("●") を使い unit の状態が一目瞭然とされる。

  • 白い "●" は "活動停止" や "停止済み" の状態を示す。

  • 赤い "●" は "失敗発生" や "エラー発生" の状態を示す。

  • 緑の "●" は "活動中" や "再起動中" や "起動中" の状態を示す。

Here are a list of other monitoring command snippets under systemd. Please read the pertinent manpages including cgroups(7).


デフォルトのインストールでは、多くのネットワークサービス(6章ネットワークアプリケーション を参照) はブート時に systemd によってブート時に network.target の後に起動される。"sshd" も例外ではありません。カスタム化の例としてオンデマンド起動に "sshd" をかえましょう。

最初に、システムがインストールしたサービスの unit を無効化しましょう。

 $ sudo systemctl stop sshd.service
 $ sudo systemctl mask sshd.service

古典的 Unix サービスでは indetd (または xinetd) スーパーサーバーによりオンデマンドでソケットを有効化していました。systemd では、*.socket*.service unit 設定ファイルを追加することでこれと同等のことが できます。

聞くソケットを指定するには sshd.socket

[Unit]
Description=SSH Socket for Per-Connection Servers

[Socket]
ListenStream=22
Accept=yes

[Install]
WantedBy=sockets.target

sshd.socket に対応するサービスファイルの sshd@.service

[Unit]
Description=SSH Per-Connection Server

[Service]
ExecStart=-/usr/sbin/sshd -i
StandardInput=socket

そして、再ロードします。

 $ sudo systemctl daemon-reload

udev システムはハードウエアーの自動検出と初期化のメカニズムを提供します (udev(7) 参照下さい)。カーネルが各デバイスを発見すると、udev システムは sysfs ファイルシステム (「procfs と sysfs」参照下さい) からの情報を使いユーザープロセスを起動し、modprobe(8) プログラム (「カーネルモジュール初期化」参照下さい) を使ってそれをサポートする必要なカーネルモジュールをロードし、対応するデバイスノードを作成します。

[ヒント] ヒント

もし "/lib/modules/kernel-version/modules.dep" が何らかの理由で depmod(8) によって適正に生成されていなかった場合には、モジュールは udev システムによる期待にそってロードされないかもしれません。これを修正するには、"depmod -a" を実行します。

"/etc/fstab" 中のマウントルールでは、デバイス名が静的なデバイス名である必要がありません。"/dev/sda" 等のデバイス名ではなく UUID を使ってデバイスをマウントできます。「UUID を使ってパーティションをアクセス」を参照下さい。

udev システムは少々動くターゲットなので、詳細は他のドキュメントに譲り、ここでは最小限の記述に止めます。

modprobe(8) プログラムは、ユーザープロセスからカーネルモジュールを追加や削除することで実行中の Linux カーネルの設定を可能にします。udev システム (「udev システム」参照下さい) は、その起動を自動化しカーネルモジュールの初期化を補助します。

"/etc/modules" ファイル中にリストしてプリロードする必要のある (modules(5) 参照下さい) 次に記すような非ハードウエアーや特殊ハードウエアーのドライバーモジュールがあります。

modprobe(8) プログラムのための設定ファイルは、modprobe.conf(5) で説明されているように "/etc/modprobes.d/" ディレクトリーの下にあります。(あるカーネルモジュールが自動ロードされるのを避けるには、"/etc/modprobes.d/blacklist" ファイル中にブラックリストします。)

depmod(8) プログラムによって生成される "/lib/modules/version/modules.dep" ファイルは、modprobe(8) プログラムによって使われるモジュール依存関係を記述します。

[注記] 注記

ブート時に modprobe(8) を使ってのモジュールロードの問題に出会った場合には、"depmod -a" として "modules.dep" を再構築をするとこの様な問題が解消できるかもしれません。

modinfo(8) プログラムは Linux カーネルモジュールに関する情報を表示します。

lsmod(8) プログラムは "/proc/modules" の内容を読みやすい形式にして、どのカーネルモジュールが現在ロードされているかを表示します。

[ヒント] ヒント

あなたのシステム上の正確なハードウエアーを特定します。「ハードウエアーの識別」を参照下さい。

ブート時に期待されるハードウエアー機能を有効となるように設定もできます。「ハードウエアー設定」を参照下さい。

あなたのデバイスのサポートは、カーネルを再コンパイルすれば追加できます。「カーネル」を参照下さい。