LPIC201対策 - カーネルの管理とトラブルシューティング

# この記事について
Linux Level 2 取得を目標としている筆者です。
先日 Level 1 を取得しましたが、短期詰め込みの暗記がしんどかったので、Level2はじっくり時間をかけていいから、ちゃんと理解してやっていきたい。

一方で、暗記も暗記で重要。

ということで、理解を深めるためにと、暗記しやすいように、両方の目的で、覚えたことを Qiita に整理してまとめながら受験対策することにしました。

# この分野で覚えること

## ファイル・ディレクトリ関連

| パス | 中身 |
|:-|:-|
| /usr/src/linux/Makefile  | カーネルのビルドプロセスを制御する様のファイル  |

### /proc/ 配下

`/proc/` ディレクトリ配下は、プロセス、HW、システムリソースなどの情報を扱うための擬似的なファイルシステムになっている。

| パス | 中身 |
|:-|:-|
| /proc/bus/pci/devices  |PCIデバイスの情報  |
| /proc/bus/usb/devices  |USBデバイスの情報  |
| /proc/dma  |lsdev の参照先  |
| /proc/interrupts  |〃  |
| /proc/ioports  |〃  |
| /proc/sys/ |カーネルパラメータを操作するための仮想ファイルが入っている  |
| /proc/version |バージョン情報を示すファイル  |

### カーネルパラメータの置き場所（恒久）

**恒久的的な** カーネルパラメータの置き場は、以下のファイル／ディレクトリに置かれる。

| パス | 中身 |
|:-|:-|
| /etc/sysctl.conf  | カーネルパラメータを記述できるファイル  |
| /etc/sysctl.d/  | カーネルパラメータの設定ファイルを置くディレクトリ  |

後述する `sysctl -w` コマンドや `/proc/sys/` 配下の仮想ファイルを置き換えることにより、**動作中にカーネルパラメータの値を即時変更する**ことはできるが、この方法だと再起動時に設定が元に戻ってしまう。

### その他のディレクトリ・ファイル

| パス | 中身 |
|:-|:-|
| /etc/udev/udev.conf  | udev本体の設定ファイル  |
| /etc/udev.rules.d/  | udevのルールファイルを置くディレクトリ  |
| /etc/modprobe.conf  | modprobeの設定ファイル  |
| /etc/modprobe.d/  | 〃を複数設置できるディレクトリ(.confで終わるファイルを設定ファイルとみなす)|
| /lib/modules/x.x.x/modules.dep  | modprobe コマンドが使用する、依存関係情報が書かれたファイル  |
| /lib/modules/x.x.x/modules.dep.bin  | ↑のバイナリ  |


`modprobe.conf` の書式
`alias mod1 mod2` -> modprobe mod1 を実行した際に、mod2がロードされるようにしたい場合の設定。

## sysctl コマンド

- カーネルパラメータの値を参照できる。
- カーネルパラメータの値を、**動作中に一時的に変更し即時反映**することができる。（再起動時にリセットされる）

| オプション | 意味 |
|:-|:-|
| [オプションなし] カーネルパラメータ名  | 指定したカーネルパラメータの値を表示 |
| -a  | カーネルパラメータと値の一覧を表示 |
| -w | パラメータ=値を続けて、パラメータ値を設定 |

### カーネルパラメータの仮想ファイル（/proc/sys　配下）

/proc/sys 以下に、パラメータの設定値に相当する仮想ファイルが入っている。

たとえば、vmのスワップの積極性を設定する vm.swappiness というパラメータであれば、 `/proc/sys/vm/swappiness` という仮想ファイルに現在の設定値が入っている。

上記のように、仮想パラメータの path の /proc/sys 以下の部分を、スラッシュをドットに読み替えたものがカーネルパラメータ名となる。

これらカーネルパラメータを参照・更新するには、以下の方法がある。

#### カーネルパラメータの参照方法

カーネルパラメータの設定値の一覧は、`sysctl -a` で参照できる。
特定のカーネルパラメータの値を参照するには、この結果を grep する他に、以下の方法がある。

##### 方法① /proc/sys 配下のファイルを参照する

`cat /proc/sys/vm/swappiness` のように、該当の仮想ファイルを cat で参照する方法。

##### 方法② sysctl コマンドを使う

`sysctl vm.swappiness` のように、該当のカーネルパラメータをsysctl コマンドで参照する方法。

#### カーネルパラメータの更新方法

以下の方法で更新すると、**即時反映**される。
（特に改めてコマンドたたいたりする必要なし）

ただし、以下の方法で更新した場合は**再起動時にリセット**される。恒久的に変更したい場合は「カーネルパラメータの置き場所（恒久）」に記載のファイル or ディレクトリの値を更新する必要がある。

##### 方法① /proc/sys 配下のファイルを更新する

`echo 10 > /proc/sys/vm/swappiness` のように、該当の仮想ファイルを更新する方法。

##### 方法② sysctl コマンドを使う

`sysctl -w vm.swappiness=10` のように、該当のカーネルパラメータをsysctl コマンドで参照する方法。

### ブート時に参照されるカーネルパラメータ

`etc/sysctl.d/` 配下に `.conf` で終わるファイルを置き、その中に `パラメータ名=値` の書式で定義しておくと、そのカーネルパラメータが起動時に読み込まれる。

ここの値を即時反映したい場合は、以下のコマンドをたたくらしい。
（`etc/sysctl.d/README.txt` より。試験に出るかはわからん。）

```shell
# Debian系の場合
deb-systemd-invoke restart procps.service

# その他
service procps force-reload
```


