とにかく、Linuxで意図的にブロックデバイスにI/Oエラーを報告させたり、テスト目的でエラーをシミュレートしたりすることはありますか?
はい、デバイスマッパーでこれを行う非常にもっともらしい方法があります。
デバイスマッパーは、ブロックデバイスを選択した新しいマッピング/順序に再結合できます。 LVMはこれを行います。また、障害のあるディスクを模倣する「フレーク」やディスクの障害のある領域をシミュレートする「エラー」など、他のターゲット(一部は非常に斬新なもの)もサポートしています。
意図的にIOブラックホールが存在するデバイスを構築すると、交差時にIOエラーが報告されます。
まず、ターゲットとして使用する仮想ボリュームを作成し、ブロックデバイスとしてアドレス可能にします。
dd if=/dev/zero of=/var/lib/virtualblock.img bs=512 count=1048576
losetup /dev/loop0 /var/lib/virtualblock.img
したがって、これを開始するには、「穴」を開ける仮想ブロックデバイスの基礎となる512Mファイルを作成します。ただし、まだ穴はありません。 mkfs.ext4 /dev/loop0
を使用すると、完全に有効なファイルシステムが得られます。
したがって、このブロックデバイスを使用するdmsetupを使用して、いくつかの穴がある新しいデバイスを作成します。ここに最初の例があります
dmsetup create errdev0
0 261144 linear /dev/loop0 0
261144 5 error
261149 787427 linear /dev/loop0 261139
これにより、「errdev0」というデバイスが作成されます(通常は/ dev/mapperにあります)。 dmsetup create errdev0
と入力すると、標準入力を待機し、^ Dが入力されると終了します。
上記の例では、ループデバイスのセクター261144に5セクターホール(2.5kb)を作成しました。次に、通常どおりループデバイスを続行します。
このスクリプトは、ランダムな場所に穴を配置するテーブルを生成しようとします(およそかなりランダムですが)。
#!/bin/bash
start_sector=0
good_sector_size=0
for sector in {0..1048576}; do
if [[ ${RANDOM} == 0 ]]; then
echo "${start_sector} ${good_sector_size} linear /dev/loop0 ${start_sector}"
echo "${sector} 1 error"
start_sector=$((${sector}+1))
good_sector_size=0
else
good_sector_size=$((${good_sector_size}+1))
fi
done
echo "${start_sector} $((${good_sector_size}-1)) linear /dev/loop0 ${start_sector}"
このスクリプトでは、512Mbデバイスも作成済みであり、仮想ブロックデバイスが/dev/loop0
上にあると想定しています。
このデータをテーブルとしてテキストファイルに出力し、dmsetup create errdev0
にパイプするだけです。
デバイスを作成したら、通常のブロックデバイスのように、最初にデバイスをフォーマットしてからファイルを配置することで、デバイスの使用を開始できます。ある時点で、実際にIO仮想デバイスの穴であるセクターにぶつかったときに、いくつかのIO問題に遭遇するはずです。
完了したら、dmsetup remove errdev0
を使用してデバイスを削除します。
IOエラーが発生する可能性を高くしたい場合は、より頻繁に穴を追加するか、作成する穴のサイズを変更できます。特定のセクションにエラーを配置すると、問題が発生する可能性があります。 get-goの32MBのデバイスへのIEでは、extが通常行うスーパーブロックを書き込むことができないため、フォーマットは機能しません。
おもしろい-実際にはlosetup
してからmkfs.ext4 /dev/loop0
を実行して、データを入力するだけです。そこに素敵なファイルシステムができたら、ファイルシステムをアンマウントし、dmsetupを使用していくつかの穴を追加し、それを再マウントします!
出力が失敗した場合のプログラムの堅牢性を確認するには、書き込み時に常に「ENOSPACE」を返す疑似デバイス/dev/full
を使用できます。
$ dd if=/dev/zero of=/dev/full
dd: writing to `/dev/full': No space left on device
1+0 records in
0+0 records out
テストする対象によって異なります。 LD_PRELOAD
edライブラリを使用すると、アプリケーションをだまして、たとえば「すべての書き込みがENOSPC
またはEIO
で失敗する」などと考えることができます。
あなたはああそう多くの興味深い方法でそれを行うことができます。 https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt を参照してください
パーティションテーブルを変更して、パーティションを実際より大きくすることもできます。これはおそらくI/Oエラーを引き起こします。または、ディスクがホットプラグ可能な場合は、1つだけ引き出すことができます。