在Linux中故意造成I / O错误?

无论如何,在Linux中,有意使块设备报告I / O错误,或者为了testing目的可能模拟一个错误?

是的,这是一个非常合理的方式来做到这一点与设备映射器。

设备映射器可以将块设备重新组合为您select的新映射/顺序。 LVM这样做。 它还支持其他目标,(像一些相当新颖),如“flakey”来模拟失败的磁盘和“错误”来模拟磁盘的失败区域。

人们可以构build一个故意有IO黑洞的设备,它会在交叉时报告IO错误。

首先,创build一些虚拟卷作为目标,并将其作为块设备进行寻址。

 dd if=/dev/zero of=/var/lib/virtualblock.img bs=512 count=1048576 losetup /dev/loop0 /var/lib/virtualblock.img 

所以,开始创build一个512M的文件,这是我们的虚拟块设备的基础,我们将打一个“洞”,虽然没有洞。 如果你是mkfs.ext4 /dev/loop0你会得到一个完全有效的文件系统。

所以,让我们使用dmsetup,使用这个块设备 – 将创build一个新的设备,其中有一些漏洞。 首先是一个例子

 dmsetup create errdev0 0 261144 linear /dev/loop0 0 261144 5 error 261149 787427 linear /dev/loop0 261139 

这将创build一个名为“errdev0”的设备(通常在/ dev / mapper中)。 当你键入dmsetup create errdev0它将等待stdin,并在^ Dinput时结束。

在上面的例子中,我们在回路设备的扇区261144处做了一个5扇区(2.5kb)。 然后我们照常继续通过循环设备。

这个脚本会尝试生成一个表格,将随机的位置放在大约16Mb左右的位置(虽然它非常随机)。

 #!/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}" 

该脚本假定您还创build了一个512Mb设备,并且您的虚拟块设备位于/dev/loop0

您可以将这些数据以表格的forms输出到文本文件中,并将其input到dmsetup create errdev0

一旦你创build了设备,你就可以开始像普通的块设备一样使用它,首先通过格式化,然后在其上放置文件。 在某些情况下,您应该遇到一些IO问题,您碰到虚拟设备中真正IO洞的扇区。

一旦你完成使用dmsetup remove errdev0删除设备。

如果您希望更容易出现IO错误,则可以更频繁地添加空洞或更改创build的空洞大小。 注意错误在某些部分可能会导致问题的开始,IE浏览器在32MB到一个设备,你不能写一个超级块通常试图做,所以格式不会工作..

为了增加乐趣 – 你可以实际上只需要启动,然后mkfs.ext4 /dev/loop0并填充数据。 一旦你有一个很好的工作文件系统,只需卸载文件系统,并使用dmsetup添加一些漏洞,并重新安装!

为了在程序输出失败的情况下检查程序的健壮性,可以使用伪设备/dev/full ,写入时总是返回“ENOSPACE”。

 $ 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 

取决于你想testing什么。 使用LD_PRELOAD ed库,您可以诱骗应用程序进行思考,例如“所有写入操作都会因ENOSPCEIO失败”。

你可以用很多有趣的方法来做到这一点。 请参阅https://www.kernel.org/doc/Documentation/fault-injection/fault-injection.txt

也许你可以改变分区表,使分区变大一点。 这可能会导致I / O错误。 或者如果你的磁盘是热插拔的,你可以把它拉出来。