## modprobeコマンド

### modprobe コマンドのオプション

| オプション | 意味 |
|:-|:-|
| [オプションなし] モジュール名 | モジュールを、依存関係を解決してロード |
| -r モジュール名 | モジュールを、依存関係を解決してアンロード |
| -f | 強制的に操作を行う |
| --show-depends モジュール名 | 指定したモジュールの依存関係を表示 |

### modprobe コマンドの実行に必要なファイル

modprobeコマンドは、以下のファイルとバイナリを使用するため、これらがないとたたけない。

| パス | 中身 |
|:-|:-|
| /lib/modules/x.x.x/modules.dep  | modprobe コマンドが使用する、依存関係情報が書かれたファイル<br><br>書式<br>`モジュールのpath : 依存するモジュール1 依存するモジュール2 ...`  |
| /lib/modules/x.x.x/modules.dep.bin  | ↑のバイナリ  |

これらを誤って消してしまった場合は、depmodコマンドを使って作る。

### modprobe コマンドの設定ファイル

modprobe コマンドは、以下の設定ファイルに基づいて実行される。

| パス | 中身 |
|:-|:-|
| /etc/modprobe.conf  | modprobeの設定ファイル  |
| /etc/modprobe.d/  | 〃を複数設置できるディレクトリ(.confで終わるファイルを設定ファイルとみなす)|

これらの設定ファイルの書式を以下に例示します。

```shell
### alias : カーネルモジュールに別名をつける

# moda を実行したら、modbをロードしてね
alias moda modb

### install, remove : カーネルモジュールのインストール・アンロードにあたって実行するコマンドを設定  

# modxをインストールするときは、/bin/install.sh を実行してね
install modx /bin/install.sh
# modxをアンロードするときは、/bin/remove.sh を実行してね
remove modx /bin/remove.sh

### options : カーネルモジュールのデフォルトパラメータを設定 
# mody を実行するときは、 param1=0, param2=2 をデフォルトのパラメータとしてね
options mody parm1=0 parm2=2

### blacklist : ロードしたくないカーネルモジュールを指定

# ponkotsu-mod をロードしないでね
blacklist ponkotsu-mod
```

## modinfo コマンドとそのオプション

`modinfo` 指定したカーネルモジュールの情報を表示する

| オプション | 意味 |
|:-|:-|
| [オプションなし] | 詳細情報をすべて（ファイル名、解説、作者、ライセンス、パラメータ）表示 |
| -d, --description | モジュールの説明 |
| -l, --license | モジュールのライセンス |
| -n, --filename | モジュールのファイルパス |
| -p, --parameters | モジュールがサポートしているパラメータ |

たとえば `modinfo lp` を実行した場合の結果は以下。

```shell
ubuntu@ip-10-0-0-xx:~$ modinfo lp
filename:       /lib/modules/6.2.0-1017-aws/kernel/drivers/char/lp.ko
license:        GPL
alias:          char-major-6-*
srcversion:     75E9B702288AADB40078617
depends:        parport
retpoline:      Y
intree:         Y
name:           lp
vermagic:       6.2.0-1017-aws SMP mod_unload modversions
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        44:95:96:F6:F8 ... 略
sig_hashalgo:   sha512
signature:      74:0B:F0:74:CD:C7:54 ... 略
parm:           parport:array of charp
parm:           reset:bool
```

## udev関連コマンド

| コマンド | 中身 |
|:-|:-|
|udevcontrol| udev を操作し、動作・停止などを行う |
|udevinfo | udevが認識しているデバイス情報（デバイスファイルのパスなど）を表示 |
| udevmonitor  | udevの動作を監視し、ルールファイルに基づいてカーネルイベントなどをコンソールへ出力 |
|udevadm サブコマンド|上記を統合した新しいコマンド <br>サブコマンドには、control, info, monitor などが入る|

## その他のコマンド

| コマンド | 中身 |
|:-|:-|
| lsmod  | ロードされているカーネルモジュールの一覧を表示  |
| rmmod  | 指定したカーネルモジュールだけを、依存関係を考慮せずにアンロード |
| insmod  | 指定したカーネルモジュールを、依存関係は考慮せずにロード |  
| depmod  | カーネルの依存関係ファイル（modules.dep）を更新  |
| lspci  | PCIデバイスの情報を表示 |
| lsusb  | USBデバイスの情報を表示 |
| lsdev  | ハードウェアに関する情報を一覧表示 |
|udevadm|udevの動作を統合的に操作したり、情報を表示する|
| udevadm monitor  | udevの動作を監視し、ルールファイルに基づいてカーネルイベントなどをコンソールへ出力 |
| udevmonitor  | 〃 |

## その他の暗記事項

### bzImage, zImage

#### 共通点
- カーネルイメージ（ファイルとして保存されたカーネル本体のデータ）である
- gzip で圧縮され、自己伸長できるようになっている

#### 相違点

| 観点 | zImage | bzImage |
|:-|:-|:-|
| サイズ  | 512KBまで |1MB超えてもOK|
| 対応するカーネルバージョン | 右記以前 | 2.6系、3.x系|
| 利用するメモリ空間 | ローメモリのみ | ハイメモリ（ユーザースペース）を利用可能|

### その他

| 用語 | 意味 |
|:-|:-|
| udevd  | 接続されたHWに対するデバイスファイルを自動的に作成するプロセス（HWの検出はカーネルが行う）  |
| .ko  | カーネルモジュールファイルの拡張子 |


# 以上！

勉強が進んだら適宜追記・修正などしていきます。