我正在使用f3
自定义 Bash 脚本来测试大量 USB 闪存。
我遇到的一个常见问题是,一些有故障的驱动器会导致所有健康驱动器的 IO 不足,从而有效地拖延测试过程。
例如,当留下 50 个 USB 驱动器进行测试时,我经常在一小时后发现 48 个 USB 驱动器什么也没做,而 2 个 USB 驱动器的 LED 正在闪烁。删除这两个驱动器会突然恢复所有其他驱动器测试。
有时会出现更复杂的情况,其中 24 个驱动器停止运行,而其余驱动器似乎工作正常。除了少数驱动器在 20 分钟后没有任何进展之外。你把它们拔掉,剩下的就恢复了,测试继续进行。
然而 - 我还发现停止测试有故障的驱动器就足以使其余的驱动器恢复正常。
我正在寻找一种方法来找出哪些驱动器导致其他驱动器出现此文件操作阻塞,以便我可以在脚本中自动停止它们。
我一直在观察atop
、iostat
、htop
并dmesg
试图找到一个区分因素,但我看不到任何东西。我发现有所谓的usbmon
内核调试接口,尽管它的级别太低,我真的不知道如何使用它。原始 USB 数据包没有告诉我任何信息。
还有其他工具可以用来判断哪些驱动器出现异常吗?
我使用f3write
和f3read
程序来测试驱动器。该f3write
程序创建 1GB 文件,f3read
然后读取该文件,识别在此过程中发生的任何数据损坏。
另外 - 这很奇怪,但是当存在行为异常的驱动器时,其余“健康”驱动器将完成当前文件的工作。例如,写入或读取 1GB 大小的文件,但在删除行为不当的驱动器之前不会创建新文件。这就像在存在“IO hog”驱动器的情况下打开新文件变得不可能。
我能做什么来区分它们?
答案1
我终于找到了一种方法来做到这一点。
下面是一个 Bash 脚本,它将列出驱动器及其每秒的读/写 IO 速率总和。如果一个驱动器或多个驱动器导致其他驱动器的 IO 需求不足 - 它们可以在此处被识别为具有最高编号的驱动器:
#!/bin/bash
# hogs.sh - by Tobiasz 'unfa' Karoń - identify IO hogs in the system
rm hogs.a hogs.b 2>/dev/null
while [ 1=1 ]; do
mv hogs.a hogs.b 2>/dev/null # store old data and make room for new data
for i in /sys/block/sd*; do # cycle through all block devices
# sum two last fields of the stat data and put that into a file along with the drive handle
echo $(echo -n "$i" | cut -d'/' -f4; cat "$i/stat" | xargs| cut -d' ' -f 10-11 | tr ' ' '+' | bc) >> hogs.a
done
# sort files
sort hogs.a > hogs.a2
sort hogs.b > hogs.b2
join hogs.a2 hogs.b2 > hogs.c # combine previous and current data into one file so we can calculate a difference
rm hogs.d 2>/dev/null
while read line; do
echo "$(echo "$line" | cut -d' ' -f1) $(echo "$line" | cut -d' ' -f 2- | tr ' ' '-' | bc)" >> hogs.d
done < hogs.c
sort hogs.d > hogs # sort for the final output
echo "max $(cat hogs | cut -d' ' -f2 | sort -n | tail -n1)" >> hogs # add the highest value
echo "min $(cat hogs | cut -d' ' -f2 | sort -n | head -n1)" >> hogs # add the lowest value
clear
cat hogs # print the final output
sleep 1
done
该脚本使用 /sys/block/sd*/stat 文件显示系统中存在的每个块设备的 IO/秒。我不确定这些是什么单位,但如果他妈的有效,那就是我关心的一切。
这真是一场噩梦。使用 4 个 USB 集线器对 40 个带有 f3 的驱动器进行成像测试。然后一切都停止了,你不知道为什么。如果驱动器有 LED,通常那些导致 IO 不足的 LED 会闪烁,而其他驱动器则不会 - 但许多闪存模块没有 LED。所以在我发现这个之前,没有办法找出导致问题的原因。
请注意,这不是 atop 报告的驱动器读/写速率 - 这些读数对于此类行为不当的驱动器来说是不正确的。通常所有读数都为零,但是使用上面的脚本,您可以区分令人讨厌的猪并将它们删除,以便其余的可以继续。
最后!
这是指示问题的典型输出:
相对健康的情况如下:
分布越均匀越好。也许计算平均值也会有所帮助。最大值和平均值之间的差异可能表明存在问题。
请注意,屏幕截图不显示 sda,因为我从脚本的不同版本中获取了它们,该脚本仅列出了我的大规模测试工具所运行的驱动器。