Help us understand the problem. What is going on with this article?

Linux起動プロセスについて

起動の流れ

1. BIOS/UEFI

BIOS(Basic Input/Output System)
- 旧来のシステム
- 起動ドライブの容量制限2TB
- メモリのチェック
- HW設定の読み込み
- 起動デバイスのチェック
- 起動デバイスのMBR内のブートローダの実行

UEFI(Unified Extensible Firmware Interface)
- BIOSの代替となるシステム
- 起動ドライブの容量制限なし
- GUIベースのセットアップ画面も利用可能

2. MBR/GPT

(BIOSの場合)
起動デバイスのはじめに含まれるMBR(Master Boot Record)を実行
MBRには以下が含まれる

  • OSを起動するブートローダの一部
  • パーティションテーブル(基本パーティション情報)

(UEFIの場合)
GPT(GUID Partition Table)でパーティションを管理
ブートローダは/boot/efi配下に格納される

3. ブートローダ

GRUB(Grand Unified Bootloader)
GRUB2
指定されたパーティションからカーネルをロードし、制御を渡す

4. カーネル

以下を行う。カーネル起動中のメッセージはdmesgコマンドで確認可能

  • メモリの初期化
  • システムクロックの設定
  • IRQの設定
  • ルートパーティションのマウント
  • initの実行

サービス管理

旧:SysVinit
新:systemd

ブートローダ

GRUB Legacy(開発終了しているため詳細は割愛)

設定ファイル: /boot/grub/menu.lst

GRUB2

設定ファイル:
(BIOSの場合) /boot/grub/grub.cfg
(UEFIの場合) /boot/efi/EFI/<id>/grub.cfg

設定ファイルを直接作成、編集せずに以下の手順で作成する。

設定ファイルの作り方

/etc/default/grubに設定を書き込み、grub-mkconfigコマンド(またはgrub2-mkconfig)実行でgrub.cfgを作成する

CentOS7のデフォルトではまだ設定ファイルは無い
# ll /boot/efi/EFI/centos/
total 0
元となる設定ファイル
# cat /etc/default/grub 
GRUB_TIMEOUT=1
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="no_timer_check console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 elevator=noop crashkernel=auto"
GRUB_DISABLE_RECOVERY="true"
パラメータ 説明
GRUB_TIMEOUT OS起動までの秒数
GRUB_DISTRIBUTOR ディストリビューション情報
GRUB_DEFAULT ブート時に最初に選択される項目を定義する変数(savedの場合は前回洗濯した項目を使用)
GRUB_DISABLE_SUBMENU カーネルをサブメニューにグループ化する機能を無効化
GRUB_TERMINAL_OUTPUT 表示出力先を指定
GRUB_CMDLINE_LINUX カーネルコマンドラインに与える引数を
GRUB_DISABLE_RECOVERY リカバリー用のメニューを生成しない
grub.cfgの作成
# grub2-mkconfig  -o /boot/efi/EFI/centos/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.16.73
Found initrd image: /boot/initramfs-3.16.73.img
Found linux image: /boot/vmlinuz-3.10.0-957.12.2.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-957.12.2.el7.x86_64.img
done
# ll /boot/efi/EFI/centos/
total 8
-rw-r--r-- 1 root root 4248  9月 17 15:05 grub.cfg

その他のブートローダ

以下のブートローダがsyslinuxパッケージに含まれる

ブートローダ 説明
SYSLINUX FATファイルシステム(USBなど)からカーネル起動する時
ISOLINUX ISOファイルシステム(CD-ROMなど)からカーネル起動する時
PXELINUX PXEを使ってネットワークブートする時

PXE(Preboot eXecution Environment): ネットワークブートの規格

  1. DHCPによりネットワーク情報取得
  2. TFTPでブートプログラムをサーバからダウンロード&起動

といった方法で起動できる。
特徴は以下の通り

  • クライアント側でインストールメディア不要
  • ディスクも不要(メモリやNFSを代わりに利用できる)
  • PXE準拠のネットワークインターフェイスが必要

SysVinitでの起動プロセス

  1. 最初に実行されるプロセスであるinit(PIDは1)が/etc/inittabを読み込む

/etc/inittabの書式
ID:処理を行うランレベル:アクション指示子(処理を行うタイミング):処理コマンド(実行するプロセス)
例: 2:2345:respawn:/sbin/mingetty tty2
ランレベル2345の場合に、respawn(指定したプロセスが終了すれば再起動させる)でプロセスを実行
アクション指示子には
initdefault:デフォルトのランレベルを指定
boot:システム起動時実行され、終了を待たずに次を実行
bootwait:システム起動時に実行され、終了するまで待ってから次の処理を実行
ctlaltdel:Ctrl+Alt+Delが押下されるなど、SIGINTがinitに送られた時に実行

