当使用 运行 SMART 测试时smartmontools
,它们绝不完成。我在各种不同的系统和磁盘上总是收到“中断(主机重置)”的消息,包括 x86 和 ARM 上的 Debian、x64 上的 OS X,以及外部和内部驱动器。
即使在磁盘全部为空(用 清零dd
)的受限模式下运行。
我究竟做错了什么?
答案1
当驱动器在测试期间不处理任何输入/输出活动时,它可能会进入待机状态,从而引发此Interrupted (host reset)
情况。尝试以适当的间隔从磁盘读取:
while true; do dd if=/dev/disk1 of=/dev/null count=1; sleep 60; done
(/dev/disk1
用适当的设备替换;每 60 秒从该设备读取一个扇区,直到达到ctrl-c
)
这对我的环境有帮助:OS X 10.6.8、WD Elements USB 连接驱动器、SAT-SMART 驱动程序 0.8。
从理论上讲,强制测试应该可以让驱动器保持在线状态。然而,硬件命令发送smartctl
可能会在测试完成之前超时,导致内核重置链接,最终陷入与上述相同的情况(错误 #303)。
看此主题有关更多详细信息,请参阅 smartmontools-support 邮件列表。我感谢 Christian Franke 在此处提供的见解。
答案2
变体Ari 的回答是使用watch
,因为smartctl
输出实际上可能有趣地跟踪状态:
sudo watch -d -n 60 smartctl -a /dev/sdx
这将每 60 秒自动更新一次输出smartctl -a
,以便您可以看到剩余的自检时间,并突出显示更改(因此更容易发现测试确实正在进行中)。
答案3
我尝试过来自 sve.g 的解决方案,就我而言,无论在开始测试并中断测试后的某个时间,我都会发现外部 USB 驱动器处于睡眠模式,似乎 dd 最终从内核缓存中读取,并且缓存足够大以使磁盘进入睡眠模式。
我注意到,调用 smartctl 询问状态总是能够“唤醒”磁盘。因此:这个相同想法的版本对我来说很管用:
sudo bash -c 'while true; do smartctl -a /dev/sdb > /dev/null; sleep 60; done'
5 小时后,外部 USB 磁盘仍在旋转。这是我第一次在外部磁盘上看到 smartctl 长测试完成。
我相信这个解决方案还有一个优点,就是磁盘头不会每分钟不必要地移动。长时间运行几乎完全在预计的时间内完成(保持唤醒脚本没有增加运行时间)
答案4
作为GreatEmerald 指出每隔几分钟探测一次智能数据可防止外部 USB 驱动器进入休眠状态。我编写了一个脚本,每 5 分钟检查一次智能数据,直到测试退出。
我依靠“自检执行状态”代码来检查智能测试是否已完成。此脚本需要以 root 身份运行。
smartctl -a $DEVICE | grep "Self-test execution status" | cut -d "(" -f2 | cut -d ")" -f1
提取自检的状态代码。已使用smartctl
7.3 版进行了测试
您需要编辑指定设备 UUID 的行。您可以使用以下命令找到设备的 UUIDls /dev/disk/by-id
#!/bin/bash
# SMART test status reference
# 240 to 250 - test running
# 0 - The previous self-test routine completed without error
# 33 - The self-test routine was interrupted by the host with a hard or soft reset
# This script runs a SMART long test and prevents the disk from going to sleep until the test has completed
# Probing a drive with smartctl seems to keep it spinning
DEVICE="/dev/disk/by-id/usb-WD_Elements_2621_575835324136314656444C4E-0:0"
smartctl -t long $DEVICE >/dev/null 2>&1
STATUS=$(smartctl -a $DEVICE | grep "Self-test execution status" | cut -d "(" -f2 | cut -d ")" -f1)
while [ $STATUS -gt 240 ]
do
sleep 300
STATUS=$(smartctl -a $DEVICE | grep "Self-test execution status" | cut -d "(" -f2 | cut -d ")" -f1)
done