导致 I/O 错误的特殊文件

mre*_*hub 15 linux io devices testing

如果无法读取基本的 SQLite DB 文件(导致 I/O 错误),我想自动测试某个软件是否按预期做出反应。这正是几天前发生在客户身上的事情。我们手动修复了它,但现在我想创建自动代码来修复它,并且需要访问损坏的文件来测试它。

由于 Unix 中的一切都是一个文件,我怀疑可能有一个特殊的文件,当人们试图读取它时(例如在 /dev 中),它总是会导致 I/O 错误。

一些类似的文件(imo)是:

  • /dev/full 如果您尝试编写它,它总是显示“设备上没有剩余空间”
  • /dev/null/dev/zero

所以我认为必须有一个这样的文件(但还没有找到)。

有谁知道这样的文件或任何其他方法可以让我获得所需的结果(故意错误的分区映像,使用 LD_PRELOAD 围绕 open() 的包装器,...)?
去这里的最佳方式是什么?

Ano*_*non 15

在 Stack Overflow 和 Server Fault 上已经有很多关于这个的答案,但缺少一些技术。为了让生活更轻松,这里列出了 VM/Linux 块设备/Linux 文件系统/Linux 用户空间库 I/O 故障注入机制:

额外的事实:SQLite 有一个用于模拟错误的 VFS 驱动程序,因此它可以获得良好的测试覆盖率。

有关的:


psu*_*usi 8

您可以使用或目标来dmsetup创建设备映射器设备来模拟故障。errorflakey

dmsetup create test --table '0 123 flakey 1 0 /dev/loop0'
Run Code Online (Sandbox Code Playgroud)

其中 123 是设备的长度,以扇区为单位,/dev/loop0 是您要在其上模拟错误的原始设备。对于错误,您不需要后续参数,因为它总是返回错误。


Gil*_*il' 5

您需要I/O的故障注入机制。

在 Linux 上,这是一种不需要任何事先设置并生成异常错误的方法(不是 EIO“输入/输出错误”而是 ESRCH“无此类进程”):

cat /proc/1234/mem
Run Code Online (Sandbox Code Playgroud)

其中 1234 是与您正在测试的进程以同一用户身份运行的进程的 PID,但不是该进程本身。学分rubasov思考/proc/$pid/mem

如果您使用进程本身的 PID,您将获得 EIO,但前提是您从未映射到进程内存中的区域读取数据。第一页永远不会被映射,所以如果你顺序读取文件是可以的,但不适合直接寻找文件中间的数据库进程。

以 root 身份进行更多设置后,您可以利用设备映射器创建具有有效扇区和坏扇区的文件。

另一种方法是实现一个小的FUSE文件系统。EIO 是用户空间文件系统驱动程序出错时的默认错误代码,因此很容易实现。无论是Perl的Python的绑定来举例上手,您可以快速编写大多镜子现有的文件,但一个内喷射在EIO精心挑选的地方文件系统。有一个现有的这样的文件系统:petardfs文章),我不知道它开箱即用的效果如何。

另一种方法是LD_PRELOAD包装器。现有的一个是Libfiu(用户空间中的故障注入)。它通过预加载一个重载 POSIX API 调用的库来工作。您可以编写简单的指令或任意 C 代码来覆盖正常行为。