如何使用hdparm修复未决的扇区?

SMART正在说服我的服务器的硬盘上的一个未决的部门。 我读过很多文章,build议使用hdparm“轻松”强制磁盘重新定位坏扇区,但我找不到正确的方法来使用它。

我的“smartctl”中的一些信息:

Error 95 occurred at disk power-on lifetime: 20184 hours (841 days + 0 hours) When the command that caused the error occurred, the device was active or idle. After command completion occurred, registers were: ER ST SC SN CL CH DH -- -- -- -- -- -- -- 40 51 00 d7 55 dd 02 Error: UNC at LBA = 0x02dd55d7 = 48059863 Commands leading to the command that caused the error were: CR FR SC SN CL CH DH DC Powered_Up_Time Command/Feature_Name -- -- -- -- -- -- -- -- ---------------- -------------------- c8 00 08 d6 55 dd e2 00 18d+05:13:42.421 READ DMA 27 00 00 00 00 00 e0 00 18d+05:13:42.392 READ NATIVE MAX ADDRESS EXT ec 00 00 00 00 00 a0 02 18d+05:13:42.378 IDENTIFY DEVICE ef 03 46 00 00 00 a0 02 18d+05:13:42.355 SET FEATURES [Set transfer mode] 27 00 00 00 00 00 e0 00 18d+05:13:42.327 READ NATIVE MAX ADDRESS EXT SMART Self-test log structure revision number 1 Num Test_Description Status Remaining LifeTime(hours) LBA_of_first_error # 1 Extended offline Completed: read failure 90% 20194 48059863 # 2 Short offline Completed without error 00% 15161 - 

有了这个“糟糕的LBA”( 48059863 ),我该如何使用hdparm? 参数“–read-sector”和“–write-sector”应该有什么types的地址?

如果我发出命令hdparm –read-sector 48095863 / dev / sda它读取和转储数据。 如果这个命令是正确的,我应该会有一个I / O错误,对吧?

相反,它会转储数据:

 $ ./hdparm --read-sector 48059863 /dev/sda /dev/sda: reading sector 48059863: succeeded 4b50 5d1b 7563 a932 618d 1f81 4514 2343 8a16 3342 5e36 2591 3b4e 762a 4dd7 037f 6a32 6996 816f 573f eee1 bc24 eed4 206e (...) 

如果出于任何原因,您宁愿尝试清除这些坏扇区,而您不关心驱动器的现有内容,下面的shell代码可能会有所帮助。 我在一个老旧的Seagate Barracuda驱动器上testing了这款产品,这个驱动器已经远远超过了它的保修期。 它可能无法与其他驱动器型号或制造商合作,但是如果您必须编写脚本,它会使您走上正确的道路。 它破坏你在硬盘上的任何内容。

您可能更愿意只运行badblocks,hdparm安全擦除(SE)( https://wiki.archlinux.org/index.php/Securely_wipe_disk )或其他一些实际为此devise的工具。 甚至制造商提供的工具,如SeaTools(有一个32位Linux的企业版本,谷歌它)。

在执行此操作之前,请确保所涉及的驱动器完全未使用/未安装。 另外,我知道,while循环,没有任何借口。 这是一个黑客,你可以做得更好…

 baddrive=/dev/sdb badsect=1 while true; do echo Testing from LBA $badsect smartctl -t select,${badsect}-max ${baddrive} 2>&1 >> /dev/null echo "Waiting for test to stop (each dot is 5 sec)" while [ "$(smartctl -l selective ${baddrive} | awk '/^ *1/{print substr($4,1,9)}')" != "Completed" ]; do echo -n . sleep 5 done echo badsect=$(smartctl -l selective ${baddrive} | awk '/# 1 Selective offline Completed: read failure/ {print $10}') [ $badsect = "-" ] && exit 0 echo Attempting to fix sector $badsect on $baddrive hdparm --repair-sector ${badsect} --yes-i-know-what-i-am-doing $baddrive echo Continuning test done 

使用“自测”方法的一个优点是负载由驱动器固件来处理,所以它所连接的PC不会像使用dd或badblocks那样加载。

注意:对不起,我犯了一个错误,正确的条件是这样的:

 while [ "$(smartctl -l selective ${baddrive} | awk '/^ *1/{print $4}')" = "Self_test_in_progess" ]; do 

脚本的退出条件变成:

 [ $badsect = "-" ] || [ "$badsect" = "" ] && exit 0 

我认为它可能没有错误地阅读,因为这个行业并不坏,但其他工具由于其他行为而不能读取该行业。 (预读到达一个实际上不可读的扇区?)

我发现了一些坏的部分,如果我修复了唯一一个“hdparm -read-sector”无法读取的部分,那么其他“坏”的部分突然不再像dd一样无法读取了。 有趣的是,在查看“dmesg”输出时,只有hdparm不可读的报告。

例如。 我有部分36589320到36589327,而36589344到36589351无法读取dd,但只有36589326和36589345无法读取hdparm – 读取扇区。 然后我用hdparm –write这个扇区,然后所有的16个扇区再次可读。

这是dmesg输出的一小部分:

 [30152036.527940] end_request: I/O error, dev sda, sector 36589326 [30152077.363710] end_request: I/O error, dev sda, sector 36589345 

和磁盘信息:

 # smartctl -i /dev/sda ... === START OF INFORMATION SECTION === Device Model: TOSHIBA MK2002TSKB ... Firmware Version: MT2A User Capacity: 2,000,398,934,016 bytes [2.00 TB] Sector Size: 512 bytes logical/physical ... 

显然,这个磁盘的固件要么没有正确logging重新分配的扇区,要么他们没有被真正的重新分配,而只是被破坏了(就像一个不可恢复的ECC错误,但是表面仍然有效,就像是由于电路故障而造成的,坏媒体):

 # smartctl -A /dev/sda | egrep "Reallocated|Pending|Uncorrectable" 5 Reallocated_Sector_Ct 0x0033 100 100 050 Pre-fail Always - 0 196 Reallocated_Event_Count 0x0032 100 100 000 Old_age Always - 0 197 Current_Pending_Sector 0x0032 100 100 000 Old_age Always - 0 198 Offline_Uncorrectable 0x0030 100 100 000 Old_age Offline - 0 # smartctl -l error /dev/sda ... SMART Error Log Version: 1 No Errors Logged 

请注意,我运行了一个“读取”部分和一个“写入”部分。 读取可能需要正确地重新分配扇区,而不仅仅是写入。 如果你不先读,它可能不知道该部门是坏的。