我正在尝试在 Ubuntu 19.04 上使用 ddrescue 来镜像一个故障的外部硬盘。有一个 220GB 的主 Windows NTFS 分区和一个 14GB 的辅助恢复 NTFS 分区。ddrescue 能够很好地镜像后者,但当用于镜像较大的分区时,它会变得非常缓慢。检查 dmesg 显示系统会因每次 I/O 错误而超时。有没有办法禁用此超时,以便 ddrescue 在合理的时间内完成?
dmesg 输出:
[188659.123829] print_req_error: I/O error, dev sdc, sector 2176 flags 0
[188841.586225] sd 7:0:0:0: timing out command, waited 180s
[188841.586235] sd 7:0:0:0: [sdc] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[188841.586237] sd 7:0:0:0: [sdc] tag#0 Sense Key : Hardware Error [current]
[188841.586238] sd 7:0:0:0: [sdc] tag#0 Add. Sense: Logical unit communication CRC error (Ultra-DMA/32)
[188841.586241] sd 7:0:0:0: [sdc] tag#0 CDB: Read(10) 28 00 00 00 17 00 00 00 80 00
[188841.586242] print_req_error: I/O error, dev sdc, sector 5888 flags 0
[189021.915161] sd 7:0:0:0: timing out command, waited 180s
[189021.915191] sd 7:0:0:0: [sdc] tag#0 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
[189021.915193] sd 7:0:0:0: [sdc] tag#0 Sense Key : Hardware Error [current]
[189021.915195] sd 7:0:0:0: [sdc] tag#0 Add. Sense: Logical unit communication CRC error (Ultra-DMA/32)
[189021.915197] sd 7:0:0:0: [sdc] tag#0 CDB: Read(10) 28 00 00 00 1d 80 00 00 80 00
答案1
您正在尝试从有缺陷的设备中挽救数据——220GB 的合理时间以周或月来计算,而不是以小时来计算。
也就是说,GNU 版本的 ddrescue 允许您进行以下设置:
-a
(以字节/秒为单位)是被认为良好的最低读取速率。如果吞吐量低于此阈值,则会跳过一个块-K
– 每次读取错误时要跳过的块大小
这样,您可以先挑选低垂的果实,然后在以后的传递中只进行超慢的读取。
答案2
我发现大多数 I/O 错误都发生在磁盘崩溃时 Windows 正在使用的分区的开头。当 ddrescue 读取这些扇区时,我通过echo 1 > /sys/block/sdb/device/timeout
以 root 身份运行来禁用超时。
这将超时时间减少到 6 秒(由于某种原因,Ubuntu 将超时值乘以 6。)
复制错误扇区后,我将超时时间增加回 30 秒,这样复制就不会因为磁盘速度慢而超时。