NVMe SSDにfault injectionしてみる
この記事は
Linux kernelのfalult injection機能の(特にNVMe SSDに関連する部分について)
ソースを読んだり、実際に使ってみたりする記事のうちの一つ
記事一覧
その1:fault injectionってなあに
その2:fault injection機能が埋まっている箇所のソースを読む
その3:NVMe SSDにfault injectionしてみる ★今回はこれ
NVMe SSDにfault injectionしてみる
環境準備
OSインストール
なんでもいいんですが
私はVirtualBox上にUbuntu22.04.3をインストールした
SATA(AHCI)コントローラーに接続されているHDDがシステムディスク
NVMeコントローラに接続されているSSDがデータディスク
システムディスクにfalult injectionするのはちょっと不安なので、
NVMe SSDはデータディスクとして準備するのがおすすめ
fault injection機能の有効化
Ubuntu22.04.3では、fault injectionは無効になっているため
機能を有効化するためにKernelをビルドする
Linux Kernelのソースを入手する
手順はUbuntuの公式Wiki (と自分の記憶)などを参考にしました
/etc/apt/source.listのdeb-srcの行のコメントをすべて外す
deb-src hogehoge
パッケージのリストを更新
apt update
適当な作業用ディレクトリに移動し、ソースのパッケージをダウンロード
apt-get source linux-image-$(uname -r)
以下三つのファイルが落ちてくるので
以下をたたいてUbuntu向けの修正が反映されたソースを生成する
dpkg-source -x linux_hoge.dsc
Linux Kernelをビルドする
kernelのビルドに必要なパッケージをインストールする
apt install make gcc flex bison libncurses-dev libelf-dev libssl-dev
ソースのルートディレクトリに移動
デフォルトのconfigファイルをKernelビルドに再利用するためコピー
cp /boot/config-hoge ./.config
fault injectionを有効にするよう.configを編集
CONFIG_FAULT_INJECTION=y
make oldconfigたたいてfault injection関係と思われるものはyを選択
Kernelのビルドとdpkgの作成
make -$(nproc) deb-pkg
ビルドしたKernelの適用
apt install linux-headers-hoge_amd64.deb apt install linux-headers-hoge_amd64.deb
再起動する(ビルドしたKernelで起動しなおす)
/sys/kernel/debug/nvme*が存在することを確認する
root@nodoguro-VirtualBox:/home/nodoguro# ls /sys/kernel/debug/nvme0 nvme0/ nvme0n1/
実践編
ターゲットの確認
ターゲットとなるディスクを確認しておく
今回は/dev/nvme0n1
root@nodoguro-VirtualBox:/home/nodoguro# parted -l Model: ATA VBOX HARDDISK (scsi) Disk /dev/sda: 107GB Sector size (logical/physical): 512B/512B Partition Table: gpt Disk Flags: Number Start End Size File system Name Flags 1 1049kB 538MB 537MB fat32 EFI System Partition boot, esp 2 538MB 107GB 107GB ext4 Error: /dev/nvme0n1: unrecognised disk label Model: ORCL-VBOX-NVME-VER12 (nvme) Disk /dev/nvme0n1: 26.8GB Sector size (logical/physical): 512B/512B Partition Table: unknown Disk Flags:
fault injectionしてみる
今回は公式ドキュメントのnvme-fault-injectionに記載のある以下3種のエラー注入を試してみる
Example 1:Inject default status code with no retry
Example 2: Inject default status code with retry
Example 3: Inject an error into the 10th admin command
今回は、ddコマンドでランダムなデータを書き込んでテストする
正常に終了した場合は以下のようになる
root@nodoguro-VirtualBox:/home/nodoguro# dd if=/dev/urandom of=/dev/nvme0n1 count=10000 10000+0 records in 10000+0 records out 5120000 bytes (5.1 MB, 4.9 MiB) copied, 0.526876 s, 9.7 MB/s
Example 1:Inject default status code with no retry
100%の確率で1度だけfault injectionする
リトライしない
設定
echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability
結果
root@nodoguro-VirtualBox:/home/nodoguro/source# dd if=/dev/urandom of=/dev/nvme0n1 count=10000 dd: writing to '/dev/nvme0n1': Input/output error 1+0 records in 0+0 records out 0 bytes copied, 0.00110659 s, 0.0 kB/s
エラーでこけていて期待通り
Example 2: Inject default status code with retry
100%の確率で1度だけfault injectionする
リトライする
設定
echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability echo 0 > /sys/kernel/debug/nvme0n1/fault_inject/dont_retry
結果
root@nodoguro-VirtualBox:/home/nodoguro/source# dd if=/dev/urandom of=/dev/nvme0n1 count=10000 10000+0 records in 10000+0 records out 5120000 bytes (5.1 MB, 4.9 MiB) copied, 0.600538 s, 8.5 MB/s
リトライするのでエラー見えないで期待通り
Example 3: Inject an error into the 10th admin command
しばらくしてから100%の確率で1度だけfault injectionする
※admin commandと書いてあるが、他と合わせてddで試す
設定
echo 100 > /sys/kernel/debug/nvme0n1/fault_inject/probability echo 10 > /sys/kernel/debug/nvme0n1/fault_inject/space echo 1 > /sys/kernel/debug/nvme0n1/fault_inject/times
結果
root@nodoguro-VirtualBox:/home/nodoguro/source# dd if=/dev/urandom of=/dev/nvme0n1 count=10000 dd: writing to '/dev/nvme0n1': Input/output error 73+0 records in 72+0 records out 36864 bytes (37 kB, 36 KiB) copied, 0.00613897 s, 6.0 MB/s
最初はIO成功、途中でIOが失敗しており期待通り
最後に
NVMe SSDへのfault injectionを実際に使ってみるところまでお試しできた
当初の予定通り、使ってみるところまでできて良かった
何か調べたいときに適したツールでサクッと調査できるしぐさに常に憧れがあるが
こういった、Linux Kernelに埋まっている、今はまだ知らない機能たちを触っていくのがそれに近づく一歩な気がしている
(これに関しては使うにはKernelのビルドが必要で超時間がかかっちゃうけどね..)