2 起動時のランレベルに応じて/etc/rc[0-6].dディレクトリ内のサービスを実行
(initが/etc/rc.sysinitを読み込み、/etc/rcスクリプトを実行)

# ll /etc/rc3.d/
total 0
lrwxrwxrwx. 1 root root 20  6月  1 17:14 K50netconsole -> ../init.d/netconsole
lrwxrwxrwx. 1 root root 17  6月  1 17:14 S10network -> ../init.d/network

「S」で始まるもの:このランレベルで起動するサービス
「K」で始まるもの:このランレベルになった時に終了するサービス

SysVinitでのサービス自動起動

サービスの自動起動設定の確認

ランレベル毎にon/offが表示される

#chkconfig --list
netconsole      0:off   1:off   2:off   3:off   4:off   5:off   6:off
network         0:off   1:off   2:on    3:on    4:on    5:on    6:off
設定の変更
# chkconfig network off
# chkconfig --list
netconsole      0:off   1:off   2:off   3:off   4:off   5:off   6:off
network         0:off   1:off   2:off   3:off   4:off   5:off   6:off

# chkconfig --level 2345 network on
# chkconfig --list
netconsole      0:off   1:off   2:off   3:off   4:off   5:off   6:off
network         0:off   1:off   2:on    3:on    4:on    5:on    6:off

systemdでの起動プロセス

systemdプロセスが起動し、各サービスを管理する
※initプロセスではないので注意!

systemd関連の主なデーモンプロセス

プロセス 説明
systemd メインプロセス
systemd-journal ログ管理
systemd-logind ログイン処理
systemd-udevd デバイス動的検知

systemdではUnitと呼ばれる処理単位で動作する。

Unitの主な種類(拡張子)

プロセス 説明
service サービスの起動
device 各デバイスを表す(udevのデバイス認識時に自動作成)
mount ファイルシステムのマウント(/etc/fstabにより自動作成)
swap スワップ領域の有効化(/etc/fstabにより自動作成)
target 複数のUnitのグループ化
  1. default.targetの実行 ↓の例ではmulti-user.target(従来のランレベル2,3,4相当)で起動するサービスをまとめたUnitにリンクしている

※元々、ランレベル4は未使用でしたが、これに対応するようです

# ll /etc/systemd/system/default.target
lrwxrwxrwx. 1 root root 37  6月  1 17:17 /etc/systemd/system/default.target -> /lib/systemd/system/multi-user.target
ランレベル ランレベルの説明 ターゲット
0 システム停止 poweroff.target
1 シングルユーザモード(rootのみログイン可能) rescue.target
2 マルチユーザモード(ネットワークなし) multi-user.target
3 マルチユーザモード(ネットワークあり) multi-user.target
4 未使用 multi-user.target
5 マルチユーザモード(グラフィカルログイン) graphical.target
6 システム再起動 reboot.target
systemdでのサービス管理

systemctlコマンドによりサービスの起動・停止・再起動・再読み込み・確認などを行う。

使い方: systemctl サブコマンド [Unit名] [-t 種類]

サブコマンド 説明
start サービス起動
stop サービス停止
restart サービス再起動
reload サービス再読み込み
status,is-active サービスの稼働状況確認
enable サービスを自動起動するように設定
disable サービスを自動起動しないように設定
list-units 起動しているUnitの表示
list-unit-files 全てのUnitを表示
list-dependencies 指定したサービスが必要とするサービスの表示

サービスの起動確認

# systemctl status network
● network.service - LSB: Bring up/down networking
   Loaded: loaded (/etc/rc.d/init.d/network; bad; vendor preset: disabled)
   Active: active (exited) since 水 2019-09-11 22:39:49 UTC; 4 days ago
     Docs: man:systemd-sysv-generator(8)

 9月 11 22:39:48 webapp1 systemd[1]: Starting LSB: Bring up/down networking...
 9月 11 22:39:49 webapp1 network[2465]: Bringing up loopback interface:  [  OK  ]
 9月 11 22:39:49 webapp1 network[2465]: Bringing up interface eth0:  [  OK  ]
 9月 11 22:39:49 webapp1 network[2465]: Bringing up interface eth1:  [  OK  ]
 9月 11 22:39:49 webapp1 systemd[1]: Started LSB: Bring up/down networking.
# systemctl is-active network
active

自動起動の設定(status確認の時にLoaded:の行がdisabledからenabledになっている)

# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: inactive (dead)
# systemctl enable nginx
Created symlink from /etc/systemd/system/multi-user.target.wants/nginx.service to /usr/lib/systemd/system/nginx.service.
# systemctl status nginx
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

systemctlでの自動起動の設定により、/etc/systemd/systemディレクトリ配下のファイルが修正される
Unitの設定ファイル自体は/usr/lib/systemd/system/配下に格納されている

Unit設定ファイル

以下にnginxのUnit設定ファイル(nginx.target)の例を示す

パラメータ 説明
After 指定したUnit以降に起動する
Type サービスのタイプ(simple/forking/oneshot/notify/dbus)
ExecStartPre startの前に実行するコマンド
KillMode ExecStop実行後にSIGNALを送信する先(control-group, process, mixed, none)
KillSignal KillModeで指定した対象に送信するシグナル
PrivateTmp trueとすると、サービス専用の独立した/tmpと/var/tmpが用意される
# cat /usr/lib/systemd/system/nginx.service 
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target
systemdでのログ管理

journalctlコマンドでsystemdのログが確認できる

使い方: journalctl [オプション]

オプション無しだと全てのログがページ毎に表示される
# journalctl 
-- Logs begin at 水 2019-09-11 22:39:38 UTC, end at 月 2019-09-16 09:20:01 UTC. --
 9月 11 22:39:38 webapp1 systemd-journal[94]: Runtime journal is using 4.0M (max allowed 24.4M, trying to leave 36.6M free of 240.0M available → current limit 24.4M).
 9月 11 22:39:38 webapp1 kernel: Initializing cgroup subsys cpuset
 9月 11 22:39:38 webapp1 kernel: Initializing cgroup subsys cpu
 9月 11 22:39:38 webapp1 kernel: Initializing cgroup subsys cpuacct
 9月 11 22:39:38 webapp1 kernel: Linux version 3.16.73 (vagrant@webapp1) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #2 SMP Wed Sep 11 23:12:25 UTC 2019
 9月 11 22:39:38 webapp1 kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-3.16.73 root=UUID=8ac075e3-1124-4bb6-bef7-a6811bf8b870 ro no_timer_check console=tty0 console=ttyS0,1152
 9月 11 22:39:38 webapp1 kernel: e820: BIOS-provided physical RAM map:
(以下省略)
サービスの指定
# journalctl -u network
-- Logs begin at 水 2019-09-11 22:39:38 UTC, end at 月 2019-09-16 09:30:01 UTC. --
 9月 11 22:39:48 webapp1 systemd[1]: Starting LSB: Bring up/down networking...
 9月 11 22:39:49 webapp1 network[2465]: Bringing up loopback interface:  [  OK  ]
 9月 11 22:39:49 webapp1 network[2465]: Bringing up interface eth0:  [  OK  ]
 9月 11 22:39:49 webapp1 network[2465]: Bringing up interface eth1:  [  OK  ]
 9月 11 22:39:49 webapp1 systemd[1]: Started LSB: Bring up/down networking.
新しい順、プライオリティの指定、行数の指定
# journalctl -r -p err
-- Logs begin at 水 2019-09-11 22:39:38 UTC, end at 月 2019-09-16 09:30:01 UTC. --
 9月 11 22:39:49 webapp1 rsyslogd[2663]: imjournal: loaded invalid cursor, seeking to the head of journal  [v8.24.0-34.el7 try http://www.rsyslog.com/e/2027 ]
 9月 11 22:39:47 webapp1 kernel: snd_intel8x0 0000:00:05.0: measure - unreliable DMA position..
 9月 11 22:39:47 webapp1 kernel: snd_intel8x0 0000:00:05.0: measure - unreliable DMA position..
 9月 11 22:39:47 webapp1 kernel: snd_intel8x0 0000:00:05.0: measure - unreliable DMA position..
systemdのログの場所

ログ/var/run/log/journal/配下のバイナリファイルに保存されている

# ll /var/run/log/journal/
total 0
drwxr-s---+ 2 root systemd-journal 60  9月 11 22:39 f4cadd827379494cba52149ae2237f26

この場合システム再起動によりログは消えるが、残したい場合は/var/log/journalctlディレクトリを作成し、/etc/systemd/journald.confに以下を記載する(SystemMaxUseはログの最大容量)
設定変更後はsystemd-journaldを再起動する

[Journal]
Storage=persistent
SystemMaxUse=100M

参考

【grub2-mkconfig/grub-mkconfig 】コマンド――GRUB 2の起動メニューを生成する

UEFIのブートプロセスについて

systemcサービスユニット覚書

SYSTEMDターゲットでの作業

ランレベルはどこへ行った?

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away