如何在testing期间模拟出现故障的磁盘?

在Linux VM(Vmware工作站或类似的)中,如何模拟以前工作的光盘上的故障?

生产中出现光盘故障(可能是控制器,电缆或固件问题)的情况。 显然这是不可预测或可重复的,我想testing我的监测,以确保它正确警报。

理想情况下,我希望能够模拟写入失败但成功读取的情况,以及完全失败的情况,即scsi接口将错误报告给内核。

有几个层可以模拟磁盘错误。 如果您正在测试单个用户空间程序,最简单的方法可能是插入适当的调用(例如write() ),并让它们有时返回一个错误。 libfiu故障注入库可以使用它fiu-run工具来完成。

另一种方法是使用一个内核驱动程序,可以将数据传递到另一个设备或从另一个设备传递数据,但是一路注入错误。 然后,您可以挂载设备,并从任何应用程序使用它,就像它是一个错误的磁盘。 fsdisk驱动程序就是一个例子。

还有一个故障注入基础设施已经被合并到Linux内核中,尽管您可能需要重新配置内核来启用它。 它记录在Documentation / fault-injection / fault-injection.txt中 。 这对测试内核代码很有用。

也可以使用SystemTap在内核级别注入错误。 请参阅SCSI故障注入测试和使用SystemTap的内核故障注入 。

要添加到mark4o的答案,您还可以使用Linux的Device Mapper来生成失败的设备。

设备映射器的延迟设备可以用来发送同一块的读写I / O到不同的底层设备(它也可以延迟这个I / O顾名思义)。 设备映射程序的错误设备可用于在访问特定块时生成永久性错误。 通过组合这两者,您可以创建一个写入总是失败的设备,但对于给定的区域,读取总是成功的。

上面是一个更复杂的例子,在问题中描述了用读取错误来模拟有故障的块设备? (有关简单的Device Mapper示例,请参阅https://stackoverflow.com/a/1871029 )。

特殊文件上还有一个Linux磁盘错误注入机制的列表, 这个错误会导致I / O错误 Unix和Linux的问题。

使用2.6内核使SCSI磁盘消失的一个简单方法是:

 echo 1 > /sys/bus/scsi/devices/H:B:T:L/delete 

(H:B:T:L是主机,总线,目标,LUN)。 为了模拟只读的情况,你必须使用mark4o提到的故障注入方法。

Linux内核提供了一个很好的功能,称为“故障注入”

 echo 1 > /sys/block/vdd/vdd2/make-it-fail 

要设置一些选项:

 mkdir /debug mount debugfs /debug -t debugfs cd /debug/fail_make_request echo 10 > interval # interval echo 100 > probability # 100% probability echo -1 > times # how many times: -1 means no limit 

https://lxadm.com/Using_fault_injection

也可以使用磁盘提供的方法来进行媒体错误测试。 SCSI具有WRITE LONG命令,可以通过用无效的ECC写入数据来破坏块。 SATA和NVMe也有类似的命令。

对于最常见的情况(SATA),可以使用带有–make-bad-sector的hdparm来使用该命令,可以使用sg_write_long作为SCSI,NVMe可以使用带有write-uncor选项的nvme-cli。

这些命令相对于其他注入方法的巨大优势在于,它们也像驱动器一样运行,具有完全的延迟影响,并且通过重新分配写入到该扇区的恢复也是如此。 这也包括驱动器中的错误计数器。

缺点是,如果你对同一个驱动器执行的操作太多,它的错误计数器将会增加,SMART可能会将磁盘标记为坏,否则可能会耗尽其重新分配表。 所以,请使用它进行手动测试,但是如果您在自动测试中运行它,请不要经常这样做。

您可以使用scsi_debug内核模块来模拟RAM磁盘,并使用optsevery_nth选项支持所有的SCSI错误。

请检查这个http://sg.danny.cz/sg/sdebug26.html

扇区4656中等错误示例:

 [fge@Gris-Laptop ~]$ sudo modprobe scsi_debug opts=2 every_nth=1 [fge@Gris-Laptop ~]$ sudo dd if=/dev/sdb of=/dev/null dd: error reading '/dev/sdb': Input/output error 4656+0 records in 4656+0 records out 2383872 bytes (2.4 MB) copied, 0.021299 s, 112 MB/s [fge@Gris-Laptop ~]$ dmesg|tail [11201.454332] blk_update_request: critical medium error, dev sdb, sector 4656 [11201.456292] sd 5:0:0:0: [sdb] FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE [11201.456299] sd 5:0:0:0: [sdb] Sense Key : Medium Error [current] [11201.456303] sd 5:0:0:0: [sdb] Add. Sense: Unrecovered read error [11201.456308] sd 5:0:0:0: [sdb] CDB: Read(10) 28 00 00 00 12 30 00 00 08 00 [11201.456312] blk_update_request: critical medium error, dev sdb, sector 4656 

你可以通过sysfs在运行时改变optsevery_nth选项:

 echo 2 | sudo tee /sys/bus/pseudo/drivers/scsi_debug/opts echo 1 | sudo tee /sys/bus/pseudo/drivers/scsi_debug/opts