GNU/Linux >> Linux の 問題 >  >> Linux

I/Oエラーの原因となる特殊ファイル

Stack Overflow と Server Fault には、これに対する優れた回答が既にありますが、いくつかの手法が欠けていました。作業を楽にするために、VM/Linux ブロック デバイス/Linux ファイルシステム/Linux ユーザー空間ライブラリ I/O 障害挿入メカニズムのリストを次に示します。

  • Device Mapper の error/flakey/delay/dm-dust デバイスを使用して、合成済みブロック デバイスからのエラー/破損を返したり、IO を遅延/分割したりします (カーネル、カーネルがデバイス マッパー サポートで構築されている必要があり、適切な追加デバイスマッパー モジュール (dm-dust はカーネル>=5.2 でのみ使用可能) であり、デバイス マッパー ユーザー空間ビットを備えています)。
  • md のフォールト パーソナリティを使用して、合成されたブロック デバイスに対して定期的なフォールト インジェクションを実行します。 --layout を参照してください 構成方法については、mdadm man ページのオプションを参照してください (カーネルお​​よび mdadm ユーザー空間ビット)。
  • libfiu を使用して、POSIX API 呼び出しでフォールト挿入を実行します (ユーザー空間、LD_PRELOAD で使用できます) ).
  • Linux カーネルのフォールト インジェクターを使用して、基盤となるブロック デバイスにエラーを挿入します (カーネル、カーネルが FAIL_MAKE_REQUEST=y でビルドされている必要があります)。 ).
  • SystemTap を使用してフォールト インジェクションを実行します (カーネル。カーネルには多くの要素が組み込まれている必要があります)。
  • CarybdeFS または PetardFS (FUSE 経由のユーザー空間) を使用して、ファイル システムの障害を挿入します。
  • フォールト インジェクション (カーネル) を実行する Linux scsi_debug ドライバーを使用して、合成ブロック デバイスを作成します。
  • QEMU 内でシステムを実行し、QEMU を使用して、blkdebug ドライバー (VM) を使用してブロック デバイス エラーを挿入します。
  • null_blk デバイスのオプションを使用して合成ブロック デバイスを作成し、障害を挿入します (カーネル>=4.14 ですが、タイムアウト確率などのオプションは 4.17 まで到着せず、カーネルが BLK_DEV_NULL_BLK_FAULT_INJECTION=y でビルドされている必要があります。 ).
  • delay などの NBDkit フィルターを介してホストに提供される、合成されたネットワーク ブロック デバイスを作成します。 または error nbd-client 経由でブロック デバイスを接続します。 (カーネル + NBD ユーザー空間ビット、NBD サポート付きでビルドされたカーネル>=4.18、nbdclient>=3.18 および nbdkit>=1.8.1 を推奨 - 20 分前後の NBDKit デモ ビデオを参照してください)。

おまけ:SQLite にはエラーをシミュレートするための VFS ドライバーがあるため、テスト範囲を広げることができます。

関連:

  • テスト中に故障したディスクをシミュレートするにはどうすればよいですか?
  • 読み取りエラーのある障害のあるブロック デバイスをシミュレートしますか?
  • 読み取りエラーを生成する
  • Linux で意図的に I/O エラーを引き起こしますか?

dmsetup を使用できます error のいずれかを使用してデバイス マッパー デバイスを作成します。 または flakey 失敗をシミュレートするターゲット。

dmsetup create test --table '0 123 flakey 1 0 /dev/loop0'

ここで、123 はデバイスの長さ (セクター単位) で、/dev/loop0 はエラーをシミュレートする元のデバイスです。エラーの場合、常にエラーを返すため、後続の引数は必要ありません。


I/O のフォールト注入メカニズムが必要です。

Linux では、事前のセットアップを必要とせず、異常なエラーを生成する方法を次に示します (EIO 「入出力エラー」ではなく、ESRCH 「そのようなプロセスはありません」)。

cat /proc/1234/mem

ここで、1234 は、テストしているプロセスと同じユーザーとして実行されているプロセスの PID ですが、そのプロセス自体ではありません。 /proc/$pid/mem を考えてくれた rubasov の功績 .

プロセス自体の PID を使用すると、EIO を取得できますが、プロセスのメモリにマップされていない領域から読み取っている場合に限ります。最初のページはマップされないため、ファイルを順番に読み取る場合は問題ありませんが、ファイルの途中を直接シークするデータベース プロセスには適していません。

root としてさらにセットアップを行うと、デバイス マッパーを利用して、有効なセクターと不良セクターを含むファイルを作成できます。

もう 1 つのアプローチは、小さな FUSE ファイルシステムを実装することです。 EIO は、ユーザー空間のファイルシステム ドライバーが何か問題を起こした場合のデフォルトのエラー コードであるため、簡単に達成できます。 Perl と Python の両方のバインディングには、開始するための例が付属しています。既存のファイルをほとんどミラーリングしながら、慎重に選択した場所に EIO を挿入するファイルシステムをすばやく作成できます。既存のそのようなファイルシステム:petardfs (記事) がありますが、すぐに使えるかどうかはわかりません。

さらに別の方法は LD_PRELOAD です ラッパー。既存のものは Libfiu (ユーザー空間でのフォールト インジェクション) です。これは、POSIX API 呼び出しをオーバーロードするライブラリをプリロードすることによって機能します。単純なディレクティブまたは任意の C コードを記述して、通常の動作をオーバーライドできます。


Linux
  1. Python で Linux デバイス ファイルに対して低レベルの I/O を実行するにはどうすればよいですか?

  2. Linux での I/O エラー:root としてディレクトリを削除できません

  3. Linux I/O レイテンシーのデバッグ

  1. デバイスファイルとデバイスドライバーの違い

  2. カーネル構成ファイルはどこに保存されますか?

  3. プロセスの合計 I/O コスト

  1. Linux I / O(入力/出力)リダイレクトの仕組みの基本を学ぶ

  2. 実際にコマンドである仮想ファイルを作成しますか?

  3. Linux –高I / Oの原因となる特定のファイルを決定しますか?