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

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

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

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

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

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

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

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

答案1

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

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

有关的:

答案2

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

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

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

答案3

你想要一个故障注入I/O 机制。

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

cat /proc/1234/mem

其中 1234 是与您正在测试的进程以同一用户身份运行的进程的 PID,但不是该进程本身。致谢鲁巴索夫为了思维/proc/$pid/mem

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

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

另一种方法是实施一个小型的保险丝文件系统。 EIO 是用户空间文件系统驱动程序出现错误时的默认错误代码,因此很容易实现。这俩珀尔Python绑定附带了入门示例,您可以快速编写一个文件系统,该文件系统主要镜像现有文件,但在精心选择的位置注入 EIO。有一个现有的这样的文件系统:佩塔德夫斯文章),我不知道它开箱即用的效果如何。

还有一种方法是LD_PRELOAD包装纸。现有的一个是图书馆(用户空间中的错误注入)。它的工作原理是预加载一个重载 POSIX API 调用的库。您可以编写简单的指令或任意 C 代码来覆盖正常行为。

答案4

您可以使用专门为此目的而制作的 CharybdeFS。

它是一个类似于 PetardFS 的直通熔断文件系统,但可配置性更高。

请参阅此处的 CharybdeFS 食谱:http://www.scyladb.com/2016/05/02/fault-injection-filesystem-cookbook/

它足够先进来测试数据库。

相关内容