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の起動メニューを生成する]
(https://www.atmarkit.co.jp/ait/articles/1902/01/news045.html)

[UEFIのブートプロセスについて]
(https://blog.tiqwab.com/2018/07/29/uefi-boot.html)

[systemcサービスユニット覚書]
(https://qiita.com/ch7821/items/369090459769c603bb6b)

[SYSTEMDターゲットでの作業]
(https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-targets)

[ランレベルはどこへ行った？]
(https://www.bnote.net/centos/runlevel.html)