“dd” 如何确定从哪里开始复制磁盘块?

“dd” 如何确定从哪里开始复制磁盘块?

假设我们有一个硬盘磁盘,其块编号为:0、1、2、3、4 等...

我假设该命令将从块 0 开始按顺序读取磁盘块(1、2、3、4……),对吗?

sudo dd if=/dev/nvme2n1 of=/dev/null bs=1M

如果我Ctrl+C该过程并再次运行此命令,是否仍会dd从块 0 读取?

答案1

它从 0 开始,每次增加 1,直到到达末尾。

实际上,dd 不会决定顺序,而是内核决定。在复制过程中,dd 不会指定要读取哪些扇区,它只使用通用的“从中读取 X 个字节”当前位置“系统调用并依靠内核来跟踪“当前位置”的实际位置。

每当程序打开任何块设备时,位置总是从 0 开始,就像常规文件一样。当 dd 调用 read(1MB) 时,它会接收 1MB 的数据,并且位置会相应地增加 1MB。位置是针对每个“打开的文件”而不是每个设备进行跟踪的,因此当您再次运行 dd 时,它将再次从 0 开始。

请注意,这些操作是以字节为单位,而不是以磁盘扇区为单位的,并且“块”bs=实际上并不是指磁盘块;它是“dd”一次要求读取的数据量。“dd”块大小应该为获得最佳性能,它是磁盘扇区大小的倍数,但从技术上来说并不要求匹配。

(换句话说,dd其工作原理几乎与完全一样cat /dev/nvme0n1p1 > /dev/null。与使用“cat”或“cp”执行相同操作相比,使用“dd”复制磁盘的唯一真正优势是,如果启用它,它具有进度显示。)

您可以使用类似skip=(aka iseek=) 的选项让“dd”跳过一定数量的块,即在输入文件中寻找特定位置(与seek=/结合oseek=用于输出),例如运行dd if=.. of=.. iseek=1G oseek=1G将在 1GB 处恢复。(当输出是常规文件时,您还需要让oflag=append conv=notruncdd 附加到输出而不是截断。)

最好使用专门为增量复制设计的工具,例如救援

ddrescue /dev/nvme0n1 /dev/null /tmp/ddrescue.status

相关内容