在Linux虚拟机(VMware Workstation或相似),我怎么可以模拟以前的工作盘上的故障?
我有一种情况,其中生产一盘失败发生(可能是一个控制器,电缆或固件问题)。 显然,这是不可预测的或重复性好,我想测试我的监控,以确保其正确警报。
我非常希望能够模拟的情况下失败写入但成功读取,以及彻底的失败,即SCSI接口报告错误回内核。
在Linux虚拟机(VMware Workstation或相似),我怎么可以模拟以前的工作盘上的故障?
我有一种情况,其中生产一盘失败发生(可能是一个控制器,电缆或固件问题)。 显然,这是不可预测的或重复性好,我想测试我的监控,以确保其正确警报。
我非常希望能够模拟的情况下失败写入但成功读取,以及彻底的失败,即SCSI接口报告错误回内核。
有一个能模拟磁盘错误几层。 如果您正在测试一个用户空间程序,可能是最简单的方法是介于相应的调用(如write()
),并让它们有时会返回一个错误。 该libfiu
故障注入图书馆可以做到这一点使用其fiu-run
工具。
另一种方法是使用一个内核驱动程序可以通过数据传递到/从另一设备,但注入沿途故障。 然后,您可以安装设备,并用它从任何应用程序,如果它是一个错误的磁盘。 该fsdisk驱动程序是这样的一个例子。
另外还有一点已被合并到Linux内核中,虽然你可能需要重新配置你的内核,以使其故障注入基础设施。 据中记录文档/故障注入/故障injection.txt 。 这对于测试内核代码是有用的。
也可以使用SystemTap的内核级注入故障。 见该SCSI故障注入测试和使用SystemTap的内核故障注入 。
为了增加mark4o的回答,您还可以使用Linux的Device Mapper产生故障的设备。
设备映射器的延迟装置可被用于发送读写I相同的块不同的底层设备的输入/输出(它也可以延迟该I / O作为它的名称所暗示的)。 设备映射器的错误设备可以用于当特定块被存取以产生永久的错误。 通过结合两个,您可以创建一个装置,其写入总是失败,但总是读取为给定的领域取得成功。
以上是什么在问题中所述的更复杂的例子模拟有读错误故障块设备? (参见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具有可通过与无效ECC写入数据被用于损坏的块的WRITE LONG命令。 SATA和NVMe也有类似的命令。
对于最常见的情况(SATA),可以使用hdparm的用--make-坏扇区采用的是命令,你可以使用sg_write_long用于SCSI和NVMe可以使用nvme-CLI与写uncor选项。
最大的优点是,这些命令比其他的注射方法是,他们也表现得就像一个驱动器确实,充分的延迟影响,并在该部门通过再分配写恢复。 这也包括错误计数器的驱动上升。
其缺点是,如果你在同一个驱动器做太多的错误计数器就会上升,SMART可以标记磁盘坏或者你可能会耗尽它的重新分配表。 所以,不要使用它的手动测试,但如果你是在自动测试运行它不这样做太频繁。
您可以使用scsi_debug
内核模块来模拟一个RAM盘,它支持所有与SCSI错误opts
和every_nth
选项。
请检查该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
你可以改变opts
和every_nth
通过sysfs的运行时选项:
echo 2 | sudo tee /sys/bus/pseudo/drivers/scsi_debug/opts
echo 1 | sudo tee /sys/bus/pseudo/drivers/scsi_debug/opts
你也可以使用一个低级别的SCSI实用程序(SG3-utils的)来停止驱动器。 它仍然会回应查询,所以其状态仍然会“跑”,但读取,直到它再次启动写入会失败。 我使用的mdadm这样测试的RAID驱动器的拆卸和回收。
sg_start --stop /dev/sdb