30

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

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

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

4

7 回答 7

27

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

另一种方法是使用内核驱动程序,该驱动程序可以将数据传入/传出另一个设备,但在此过程中会注入错误。然后,您可以挂载该设备并从任何应用程序使用它,就好像它是一个有故障的磁盘一样。fsdisk驱动程序就是一个例子。

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

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

于 2009-09-01T17:40:17.777 回答
7

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

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

上面是一个更复杂的例子,说明了问题Simulate a faulty block device with read errors?(有关简单的设备映射器示例,请参阅https://stackoverflow.com/a/1871029 )。

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

于 2014-05-29T10:02:10.970 回答
5

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

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

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

于 2009-09-01T23:28:55.717 回答
2

Linux 内核提供了一个很好的特性,叫做“故障注入”</p>

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

于 2017-09-29T09:49:50.400 回答
1

您可以使用scsi_debug内核模块来模拟 RAM 磁盘,它支持所有 SCSI 错误optsevery_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

您可以通过 sysfs 在运行时更改optsand选项:every_nth

echo 2 | sudo tee /sys/bus/pseudo/drivers/scsi_debug/opts
echo 1 | sudo tee /sys/bus/pseudo/drivers/scsi_debug/opts
于 2017-02-22T03:29:44.880 回答
1

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

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

与其他注入方法相比,这些命令的最大优势在于它们的行为也像驱动器一样,具有完整的延迟影响,并且还可以通过重新分配写入该扇区时恢复。这还包括驱动器中的错误计数器。

缺点是,如果您对同一驱动器执行过多此操作,则其错误计数器会上升,SMART 可能会将磁盘标记为坏盘,或者您可能会耗尽其重新分配表。因此,请务必将其用于手动测试,但如果您在自动测试中运行它,请不要经常这样做。

于 2017-10-25T08:29:54.587 回答
0

您还可以使用低级 SCSI 实用程序 (sg3-utils) 来停止驱动器。它仍然会响应 Inquiry,因此它的状态仍然是“正在运行”,但读取和写入将失败,直到它再次启动。我已经以这种方式使用 mdadm 测试了 RAID 驱动器的移除和恢复。

sg_start --stop /dev/sdb
于 2019-03-20T15:52:38.043 回答