故意在Linux中引起I / O错误?


42

无论如何,对于Linux,是否有意导致块设备报告I / O错误,或者可能为了测试目的而模拟一个I / O错误?


您是否正在模拟磁盘故障?也许您可以挂载目录,然后在使用目录时将其卸载。
Shef 2013年

2
我要编写一个内核模块,可以modprobe像块设备一样加载它,然后编写另一个小程序,发送ioctl()'s给驱动程序以使其返回所需的值。
ott--


为了跟进@Gilles的评论,在stackoverflow.com/questions/1361518/…(几个不同的故障注入答案)和stackoverflow.com/questions/1870696/…(使用设备映射器)上也有人问过。
2014年

Answers:


54

是的,有一种非常合理的方法可以使用设备映射器执行此操作。

设备映射器可以将块设备重新组合为您选择的新映射/顺序。LVM执行此操作。它还支持其他目标(有些非常新颖),例如“ flakey”模拟故障磁盘,“ error”模拟磁盘故障区域。

可以构造一个故意在其上存在IO黑洞的设备,该设备将在穿越时报告IO错误。

首先,创建一些虚拟卷以用作目标,并使它可作为块设备寻址。

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

因此,首先要创建一个512M文件,该文件是我们将在其中打孔的虚拟块设备的基础。但是,尚无孔。如果您mkfs.ext4 /dev/loop0愿意的话,您将获得一个完全有效的文件系统。

因此,让我们使用dmsetup,它使用此块设备-将创建一个新设备,其中有一些孔。这是第一个例子

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

这将创建一个名为“ errdev0”的设备(通常在/ dev / mapper中)。键入时dmsetup create errdev0,它将等待标准输入并在输入^ D时结束。

在上面的示例中,我们在循环设备的扇区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}"

该脚本假定您还创建了512Mb设备,并且您的虚拟块设备已打开/dev/loop0

您只需将此数据作为表格输出到文本文件中,然后将其传送到中即可dmsetup create errdev0

一旦创建了设备,就可以像正常块设备一样开始使用它,首先对其进行格式化,然后再在其上放置文件。在某些时候,您应该遇到一些IO问题,其中您遇到的部分实际上是虚拟设备中的IO漏洞。

完成使用后dmsetup remove errdev0,请卸下设备。

如果要使其更可能出现IO错误,则可以更频繁地添加孔或更改创建的孔的大小。请注意,在某些部分中放置错误很可能会导致一开始的问题,即32mb的IE进入无法编写ext通常尝试执行的超级块的设备,因此该格式将无法工作。

为了增加乐趣-您实际上可以在losetup那时mkfs.ext4 /dev/loop0并用数据填充它。一旦有了一个不错的工作文件系统,只需卸载该文件系统并使用dmsetup添加一些漏洞,然后重新安装!


6
我不知道你能做到这一点。很酷

15

为了在程序输出失败的情况下检查程序的健壮性,可以使用pseudodevice /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



1

也许您可以更改分区表,并使分区实际更大。那可能会导致I / O错误。或者,如果您的磁盘是可热插拔的,则可以将其拔出。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.