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


13

不可欠なSQLite DBファイルの読み取りに失敗した場合(I / Oエラーが発生した場合)、ソフトウェアが期待どおりに反応するかどうかを自動的にテストしたいと思います。まさにそれは数日前にクライアントで起こりました。手動で修正しましたが、自動コードを作成して修正し、テストするために壊れたファイルにアクセスする必要があります。

Unixのすべてがファイルであるため、(たとえば/ devで)読み取ろうとすると常にI / Oエラーが発生する特殊なファイルがあるのではないかと考えました。

同様のファイル(imo)は次のとおりです。

  • /dev/full 書き込もうとすると、常に「デバイスに空き容量がありません」と表示されます
  • /dev/null そして /dev/zero

そのため、そのようなファイルが必要であると想定しました(ただし、まだ見つかりませんでした)。

誰かがそのようなファイルまたは私が望ましい結果を得るための他の方法を知っていますか(意図的に欠陥のあるパーティションイメージ、LD_PRELOADを使用したopen()の周りのラッパー、...)?
ここに行く最良の方法は何ですか?


私が知る限り、Linuxから読み取るときにSIGIOを提供する特別なファイルはありません。前回SIGIOを入手したのは、USBスティックが実際の物理的なものよりもはるかに大きな容量を宣言したためです。たぶんそれは可能性があるのでしょうか?
lgeorget

うーん、私は...私は途中でどこかをトリミングだろうと小さなパーティションのイメージであることを試すことができるかもしれない
mreithub

SIGIOはエラーがあったことを意味するものではなく、select()またはpoll()を呼び出す代わりに、プログラムが非ブロッキングIOが可能になったことを通知するようにプログラムが要求できる方法です。
psusi

もちろん、そうです。SIGIOを書きましたが、EIOエラーコードを考えていました。しかし、おそらくOPも?読み取りの失敗がSIGIOを与えるのはなぜですか?
lgeorget

ああ、私は質問に...編集も...同じ過ちを犯した
mreithub

回答:


8

またはdmsetupを使用して障害をシミュレートするデバイスマッパーデバイスを作成できます。errorflakey

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

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


1
そのコマンドには少なくとも2つのエラーがあります。欠落しているデバイス名、引用符のタイプミス、および「1 0 / dev / null」とはどういう意味ですか?
ハウケレイジング

@HaukeLaging、ああ、はい、名前を省き、どういうわけか間違った引用をヒットしました。1 0 / dev / nullは、オフセット0から始まり、デバイス/ dev / nullによってバックアップされる1つのターゲットを意味します。フレイキーには必要ですが、エラーの場合はオプションです。
プーシ

それは「オプション」ではなく、単に無視されているように思えます。で確認できdmsetup table testます。あなたも書くことができますfoo barの背後にありますerror。気にしないだけです(したがって削除する必要があります)。
ハウケレイジング

@HaukeLaging、編集。
psusi

答えてくれてありがとう、私はそれが今のところ行く方法だと思います。私がこれに関して持っている唯一の小さな問題は、rootアクセスが必要なことですが、とにかくそのような低レベルのものが必要になると思います...(時間があれば、LD_PRELOADのアイデアを掘り下げます)。
mreithub

14

スタックオーバーフローとサーバーフォールトにはこれに対する優れた回答が既にありますが、いくつかのテクニックが欠落していました。作業を簡単にするために、ここにVM / Linuxブロックデバイス/ Linuxファイルシステム/ LinuxユーザースペースライブラリI / Oフォールト挿入メカニズムのリストを示します。

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

関連:


5

I / Oの障害挿入メカニズムが必要です。

Linuxでは、事前のセットアップを必要とせず、異常なエラー(EIOの「入出力エラー」ではなく、ESRCHの「No such process」)を生成するメソッドがあります。

cat /proc/1234/mem

ここで、1234は、テストするプロセスと同じユーザーとして実行されているプロセスのPIDですが、そのプロセス自体ではありません。するクレジットrubasovのために思考/proc/$pid/mem

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

ルートとしてもう少しセットアップすると、デバイスマッパー活用して、有効なセクターと不良セクターを含むファイルを作成できます。

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

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


Libfiuは本当に有望に見えます(debianリポジトリにあります)。素晴らしい回答、ありがとう、+ 1
mreithub

1

デバイスファイルを「I / Oエラーのあるファイル」として使用しても問題ない場合、解決策ははるかに簡単です。私の提案は、通常のファイルにそのようなエラーが含まれるような場合です。

> dd if=/dev/zero of=/path/to/ext2.img bs=10M count=10
> losetup /dev/loop0 /path/to/ext2.img
> blockdev --getsz /dev/loop0
204800
> echo "0 204800 linear /dev/loop0 0" | dmsetup create sane_dev
> mke2fs /dev/mapper/sane_dev # ext2 reicht
> mount -t ext2 /dev/mapper/sane_dev /some/where
> dd if=/dev/zero of=/some/where/unreadable_file bs=512 count=4
> hdparm --fibmap /some/where/unreadable_file
/mnt/tmp/unreadable_file:
 filesystem blocksize 1024, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0       2050       2053          4
> umount /dev/mapper/sane_dev
> dmsetup remove sane_dev
> start_sector=$((204800-2053-1))
> echo $'0 2053 linear /dev/loop0 0\n2053 1 error\n2054 '"${start_sector} linear /dev/loop0 2054" | 
>   dmsetup create error_dev
> mount -t ext2 /dev/mapper/error_dev /some/where
> cat /some/where/unreadable_file # 3rd sector of file is unreadable
cat: /some/where/unreadable_file: Input/output error

エラーなしでそのファイルから単一のセクターを読み取ることができなかったため、少し混乱していることを認めなければなりません(dd .. seek=...)。多分それは先読みの問題です。


ファイルシステムのブロックのサイズは少なくとも4096バイトなので、ファイルが小さくても複数のセクターにまたがります。
アノン

1

この種の目的のために作成されたCharybdeFSを使用できます。

これは、PetardFSのようなパススルーヒューズファイルシステムですが、より多くの設定が可能です。

こちらのCharybdeFSクックブックをご覧くださいhttp ://www.scylladb.com/2016/05/02/fault-injection-filesystem-cookbook/

データベースをテストできるほど高度です。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.