解释 dd 输入/输出错误

解释 dd 输入/输出错误

我尝试/dev/Storage/Storage使用管道将(LVM下的LV)复制到图像文件dd | pv | dddd报告错误,我想知道是否dd已完成磁盘复制或因错误而停止。我不确定,因为它给了我两种不同的输出:一种在顶部有错误,另一种则没有。我猜测并说没有,因为两者之间只有额外的 0.1 秒并且没有额外的数据,但我不确定是否有。 /dev/Storage/Storage是 1 TB 磁盘(TB = 10 12 = 1000 4)或 931.51 GiB(gibibyte = 2 30 = 1024 3)或 1953513472 个扇区。磁盘上的文件系统混乱且无法正常工作。

$ sudo dd if=/dev/Storage/Storage | pv | dd of=Storage.img
dd: error reading ‘/dev/Storage/Storage’: Input/output error                   ]
1627672400+0 records ins] [   <=>                                              ]
1627672400+0 records out
833368268800 bytes (833 GB) copied, 75181 s, 11.1 MB/s
776GB 20:53:01 [10.6MB/s] [  <=>                                              ]
1627672400+0 records in
1627672400+0 records out
833368268800 bytes (833 GB) copied, 75181.1 s, 11.1 MB/s

答案1

如果是硬件错误,请查看内核日志消息(dmesg、 或)以获取来自 SATA 驱动程序的更详细消息。/var/log/kern.log也有用:smartctl -x /dev/sda.如果只是尝试读取分区末尾或其他内容,那么这也可能会显示在内核日志中。

要让 dd 在发生 i/o 错误后继续执行,要读取错误后的可读部分,请使用

dd if=... of=... conv=noerror bs=128k   # it doesn't get any faster beyond about 128k, because of L2 cache size

(正如OP评论中提到的,ddrescue有这个和更多。 在IIRC存在conv=noerror后被添加到GNU dd中ddrescue。)

如果您想从上次中断的地方继续,可以使用seekskip选项,以及conv=notrunc


如果您确实想查看 dd 有多远,请查看其标准输入的文件位置:

cat /proc/$(pidof dd)/fdinfo/0  # dd opens its infile as fd #0

(或ls -lh输出文件的大小)。通过管道将整个硬盘驱动器的数据额外复制两次对我来说似乎很愚蠢,就像它只会使您的计算机比复制所需的时间慢一点点。

或者至少这样做:

dd if=... conv=noerror bs=128k | pv > Storage.img

答案2

  • 您正在使用默认的 512 字节块dd大小。通过使用更大的块大小(例如128k甚至 ),您可以显着提高性能1m

  • 有两个输出,因为您正在运行两个dd命令,第一个是设备读取器,它显示 I/O 错误。

  • 鉴于您使用的设备名称,您可能正在使用 LVM:/dev/Storage/Storage。您确定这是整个磁盘而不是子集吗?用于lvdisplay找出该设备名称背后的含义。

答案3

我遇到了同样的问题,并且没有任何专门针对我的特定形式的教程或帖子dd可以帮助解决这个问题。经过一番挖掘,我发现这个问题这个解决方案对我来说真的很有效。

以下是您的用例的示例:

$ sudo apt-get install gddrescue

$ sudo ddrescue /dev/Storage/Storage Storage.img | pv

一般形式为:

$ sudo ddrescue <in_file> <out_file>

当然,| pv如果您想将其通过管道传输stdout到进度监视工具。

相关内容