【はじめに】
電源を入れてから OS が起動するまでの処理を ブート(boot) または、より広義には ブートストラップ(bootstrap) と呼ぶ。
ブート手順は アーキテクチャ によって異なる。
- 電源 ON
- ファームウェアが起動
- ブートローダが起動
- カーネルが起動
-
init
(またはsystemd
)が起動 - ランレベル(SysVinit)またはターゲット(systemd)に応じたサービスが起動
ACPI
advanced configuration and power interface
電力を管理するための規格。
- 電源ボタンを押す
- ノートPCを開ける・閉じる
などの物理的操作によって ACPI イベントが発生する。イベントは acpid
デーモンによって処理される。
ブートローダ
Boot Loader
GRUB(Grand Unified Bootloader) に代表される、カーネルをメモリにロードして起動するプログラム。
- GRUB Legacy
- GRUB 2
- Linux で最も一般的
- systemd-boot
- systemd と統合されている
- rEFInd
- マルチブート
- GUI
- Windows Boot Manager
- Windows 専用(UEFI)
GRUB Legacy では /boot/grub/menu.lst
や /boot/grub/grub.conf
が設定ファイルに使われる。
GRUB 2 では /boot/grub/grub.cfg
が設定ファイルに使われる(BIOS、UEFI を問わず)。
複数の OS がインストールされている PC などで、どの OS を起動するかを選択できる機能を デュアルブート や、マルチブート という。
/etc/default/grub
GRUB 2 の設定ファイル(/boot/grub/grub.cfg
)を作成するためのテンプレートファイル。
/boot/grub/grub.cfg
は $ grub-mkconfig
によって /etc/default/grub
から生成される。
更新後は $ update-grub
コマンドを実行することで /etc/default/grub
、/etc/grub.d/
を元に /boot/grub/grub.cfg
が再生成される。
項目 | 説明 |
---|---|
GRUB_DEFAULT |
デフォルトで選ばれるメニューエントリ(数値または名前)。 |
GRUB_TIMEOUT |
メニューを表示する秒数。 |
GRUB_DISTRIBUTOR |
配布名表示(通常は自動)。 |
GRUB_CMDLINE_LINUX |
カーネルに渡すパラメータ。 すべてのカーネル起動モード(回復モードも含む)に適用される。 |
GRUB_CMDLINE_LINUX_DEFAULT |
カーネルに渡すパラメータ。 通常の GUI モードでの起動時にのみ適用される。 |
GRUB_DISABLE_RECOVERY |
回復モードを表示しない。 |
GRUB_GFXMODE |
GRUB の画面解像度(1024x768 )。 |
GRUB_BACKGROUND |
背景画像。 |
/etc/default/grub
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`( . /etc/os-release; echo ${NAME:-Ubuntu} ) 2>/dev/null || echo Ubuntu`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""
# If your computer has multiple operating systems installed, then you
# probably want to run os-prober. However, if your computer is a host
# for guest OSes installed via LVM or raw disk devices, running
# os-prober can cause damage to those guest OSes as it mounts
# filesystems to look for things.
#GRUB_DISABLE_OS_PROBER=false
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
/boot/grub/menu.lst
GRUB Legacy の設定ファイル。
/boot/grub/grub.conf
や /etc/grub.conf
が シンボリックリンクに紐付けられていることが多い。
/boot/grub/grub.cfg
GRUB 2 の設定ファイル。
手動更新はしない。
手動編集するのは、テンプレートファイル /etc/default/grub
の方で、$ update-grub
の実行によって生成される。
/boot/grub/grub.cfg
は自分で編集してはいけない。
/boot/grub/grub.cfg
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#
### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then
set have_grubenv=true
load_env
fi
if [ "${initrdfail}" = 2 ]; then
set initrdfail=
elif [ "${initrdfail}" = 1 ]; then
set next_entry="${prev_entry}"
set prev_entry=
save_env prev_entry
if [ "${next_entry}" ]; then
set initrdfail=2
fi
fi
if [ "${next_entry}" ] ; then
set default="${next_entry}"
set next_entry=
save_env next_entry
set boot_once=true
else
set default="0"
fi
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
else
menuentry_id_option=""
fi
export menuentry_id_option
if [ "${prev_saved_entry}" ]; then
set saved_entry="${prev_saved_entry}"
save_env saved_entry
set prev_saved_entry=
save_env prev_saved_entry
set boot_once=true
fi
function savedefault {
if [ -z "${boot_once}" ]; then
saved_entry="${chosen}"
save_env saved_entry
fi
}
function initrdfail {
if [ -n "${have_grubenv}" ]; then if [ -n "${partuuid}" ]; then
if [ -z "${initrdfail}" ]; then
set initrdfail=1
if [ -n "${boot_once}" ]; then
set prev_entry="${default}"
save_env prev_entry
fi
fi
save_env initrdfail
fi; fi
}
function recordfail {
set recordfail=1
if [ -n "${have_grubenv}" ]; then if [ -z "${boot_once}" ]; then save_env recordfail; fi; fi
}
function load_video {
if [ x$feature_all_video_module = xy ]; then
insmod all_video
else
insmod efi_gop
insmod efi_uga
insmod ieee1275_fb
insmod vbe
insmod vga
insmod video_bochs
insmod video_cirrus
fi
}
if [ x$feature_default_font_path = xy ] ; then
font=unicode
else
insmod part_gpt
insmod lvm
insmod ext2
set root='lvmid/xBVWvM-evpK-g65F-VoTg-pHDU-QYuM-nrisOJ/ZYDF4w-P7Bb-xBaw-YQt5-0f4i-RADe-CpV3ba'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint='lvmid/xBVWvM-evpK-g65F-VoTg-pHDU-QYuM-nrisOJ/ZYDF4w-P7Bb-xBaw-YQt5-0f4i-RADe-CpV3ba' 0ef24c83-c0a3-4caf-978f-fbb4213750a0
else
search --no-floppy --fs-uuid --set=root 0ef24c83-c0a3-4caf-978f-fbb4213750a0
fi
font="/usr/share/grub/unicode.pf2"
fi
if loadfont $font ; then
set gfxmode=auto
load_video
insmod gfxterm
set locale_dir=$prefix/locale
set lang=en_US
insmod gettext
fi
terminal_output gfxterm
if [ "${recordfail}" = 1 ] ; then
set timeout=30
else
if [ x$feature_timeout_style = xy ] ; then
set timeout_style=hidden
set timeout=0
# Fallback hidden-timeout code in case the timeout_style feature is
# unavailable.
elif sleep --interruptible 0 ; then
set timeout=0
fi
fi
### END /etc/grub.d/00_header ###
### BEGIN /etc/grub.d/05_debian_theme ###
set menu_color_normal=white/black
set menu_color_highlight=black/light-gray
### END /etc/grub.d/05_debian_theme ###
### BEGIN /etc/grub.d/10_linux ###
function gfxmode {
set gfxpayload="${1}"
if [ "${1}" = "keep" ]; then
set vt_handoff=vt.handoff=7
else
set vt_handoff=
fi
}
if [ "${recordfail}" != 1 ]; then
if [ -e ${prefix}/gfxblacklist.txt ]; then
if [ ${grub_platform} != pc ]; then
set linux_gfx_mode=keep
elif hwmatch ${prefix}/gfxblacklist.txt 3; then
if [ ${match} = 0 ]; then
set linux_gfx_mode=keep
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=text
fi
else
set linux_gfx_mode=keep
fi
else
set linux_gfx_mode=text
fi
export linux_gfx_mode
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-0ef24c83-c0a3-4caf-978f-fbb4213750a0' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 21c070f5-e452-4356-ad89-03e6f192e2e3
linux /vmlinuz-6.8.0-63-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro
initrd /initrd.img-6.8.0-63-generic
}
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-0ef24c83-c0a3-4caf-978f-fbb4213750a0' {
menuentry 'Ubuntu, with Linux 6.8.0-63-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-63-generic-advanced-0ef24c83-c0a3-4caf-978f-fbb4213750a0' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 21c070f5-e452-4356-ad89-03e6f192e2e3
echo 'Loading Linux 6.8.0-63-generic ...'
linux /vmlinuz-6.8.0-63-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro
echo 'Loading initial ramdisk ...'
initrd /initrd.img-6.8.0-63-generic
}
menuentry 'Ubuntu, with Linux 6.8.0-63-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-63-generic-recovery-0ef24c83-c0a3-4caf-978f-fbb4213750a0' {
recordfail
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 21c070f5-e452-4356-ad89-03e6f192e2e3
echo 'Loading Linux 6.8.0-63-generic ...'
linux /vmlinuz-6.8.0-63-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro recovery nomodeset
echo 'Loading initial ramdisk ...'
initrd /initrd.img-6.8.0-63-generic
}
menuentry 'Ubuntu, with Linux 6.8.0-62-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-62-generic-advanced-0ef24c83-c0a3-4caf-978f-fbb4213750a0' {
recordfail
load_video
gfxmode $linux_gfx_mode
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 21c070f5-e452-4356-ad89-03e6f192e2e3
echo 'Loading Linux 6.8.0-62-generic ...'
linux /vmlinuz-6.8.0-62-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro
echo 'Loading initial ramdisk ...'
initrd /initrd.img-6.8.0-62-generic
}
menuentry 'Ubuntu, with Linux 6.8.0-62-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.8.0-62-generic-recovery-0ef24c83-c0a3-4caf-978f-fbb4213750a0' {
recordfail
load_video
insmod gzio
if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
insmod part_gpt
insmod ext2
search --no-floppy --fs-uuid --set=root 21c070f5-e452-4356-ad89-03e6f192e2e3
echo 'Loading Linux 6.8.0-62-generic ...'
linux /vmlinuz-6.8.0-62-generic root=/dev/mapper/ubuntu--vg-ubuntu--lv ro recovery nomodeset
echo 'Loading initial ramdisk ...'
initrd /initrd.img-6.8.0-62-generic
}
}
### END /etc/grub.d/10_linux ###
### BEGIN /etc/grub.d/10_linux_zfs ###
### END /etc/grub.d/10_linux_zfs ###
### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###
### BEGIN /etc/grub.d/25_bli ###
if [ "$grub_platform" = "efi" ]; then
insmod bli
fi
### END /etc/grub.d/25_bli ###
### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###
### BEGIN /etc/grub.d/30_uefi-firmware ###
if [ "$grub_platform" = "efi" ]; then
fwsetup --is-supported
if [ "$?" = 0 ]; then
menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
fwsetup
}
fi
fi
### END /etc/grub.d/30_uefi-firmware ###
### BEGIN /etc/grub.d/35_fwupd ###
### END /etc/grub.d/35_fwupd ###
### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###
### BEGIN /etc/grub.d/41_custom ###
if [ -f ${config_directory}/custom.cfg ]; then
source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f $prefix/custom.cfg ]; then
source $prefix/custom.cfg
fi
### END /etc/grub.d/41_custom ###
/boot/grub/device.map
BIOS や UEFI の「ディスク番号」と カーネルが認識する「デバイスファイル(/dev/sd1
など)」を対応付けるためのファイル。
$ grub-install
によって自動的に生成される。
GRUB では、ディスクを以下のように扱う。
-
hd0
:1 番目のハードディスク -
hd1
:2 番目のハードディスク
一方で、カーネルはデバイスを /dev/sda
や /dev/sdb
などのように認識するため、これを紐づけるために以下のような記述がされる。
(hd0) /dev/sda
(hd1) /dev/sdb
$ grub-install
/ $ grub2-install
$ grub-install インストール先ディスク
$ grub2-install インストール先ディスク
$ grub-install /dev/sda
$ grub2-install /dev/sda
$ grub-mkconfig
/ $ grub2-mkconfig
GRUB 2 用の設定ファイル生成コマンド。
Debian 系(Debian、Ubuntu)では $ grub-mkconfig
が使用され、Red Hat 系(CentOS、Fedora、RHEL)では $ grub2-mkconfig
が用いられる。いずれも機能は同じ。
テンプレートファイルの /etc/default/grub
ファイルと、/etc/grub.d/
のスクリプト群を元に、指定された出力先に設定ファイルを生成することができる。
$ grub-mkconfig -o /boot/grub/grub.cfg
$ grub2-mkconfig -o /boot/grub2/grub.cfg
$ update-grub
GRUB の設定ファイルを更新するためのコマンド。
/etc/default/grub
と /etc/grub.d/
を元に /boot/grub/grub.cfg
を再生成する。
$ update-grub
ファームウェア
Firmware
BIOS (Basic Input / Output System)や UEFI (Unified Extensible Firmware Interface)に代表される、デバイスを制御するためのプログラム。
実体はソフトウェアでありながら、ハードウェアとソフトウェアの中間的な存在として位置づけられるため ファームウェア と呼ばれる(firm = 固い、堅牢)。
UEFI は BIOS の後継プログラムであり、両者は別々のものだが、BIOS という用語が広く定着しているために UEFI を指して BIOS を言うことがある。
以前は不揮発性の ROM に格納されていたが、現在は書き換え可能な EEPROM や フラッシュメモリ に格納されており、ファームウェア更新も可能になっている。
また UEFI には、デジタル署名済みの信頼できるソフトウェアだけを起動するセキュリティ機能(セキュアブート)もある。
BIOS vs UEFI
BIOS のブートローダも、UEFI のブートローダも、どちらも役割は カーネルを起動すること だが、格納されている場所や起動方法が異なる。
違い | BIOS | UEFI |
---|---|---|
格納先 | マザーボード上の ROM | フラッシュメモリ |
ブートローダ | 第 1 段階は MBR 先頭 512 byte 第 2 段階以降は別領域に存在 |
.efi ファイル(EFI アプリケーション) |
読み込み対象 |
1 ~ 512 byte(1 セクタ) |
ファイルシステム(FAT32)上のファイル |
パーティション方式 | 主に MBR | 主に GPT |
セキュアブート | ない | ある |
※ MBR:master boot record
※ GPT:GUID partition table
※ BIOS で GPT を扱うにはブートローダのカスタマイズが必要なため、一般には MBR が使われる。
※ UEFI では GPT が推奨されているが、一部の構成では MBR との併用も可能。
BIOS のブートローダ
BIOS のブートローダは、MBR のディスクの先頭 512 byte に直接書き込まれている。
byte | 内容 |
---|---|
0 ~ 445
|
第 1 段階のブートローダ |
446 ~ 509
|
パーティションテーブル(最大 4 個、各 16 byte、計 64 byte) |
510 ~ 511
|
シグネチャ(固定値:0x55AA )これがない場合、BIOS はディスクを「ブートできない」と判断して、エラーメッセージ(例: No bootable device )を表示したり、次のデバイスに切り替えたりする。 |
ディスク の 1 セクタが 512 byte であることを背景として、BIOS は起動時に MBR の先頭 512 byte を読み込むように設計されており、パーティションテーブルもその中に収まるよう定義されている。
ただし、この中に格納されるブートローダは「第 1 段階のブートローダ」であり、「第 2 段階のブートローダ」は MBR の外側(ディスクの空き容量や /boot/grub/
)に格納されている。設定ファイル /boot/grub/grub.cfg
も同じディレクトリに含まれている。
BIOS は MBR 内の「第 1 段階のブートローダ」しか読み込まないため、「第 2 段階のブートローダ」は「第 1 段階のブートローダ」によって読み込まれる必要がある。
- BIOS が最初に実行される
- BIOS がディスクの MBR(最初の 512 byte:第 1 段階ブートローダ)を読み込む
- 第 1 段階ブートローダが第 2 段階ブートローダを読み込む
- 第 2 段階ブートローダがカーネルをメモリに読み込む
- カーネルが
init
orsystemd
を起動する
UEFI のブートローダ
UEFI におけるブートローダは、ファイルシステム上(ESP)に保存されたファイルであり、ファームウェア UEFI によって実行される EFI アプリケーション(.efi
)である。
ESP(EFI System Partition)は、UEFI ファームウェアによって起動される EFI アプリケーション(.efi
)を格納するための 専用パーティション のことを指す。
EFI アプリケーションは、UEFI が直接実行できるバイナリのプログラムを指す。
ESP は FAT32 形式でフォーマットされることが UEFI の仕様で定められていて、通常は /boot/efi
でマウントされる。
- UEFI が ESP の EFI アプリケーション(
.efi
)を実行する - EFI アプリケーションがカーネルをメモリに読み込む
- カーネルが
init
orsystemd
を起動する
$ efibootmgr
UEFI 環境のブートマネージャが参照する ブートエントリ を操作するためのコマンド。
$ efibootmgr
$ efibootmgr
BootCurrent: 0005 👈起動したエントリ
Timeout: 3 seconds
BootOrder: 0001,0005,0003,0000,0002,0004 👈起動した順番
👇 以下は登録されたエントリ
Boot0000* UiApp FvVol(64074afe-340a-4be6-94ba-91b5b4d0f71e)/FvFile(462caa21-7614-4503-836e-8ab6f4662331)
Boot0001* UEFI QEMU QEMU USB HARDDRIVE 1-0000:00:04.0-4.1 PciRoot(0x0)/Pci(0x4,0x0)/USB(7,0)/USB(0,0){auto_created_boot_option}
Boot0002* UEFI Misc Device VenHw(93e34c7e-b50e-11df-9223-2443dfd72085,00){auto_created_boot_option}
Boot0003* UEFI Misc Device 2 PciRoot(0x0)/Pci(0x6,0x0){auto_created_boot_option}
Boot0004* EFI Internal Shell FvVol(64074afe-340a-4be6-94ba-91b5b4d0f71e)/FvFile(7c04a583-9e3e-4f1c-ad65-e05268d0b4d1)
Boot0005* Ubuntu HD(1,GPT,024057b8-125e-4bc1-aac1-8f3728d2f7a6,0x800,0x17d800)/File(\EFI\ubuntu\shimaa64.efi)
ブートエントリは NVRAM(Non Volatile RAM:マザーボード上の不揮発性メモリ)に保存される、 UEFI が直接管理するエントリのことで、起動時に UEFI によって最初に参照される情報でもある。
どのブートローダ(.efi
)を起動するかを決定するために利用され、1 つのディスク上に複数の OS がインストールされた環境ではマルチブート機能を実現する。
$ efibootmgr --botorder エントリ1,エントリ2,エントリ3...
$ efibootmgr --bootnum ブートエントリ番号 --delete-bootnum
SYSLINUX
ファイルシステムが FAT 形式の USB や CD-ROM から Linux を起動する際に使用されるブートローダ。
USB や CD-ROM の Linux は主に、レスキュー用途で利用される。
それぞれの環境向けに派生版としてブートローダが存在し、それらは SYSLINUX パッケージとしてまとめられている。
派生版 | 用途 |
---|---|
SYSLINUX |
FAT 形式の HDD、USB からカーネルを起動するブートローダ |
ISOLINUX |
ISO9660(CD-ROM)からカーネルを起動するブートローダ |
EXTLINUX |
ext2、ext3、ext4 からカーネルを起動するブートローダ |
PXELINUX |
PXE を使ってネットワークブートを行うためのブートローダ |
PXE ブート
preboot execution environment
Intel 社によって策定された BIOS / UEFI の ネットワークブート の規格。
ネットワークブートとは、ローカルのストレージ(HDD / SSD / USB)を使わずに、ネットワーク経由で OS を起動する仕組みを指す。
HDD などのストレージディスクを必要としないディスクレス端末としてマシンを利用することができる。端末にデータを残さないため、セキュリティが強化される。
ブートローダやカーネルは TETP サーバからネットワークを介してダウンロードされたものを利用する。
基本的に、ダウンロードされたプログラムはメモリ上に展開されるだけなので、電源 OFF によって消失する。そのため、ダウンロードは起動の度に行なわれる。
ただし、データセンタや大規模環境において、OS を一斉インストール(大量セットアップ)するなどのシチュエーションでは、初回ネットワークブート時にダウンロードされたブートローダ、カーネルがローカルのディスクに保持され、2 回目以降の起動ではネットワークブートでなく、通常のローカル環境でのブートが行われる、ということもある。このケースではネットワークブートは環境構築でのみ利用される。
起動手順
- クライアント
- 起動側のホスト
- PXE 対応の NIC を持つ
- サーバ
- ブートローダを保有するホスト
- DHCP サーバが稼働している(別ホストとしても可)
- TFTP サーバが稼働している
【起動手順】
- BIOS / UEFI がネットワークブートモードで起動する
- DHCP サーバから、ブートローダを保有するホストの IP アドレスを受け取る
- TFTP サーバから、ブートローダがダウンロードされる
- ブートローダがさらにカーネルや
初期 RAM ディスク
(initrd
)をダウンロードする - OS が起動する
【つぎに】
ブートは init
もしくは systemd
プロセスを起動することによって完了する。
init
、systemd
は、OS の ユーザ空間 における最初のプロセス(PID 1
)として実行され、ログイン、ネットワーク、各種デーモンなどの起動と制御を担う。
近年では従来から広く利用されてきた SysV init 方式から systemd 方式へ移り変わりつつある。
SysV init は 直列 で各プログラムを起動していくのに対して、systemd は 並列 で起動を行うため、起動速度に違いがあるものの、基本的な流れは共通している。
SysVinit
System V(Five) Init
長年 Linux の標準的な init システムとして使用されてきた、システムの起動やプロセス管理の仕組み。
並列処理ができないことによる起動の遅さなどの課題があり、Red Hat 系(RHEL、CentOS、Fedora)や Debian 系(Debian、Ubuntu)では、既に後継版である systemd に移行されている。
ただし一部の軽量ディストリビューション(Alpine Linux)では、現在も SysVinit が採用されている。
- ランレベル でシステムの状態を管理する
- サービスの起動を 直列処理 で 1 つずつ順番に起動するため時間がかかる
- サービスが異常終了した場合、自動で復旧しない
主な役割は、システム起動時に必要なプロセスを適切に立ち上げ、シャットダウン時に適切に停止することだが、「デーモンを起動する」、「親プロセスが終了した孤立プロセスを引き取る」役割なども併せ持つ。
ランレベル
システムの状態を管理するための概念のこと。
例えば、シャットダウンは「ランレベル 0
プログラムの実行」、システムの再起動は「ランレベル 6
のプログラムの実行」を意味している。
それぞれのランレベルには意味づけがされている。
ランレベル | 意味 |
---|---|
0 |
システムの停止(シャットダウン) |
1 |
シングルユーザモードroot ユーザのみがログインできる |
2 |
マルチユーザモード NFS なし |
3 |
マルチユーザモード(CUI) NFS あり |
4 |
未使用 |
5 |
マルチユーザモード + GUI(X Window) |
6 |
システムの再起動 |
ランレベルの呼び出しは init
プロセスによって行われる。
システム起動時に init
は /etc/inittab
に記載されたランレベルに応じて、実際には /etc/rcランレベル.d/
ディレクトリにあるスクリプトを「サービス」として起動する。
$ ls -l /etc/rc3.d/
total 0
lrwxrwxrwx 1 root root 17 Jan 1 09:00 K01bluetooth -> ../init.d/bluetooth
lrwxrwxrwx 1 root root 15 Jan 1 09:00 K02cups -> ../init.d/cups
lrwxrwxrwx 1 root root 16 Jan 1 09:00 S01apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 16 Jan 1 09:00 S02cron -> ../init.d/cron
lrwxrwxrwx 1 root root 18 Jan 1 09:00 S20networking -> ../init.d/networking
lrwxrwxrwx 1 root root 13 Jan 1 09:00 S99local -> ../init.d/rc.local
NFS
Network File System
リモートのサーバにあるファイルをローカルのディレクトリのように扱える仕組み。
例えば、ネットワークを介してサーバ上の /home/shared
をクライアントの /mnt/shared
に マウント すれば、まるでローカルファイルのようにアクセスできるようになる。
ランレベル 2
では NFS クライアントが無効、3
では有効。
/sbin/init
カーネル起動後、ユーザ空間 で最初に実行されるプロセス。
PID(プロセスID)1
が割り当てられる。
SysV init によって起動されたプロセスは、この init
が親プロセスになる。一方、ユーザが手動で起動したプロセスは init
ではなく、プロセスを起動したシェル(/bin/bash
)などが親プロセスになる。
$ pstree
※ $ pstree
init
は設定ファイル /etc/inittab
を読み込んで、どの ランレベル で起動するかを決定し、ランレベルに応じたスクリプトを実行する。
-
init
が/etc/inittab
を読み込む-
sysinit
アクションにより/etc/rc.sysinit
が実行される(ファイルシステムのチェaク、マウント、スワップ有効化などの全体初期化を行う) -
initdefault
アクションによりデフォルトランレベルが決定する
-
-
init
がランレベル用のスクリプト/etc/rc
(Red Hat系) または/etc/init.d/rc
(Debian系) -
/etc/rc
が/etc/rcランレベル.d/
のシンボリックリンクを処理する- 実際のスクリプトは
/etc/init.d
に存在 -
K
で始まる → サービスの停止 -
S
で始まる → サービスの起動
- 実際のスクリプトは
/etc/inittab
SysV init に対して「いつ、何を、どの条件で実行するか」を指定する設定ファイル。
init
が起動した際に読み込まれる。:
区切りで 4 つのフィールドを設定することができる。
識別子:ランレベル:アクション:コマンド
- 識別子
- 1 ~ 4 文字
- ランレベル
-
0
~6
-
- アクション
-
init
に指示する動作
-
- コマンド
- 実行されるコマンドやスクリプトのパス
識別子とアクションにはよく利用される組み合わせが存在する。
よく利用される「識別子」と「アクション」の組み合わせ
識別子 | アクション | 意味と設定例 |
---|---|---|
id |
initdefault |
システム起動時に自動で移行するデフォルトのランレベル。 エントリは 1 つである必要がある。 このエントリで指定されたランレベルにシステムが移行されると、該当ランレベルに対応するエントリ(例: 3:3:wait:... , 3:3:respawn:... など)が順次処理される。例: id:3:initdefault:
|
1 ~6
|
wait |
該当ランレベルに切り替わったときに指定されたスクリプトを 1 度だけ実行し、init は実行したスクリプトの完了を待つ。例: 3:3:wait:/etc/rc.d/rc 3 → /etc/rc3.d/ ディレクトリの、ファイル名が S または K で始まるファイルが順に実行される |
1 ~6
|
once |
該当ランレベルに切り替わった時に指定されたスクリプトを 1 度だけ実行する。init はこのスクリプトの終了を待たない。 |
si |
sysinit |
システム初期化スクリプト(/etc/rc.sysinit )を起動時に一度だけ実行する。例: si::sysinit:/etc/rc.d/rc.sysinit
|
1 ~6
|
respawn |
再び(re) + 生まれる(spawn) 指定したコマンドが終了したら、再び起動し直す。 システムが動作している間ずっと常駐していてほしい仮想端末( getty )などのプロセス起動のために利用される。常駐しないプログラムを指定した場合、無限ループが発生する。 例: 1:2345:respawn:/sbin/mingetty tty1
|
ca |
ctrlaltdel |
Ctrl + Alt + Del キーが押されたときの動作。例: ca::ctrlaltdel:/sbin/shutdown -t3 -r now
|
pf |
powerfail |
power fail 電源障害(電源が切れた)時にログ保存、サービス停止などを行う用。 例: pf::powerfail:/sbin/shutdown -h now
|
pg |
powerokwait |
power good 電源が回復(正常化)したことを検知したときにサービス再起動などを行う用。スクリプトが終了するまで待機する。 |
/etc/inittab
の内容を変更した場合、$ init q
で即時反映させることができる。
$ init q
/etc/rc.sysinit
/etc/inittab
によって、システムの起動時に実行されるように設定されたスクリプトファイル。
通常このスクリプトは、以下のようなシステム初期化処理を行う。
- ファイルシステムのチェック(
$ fsck
)、マウント($ mount
) -
/proc
や/sys
などの 仮想ファイルシステム のマウント - 時刻の設定
- スワップの有効化(
$ swapon
) - 一時ファイルのクリーンアップなど
/etc/rcランレベル.d/
run command
/etc/inittab
によって、特定のランレベルへ移行した際に実行したいスクリプトが配置されるディレクトリ。
このディレクトリ内の S
や K
で始まるスクリプトファイルは、/etc/init.d/
に配置されたスクリプトへのシンボリックリンクになっていて、S
は start、K
は kill を意味する。
以下の順に実行される。
-
K
で始まるファイル(数値(0
~99
)は小さいものからから順に実行される) -
S
で始まるファイル(数値(0
~99
)は小さいものからから順に実行される)
特定のランレベルの際に実行したいサービス(/etc/rcランレベル.d/S99サービス
など)は、このディレクトリに配置すれば良い。
スクリプト内では、起動したいサービス起動するためのコマンドが実行される。また起動だけでなく、停止コマンドを実行する場合もある。
もし起動したいサービスが /etc/init.d/
配下にある既存サービスであるなら、このディレクトリにはシンボリックリンクを作成するだけで良い。
$ ln -s /etc/init.d/既存サービス /etc/rcランレベル.d/S〇〇サービス
/etc/init.d/
サービスを開始・停止するためのスクリプトが配置されるディレクトリ。
基本的に /etc/init.d/
配下にあるスクリプトは、以下のようなサブコマンド(引数)を受け取ることを前提にしている。
$ /etc/init.d/httpd start
サブコマンド | 説明 |
---|---|
start |
サービスを起動する |
stop |
サービスを停止する |
restart |
サービスを再起動する |
condrestart |
サービスが起動している場合のみ、再起動する(conditional restart) |
status |
サービスの状態を表示する |
ただし、直接実行するのは非推奨で、ラッパーコマンドである $ service
を利用した方が良い。
$ runlevel
$ runlevel
「一つ前のランレベル」と「現在のランレベル」が表示される。
起動直後は一つ前のランレベルが N
で表示される。
$ init
/ $ telinit
$ init ランレベル
$ telinit ランレベル
$ init q
$ telinit q
$ service
SysV init で使用される サービス 管理用コマンド。
実体は /etc/init.d/
配下のスクリプトのラッパーコマンド。
$ service サービス start
$ service サービス stop
$ service サービス restart
$ service サービス reload
$ service サービス status
$ chkconfig
check config
Red Hat 系(Red Hat、CentOS、Fedora)で使用される /etc/init.d/
にあるサービスの自動起動設定を管理するためのツール。
$ chkconfig --list
$ chkconfig --list サービス
$ chkconfig サービス off
$ chkconfig sshd off
$ chkconfig サービス on
$ chkconfig sshd on
$ chkconfig --add サービス
サービスを追加登録した場合、スクリプトが /etc/init.d/サービス
として存在し、ヘッダ情報が正しく書かれていれば、/etc/rcランレベル.d/
にシンボリックリンクが作成される。
ヘッダ情報とは、各スクリプトの先頭に記載されるコメント行を指す。
# chkconfig: 有効にするランレベル(複数可) 起動の優先度(小さいほど優先) 停止の優先度(小さいほど優先)
# (例) chkconfig: 345 80 20
# description: 説明
$ chkconfig --del サービス
サービスの登録削除を行った場合、/etc/init.d/
のスクリプトは残ったまま、$ chkconfig
管理下から除外される。
$ update-rc.d
Debian 系(Debian、Ubuntu)で使用される /etc/init.d/
にあるサービスの自動起動設定を管理するためのツール。
/etc/init.d/
にあるスクリプトに対して、/etc/rcランレベル.d/
以下の S*
/ K*
という形式の シンボリックリンクを自動生成、管理する。
defaults
を指定すると、2
~ 5
が起動用、0
、1
、6
が停止用としてシンボリックリンクが作成される。
$ update-rc.d サービス defaults
$ update-rc.d サービス start 優先度 ランレベル(スペース区切りで複数可) .
$ update-rc.d サービス stop 優先度 ランレベル(スペース区切りで複数可) .
$ update-rc.d サービス 起動用の優先度 停止用の優先度
※ 優先度
$ update-rc.d サービス disable
$ update-rc.d サービス enable
remove
を付与した場合、/etc/rcランレベルd/
のシンボリックリンクが削除される(/etc/init.d/
のスクリプトはそのまま残る)。
この際、全てのランレベルが削除対象となる。
また remove
を付与する際は、通常、ファイルのリンク先である /etc/init.d/
内のスクリプトが存在しない場合、エラーが発生する。/etc/init.d/
内のスクリプトの存在有無を確認しない場合、-f
オプションを使用する。
$ update-rc.d サービス remove
$ update-rc.d -f サービス remove
systemd
従来の SysV init の後継版として開発され、現代の Linux で主流になっているブートシステム。
以下の特徴を持つ。
- 並列 処理により高速に起動
- すべての管理対象(サービス、デバイス、マウントポイントなど)を ユニット という概念で統一的に管理
- ターゲット によりシステム状態を管理(SysV init のランレベルに相当)
- 異常終了したサービスを自動で再起動可能
ただし、以下の批判をされることがある。
- SysV init はシンプルなシェルスクリプトで構成されていたのに対して、systemd はバイナリの実行可能ファイルで構成されており、内部動作が隠蔽されているのに加えて、仕組みが複雑すぎる
- UNIX の「小さなツールを組み合わせる」という設計思想に反して、多機能すぎる
- あまりにも多くを管理しすぎているため、 systemd に対する依存が強くなる
このため、一部のディストリビューション(Alpine Linux, Devuan, Artix Linux など)は systemd を採用せず、SysVinit や runit、OpenRC を使い続けている。
SysV init の init
が担っていた役割を、systemd では /usr/lib/systemd/systemd
デーモンが担当する。systemd
は init
同様に PID 1
が割り当てられる。
systemd
の他にも以下のデーモンが存在する。
デーモン | 役割 |
---|---|
systemd |
/usr/lib/systemd/systemd PID 1 の特別なメインプロセス |
systemd-journald |
ログ管理 |
systemd-logind |
ログイン処理 |
systemd-networkd |
ネットワーク管理 |
systemd-timesyncd |
システムクロック 管理 |
systemd-resolved |
ホスト名の名前解決 |
systemd-udevd |
udev(デバイスの動的検知) |
ユニットとは
Unit
systemd では、すべてのサービスやリソースを ユニット という概念で管理する。
ユニットは ユニットファイル によって定義され、一つのユニットは複数のサービスから構成される。
systemd ではサービスもユニットの一つであり、ランレベルもユニットのうちの一つにすぎない。
ユニットの種類
ユニットにはいくつかの種類があり、以下の拡張子によって区別される。
拡張子 | 説明 |
---|---|
.target |
複数のユニットをグループ化するためのユニット。 ターゲットは SysV init の ランレベルに相当する。 例えば、 graphical.target には GUI のログインを行うために必要なサービス(.service )がまとめられている。 |
.service |
自身以外の他のデーモンやサービスを管理するユニット。 |
.mount |
マウント を管理するユニット。 |
.device |
デバイスを管理するユニット。 |
.timer |
ジョブのスケジュールを管理するユニット(cron に相当)。 |
.socket |
ソケットを管理するユニット。 |
.swap |
スワップ を管理するユニット。 |
ターゲットユニット
systemd
が管理するユニットの一つ。
システム起動時は defalut.target
が最初に起動する。
default.target
には特定のランレベル(相当)のサービス(.service
)が紐づけられているわけではないが、default.target
ファイル自体が下記のターゲットへのシンボリックリンクになっている。
例えば デスクトップ 環境(GUI)で動作する Linux の場合、default.target
には graphical.target
にリンクされている。
$ systemctl
コマンドで確認できる。
$ systemctl get-default
ランレベル(相当) | ターゲット |
---|---|
0 |
poweroff.target |
1 |
rescue.target |
2 、3 、4
|
multi-user.target |
5 |
graphical.target |
6 |
reboot.target |
サービスユニット
systemd
が管理するユニットの一つ。
用途 | ターゲット |
---|---|
Web サーバ |
httpd.service apache2.service nginx.service
|
DB サーバ |
mysqld.service postgresql.service
|
メールサーバ | postfix.service |
SSH サーバ | sshd.servic |
ジョブスケジューラ | crond.service |
ユニットファイル
ユニットはユニットファイルによって定義される。
ユニットファイルは [セクション]
単位で記述され、一つのセクションは複数の ディレクティブ から構成される。
[セクション]
ディレクティブ=設定値
- ディレクティブの大文字小文字は区別されない
-
Wants
など、同じディレクティブを複数記述できるものもある - 設定値には置換文字列(specifier)が利用できる
例:/usr/lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]
EnvironmentFile=-/etc/default/ssh
ExecStartPre=/usr/sbin/sshd -t
ExecStart=/usr/sbin/sshd -D $SSHD_OPTS
ExecReload=/usr/sbin/sshd -t
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
Alias=sshd.service
置換文字列
置換文字列 | 展開される内容 |
---|---|
%n |
フルユニット名(例:my.service ) |
%N |
フルユニット名(エスケープしない) |
%p |
ユニット名のプレフィックス(. より前の my 部分。) |
%i |
インスタンス名(テンプレートユニット @ の後の部分) |
%f |
ユニットファイルのフルパス |
%u |
実行ユーザ名 |
%U |
実行ユーザ ID |
%h |
実行ユーザのホームディレクトリ |
%s |
実行ユーザのシェル |
%t |
systemd のランタイムディレクトリ(通常 /run ) |
%S |
システム状態ディレクトリ(/var/lib など) |
%m |
マシン ID(/etc/machine-id ) |
%H |
ホスト名 |
%b |
ブート ID |
Unit
セクション
ディレクティブ | 説明 |
---|---|
Description |
説明書き |
After |
起動していることが前提とされるユニット。 起動順の制御を行うが依存関係は作らない。 例えば、 After に記載されたユニットが起動に失敗しても、自身は起動する。 |
Before |
起動していないことが前提とされるユニット 起動順の制御を行うが依存関係は作らない。 例えば、 Before に記載されたユニットが起動に失敗しても、自身は起動する。 |
Wants |
推奨の依存関係(なくても起動可能)。 |
Requires |
必須の依存関係。 これが無いと起動しないという別のユニット。 強制的な依存関係となるため、指定したユニットの起動が失敗しが場合、自身は起動しない。 |
Conflicts |
同時に起動できないユニット。 |
Service
セクション
ディレクティブ | 説明 |
---|---|
Type |
サービス起動の種類。simple / forking / oneshot / notify / dbus
|
ExecStart |
サービス開始時にユニットが内部で実行するコマンド。$ systemctl start した際に、内部で実行される。 |
ExecReload |
$ systemctl reload 時に実行されるコマンド。 |
ExecStop |
$ systemctl stop 時に実行されるコマンド。 |
Restart |
サービスが終了した際の、再起動のポリシー設定。always / on-failure / no
|
RestartSec |
サービス再起動前の待機時間(秒)。 |
User |
サービス実行時の実行ユーザ。 |
Group |
サービス実行時の実行グループ。 |
WorkingDirectory |
サービス実行時の作業ディレクトリ。 |
Install
セクション
$ systemctl enable
実行時に作成される、ターゲットへの関連付け(リンク)を定義する。
WantedBy=multi-user.target
とすると $ systemctl enable
実行時に /etc/systemd/system/multi-user.target.wants/
に、サービス(.service
)へのシンボリックリンクが作成される。
ディレクティブ | 説明 |
---|---|
WantedBy |
関連付けるターゲット(弱い依存関係)。 ユニットの起動に失敗しても、ターゲットの起動は継続する。 $ systemctl enable 実行時に、指定された .target の .target.wants/ にサービスへのシンボリックリンクを作成する。主に multi-user.target や graphical.target に設定して、ユニットを自動起動させるために利用される。 |
RequiredBy |
関連付けるターゲット(強い依存関係)。 ユニットの起動に失敗すると、ターゲットの起動も失敗する。 $ systemctl enable 実行時に、指定された .target の .target.requires/ にサービスへのシンボリックリンクを作成する。 |
ユニット同士の依存関係
ユニットの依存関係を定義する方法は 2 通りある。
Requires
/ Wants
ディレクティブで設定する
依存するユニットを、ユニットファイル Requires
もしくは Wants
ディレクティブで直接指定する方法。
[Unit]
Requires=ユニット もしくは ターゲット
After=ユニット もしくは ターゲット
このように記述しておけば、指定したユニットやターゲットの起動後に自身のユニットが自動的に移動される。
- メリット
- 構成がシンプル
- デメリット
-
$ systemctl enable
/$ systemctl disable
が使用できないため、依存関係の変更はユニットファイルを直接編集するしかない - 複数のターゲットに紐付けできない
-
.target.wants/
/ .target.requires/
にシンボリックリンクを置く
ユニットファイルの RequiredBy
もしくは WantedBy
で紐付けたいターゲットを指定する方法。
[Install]
WantedBy=ターゲット
このように記述しておけば、$ systemctl enable
を実行した際に、指定した .target.wants/
もしくは .target.requires/
にユニットへのシンボリックリンクが作成される。
例えば、
[Install]
WantedBy=multi-user.target
として $ systemctl enable
を実行すれば、/etc/systemd/system/my.service
へのシンボリックリンク /etc/systemd/system/multi-user.target.wants/my.service
が作成される。
- メリット
-
$ sytemctl enable
/$ systemctl disable
による有効化、無効化が簡単 - サービスを複数のターゲットに紐付けたり、それぞれのターゲットに対して異なる依存関係が定義できる
-
- デメリット
- 依存関係が
./wants/
のリンクで表現されるため、リンクが増えると構成が複雑化する
- 依存関係が
ユニットファイルの配置
ユニットファイルは下記のディレクトリに格納されている。
ディレクトリ | 説明 |
---|---|
/etc/systemd/system/ |
ユーザがカスタマイズしたユニットが格納される。 優先順位が最も高く /usr/lib/systemd/system/ よりも早く読み込まれる。また、 /usr/lib/systemd/system/ に同名のユニットがあっても、このディレクトリ内のファイルが優先される(デフォルトを上書き)。 |
/run/systemd/system/ |
一時的ユニットが格納される。 再起動によって消失する。 |
/usr/lib/systemd/system/ |
デフォルト のユニットが格納される。 ユーザが直接編集しない。 多くのユニットは、このディレクトリ配下のファイルに対してのシンボリックリンクとなっている。 |
/lib/systemd/system/ |
ディストリビューションによって /usr/lib/systemd/system/ の代わりに使用される。 |
~/.config/systemd/user/ |
ユーザ単位のユニットファイルが格納される。 |
/etc/systemd/system/default.target
は /lib/systemd/system/graphical.target
へのシンボリックリンクになっている。
テンプレートユニット
1 つのユニットファイルを元にして、同時に複数のサービス(インスタンス)を起動するための仕組み。
起動したいユニットファイルの拡張子前に @
をつけておく必要がある。
my@.service
このようにしておくことで、サービスを起動した際に「インスタンス名」を付け、複数起動することができる。
$ systemctl start my@instance1.service
$ systemctl start my@instance2.service
$ systemctl
System Control
systemd で使用されるユニット管理用コマンド。
指定するユニットが ***.service
の場合、.service
を省略できる。
【システム全体に対する操作を行う、設定を変更する】
$ systemctl poweroff
$ systemctl reboot
$ systemctl set-default ターゲット
$ systemctl default
【システムの状態を確認する】
$ systemctl get-default
【サービス(.service
)に対する操作を行う、設定を変更する】
$ systemctl start サービス
$ systemctl stop サービス
$ systemctl restart サービス
$ systemctl reload サービス
は特定のサービスの設定を再読み込みするためのコマンド。
$ systemctl reload サービス # サービスごとに設定ファイルは異なる
$ systemctl daemon-reload
は systemd
に ユニットファイル の変更を反映させるためのコマンド。
$ systemctl daemon-reload
$ systemctl enable
/ $ systemctl disable
は、 ユニットファイル に WantedBt
もしくは RequiredBy
が定義されていることを前提としている。
$ systemctl enable サービス
$ systemctl disable サービス
$ mask
はユニットファイルに /dev/null
への シンボリックリンク を作成するため、$ systemctl start
などの起動コマンドすら無効になる。$ systemctl disable
による無効化とは異なり、手動起動もブロックされる。
$ systemctl mask サービス
$ systemctl unmask サービス
【サービス(.service
)の情報を確認する】
$ systemctl status サービス
$ systemctl is-active サービス
$ systemctl list-dependencies サービス
【ユニットの情報を確認する】
$ systemctl list-unit-files
$ systemctl list-units
-t
(--type
)で ユニットの種類(service
/ target
/ mount
...)を指定できる。
$ systemctl list-unit-files -t ユニットの種類
--state
でサービスの状態を指定できる。
$ systemctl list-unit-files --type=service --state=enabled
$ systemd-delta
ユニットファイルや、設定ファイルの変更差分を確認するためのコマンド。
systemd では、同じユニット名のファイルが複数のディレクトリに存在した場合、優先順位に基づいて読み込まれる。
ただし何らかのトラブルシューティングにおいて、この差分を把握するのは難しいため、$ systemd-delta
によって表示された差分を足がかりにして、解析作業を行うことができる。
$ systemd-delta
以下のディレクトリが検索対象となっている。
/etc/systemd/system/
/run/systemd/system/
-
/usr/lib/systemd/system/
または/lib/systemd/system/
出力される差分は 変更タイプ
によって分類されて表示される。
変更タイプ | 内容 |
---|---|
MASKED |
完全に無効化されている状態。$ systemctl mask
|
OVERRIDDEN |
上書き変更された状態。/etc/systemd/system/ に同名のユニットファイルがある。 |
EXTENDED |
部分的に上書きされた状態。/etc/systemd/system/サービス.d/override.conf が存在し、デフォルトの設定が一部だけ上書かれている。 |
REDIRECTED |
ユニットファイルが別名ユニットにリダイレクトされている状態。 |
UNCHANGED |
ユーザによる変更はない状態。 |
実行例
$ systemd-delta
[OVERRIDDEN] /etc/tmpfiles.d/screen-cleanup.conf → /usr/lib/tmpfiles.d/screen-cleanup.conf
--- /usr/lib/tmpfiles.d/screen-cleanup.conf 2024-08-27 14:31:45.000000000 +0000
+++ /etc/tmpfiles.d/screen-cleanup.conf 2024-08-27 14:31:44.000000000 +0000
@@ -1 +1,2 @@
-d /run/screen 0777 root utmp
+# This file is generated by /var/lib/dpkg/info/screen.postinst upon package configuration
+d /run/screen 1777 root utmp
[EXTENDED] /usr/lib/systemd/system/rc-local.service → /usr/lib/systemd/system/rc-local.service.d/debian.conf
[EXTENDED] /usr/lib/systemd/system/systemd-journald.service → /usr/lib/systemd/system/systemd-journald.service.d/nice.conf
[EXTENDED] /usr/lib/systemd/system/systemd-localed.service → /usr/lib/systemd/system/systemd-localed.service.d/x11-keyboard>
[EXTENDED] /usr/lib/systemd/system/systemd-logind.service → /usr/lib/systemd/system/systemd-logind.service.d/dbus.conf
[EXTENDED] /usr/lib/systemd/system/systemd-networkd-wait-online.service → /run/systemd/system/systemd-networkd-wait-online.>
[EXTENDED] /usr/lib/systemd/system/systemd-udevd.service → /usr/lib/systemd/system/systemd-udevd.service.d/syscall-architec>
[EXTENDED] /usr/lib/systemd/system/user@.service → /usr/lib/systemd/system/user@.service.d/10-login-barrier.conf
[EXTENDED] /usr/lib/systemd/system/user@.service → /usr/lib/systemd/system/user@.service.d/timeout.conf
9 overridden configuration files found.
getty
/dev/tty1
~ /dev/tty6
までの 仮想コンソール のデバイスファイルは、起動時にカーネルによって作成される。
OS が起動すると、SysVinit
もしくは systemd
が getty
(get tty)プロセスを起動する。
getty
の役割は以下を行うことにある。
- デバイスとしての端末を
open()
する-
open()
は システムコール の一つ
-
- シェルの標準入出力を
open()
した端末へ接続する - ユーザ名の入力を促すログイン用のプロンプトを表示する
-
login
プロセスを起動し、ユーザが入力した情報を渡すことでログインを実行する
getty
は /dev/tty1
、/dev/tty2
、 ... のデバイスファイルを open()
によってオープンし、戻り値として取得した ファイルディスクリプタ を次のように割り当てる。
ファイルディスクリプタ | 接続先 |
---|---|
0 (0 ) |
/dev/tty1 (キーボード) |
1 (標準出力) |
/dev/tty1 (画面出力) |
2 (標準エラー) |
/dev/tty1 (画面出力) |
これにより、シェルは 標準入力 を /dev/tty1
(キーボード)から受け取り、標準出力を /dev/tty1
(ディスプレイ)へと流せるようになる。
getty
はその後、下記のようなログインプロンプトを表示し、ユーザー名から入力された「ユーザ名」と「パスワード」を login
プロセスに渡す。login
プロセスは getty
によって起動される。
login
プロセスは、入力された情報による認証が完了すると、ユーザのデフォルトシェル(bash
など)起動する。
getty
プロセスはログアウトによって終了するが、/etc/inittab
によって再び起動する。
$ shutdown
$ shutdown -h now
$ shutdown -r now
$ shutdown -h 21:00
$ shutdown -c
$ chroot
change root
プロセスが参照するルートディレクトリ /
を、指定したディレクトリに変更することができる。
擬似的なルート環境を作ることができるため、修復、テストなどの用途で利用される。
$ chroot ルートとして見せたいディレクトリ