dd conv=sync,noerror 有什么作用?

dd conv=sync,noerror 有什么作用?

conv=sync,noerror将整个硬盘备份到映像文件上添加有什么效果?

这是conv=sync,noerror进行取证工作时的要求吗?如果是,为什么 Linux Fedora 的情况如此?

编辑:

好的,如果我dd不这样做conv=sync,noerror并且dd在读取块(假设为 100M)时遇到读取错误,是否dd只需跳过 100M 块并读取下一个块而不写入任何内容(dd conv=sync,noerror将零写入 100M 的输出 - 这种情况怎么样?)?

如果没有,原始硬盘和输出文件的哈希值会有所不同吗conv=sync,noerror?还是只有发生读取错误时才会这样?

答案1

conv=sync告诉dd用空值填充每个块的左侧,这样,如果由于错误而无法读取整个块,则可以保留原始数据的完整长度,即使并非所有数据本身都可以包含在图像中。这样,你至少知道数据损坏的程度,这可能会为你提供法医线索,如果你由于坏块或其他原因根本无法拍摄图像,你就无法分析任何数据。有总比没有好。

如果在读取源时出现读取错误,则conv=sync,noerror需要防止dd因错误而停止并执行转储。conv=sync如果没有错误则基本上毫无意义。

https://www.man7.org/linux/man-pages/man1/dd.1.html

http://vlinux-freak.blogspot.com/2011/01/how-to-use-dd-command.html

答案2

dd conv=sync,noerror(或conv=noerror,sync)破坏您的数据。

根据遇到的 I/O 错误和使用的块大小(大于物理扇区大小?),输入和输出地址实际上并不保持同步,而是最终出现在错误的偏移量上,这使得副本对于文件系统映像和其他偏移量很重要的东西毫无用处。

很多地方都建议conv=noerror,sync在处理坏盘时使用它。我自己也曾经提出过同样的建议。当我前段时间必须恢复坏盘时,它确实对我有用。

然而,测试表明,这实际上根本不可靠。

使用losetupdmsetup创建A error B设备:

truncate -s 1M a.img b.img
A=$(losetup --find --show a.img)
B=$(losetup --find --show b.img)
i=0 ; while printf "A%06d\n" $i ; do i=$((i+1)) ; done > $A
i=0 ; while printf "B%06d\n" $i ; do i=$((i+1)) ; done > $B

A、B环路设备如下所示:

# head -n 3 $A $B
==> /dev/loop0 <==
A000000
A000001
A000002

==> /dev/loop1 <==
B000000
B000001
B000002

因此它是 A、B,带有递增的数字,这将有助于我们稍后验证偏移量。

现在在两者之间放置一个读取错误,由 Linux 设备映射器提供:

# dmsetup create AerrorB << EOF
0 2000 linear $A 0
2000 96 error
2096 2000 linear $B 48
EOF

此示例创建了AerrorB扇区2000A后跟2*48错误扇区,后跟2000扇区B

只是为了验证:

# blockdev --getsz /dev/mapper/AerrorB
4096
# hexdump -C /dev/mapper/AerrorB
00000000  41 30 30 30 30 30 30 0a  41 30 30 30 30 30 31 0a  |A000000.A000001.|
00000010  41 30 30 30 30 30 32 0a  41 30 30 30 30 30 33 0a  |A000002.A000003.|
[...]
000f9fe0  41 31 32 37 39 39 36 0a  41 31 32 37 39 39 37 0a  |A127996.A127997.|
000f9ff0  41 31 32 37 39 39 38 0a  41 31 32 37 39 39 39 0a  |A127998.A127999.|
000fa000
hexdump: /dev/mapper/AerrorB: Input/output error

因此它读取直到A127999\n,因为每行有 8 个字节,总计 1024000 字节,即我们的 2000 个 512 字节扇区。一切似乎都井然有序...

它会融合吗?

for bs in 1M 64K 16K 4K 512 42
do
    dd bs=$bs conv=noerror,sync if=/dev/mapper/AerrorB of=AerrorB.$bs.gnu-dd
    busybox dd bs=$bs conv=noerror,sync if=/dev/mapper/AerrorB of=AerrorB.$bs.bb-dd
done

ddrescue /dev/mapper/AerrorB AerrorB.ddrescue

结果:

# ls -l
-rw-r--r-- 1 root root 2113536 May 11 23:54 AerrorB.16K.bb-dd
-rw-r--r-- 1 root root 2064384 May 11 23:54 AerrorB.16K.gnu-dd
-rw-r--r-- 1 root root 3145728 May 11 23:54 AerrorB.1M.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.1M.gnu-dd
-rw-r--r-- 1 root root 2097186 May 11 23:54 AerrorB.42.bb-dd
-rw-r--r-- 1 root root 2048004 May 11 23:54 AerrorB.42.gnu-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.4K.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.4K.gnu-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.512.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.512.gnu-dd
-rw-r--r-- 1 root root 2162688 May 11 23:54 AerrorB.64K.bb-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.64K.gnu-dd
-rw-r--r-- 1 root root 2097152 May 11 23:54 AerrorB.ddrescue

仅从文件大小你就能看出某些块大小有问题。

校验和:

# md5sum *
8972776e4bd29eb5a55aa4d1eb3b8a43  AerrorB.16K.bb-dd
4ee0b656ff9be862a7e96d37a2ebdeb0  AerrorB.16K.gnu-dd
7874ef3fe3426436f19ffa0635a53f63  AerrorB.1M.bb-dd
6f60e9d5ec06eb7721dbfddaaa625473  AerrorB.1M.gnu-dd
94abec9a526553c5aa063b0c917d8e8f  AerrorB.42.bb-dd
1413c824cd090cba5c33b2d7de330339  AerrorB.42.gnu-dd
b381efd87f17354cfb121dae49e3487a  AerrorB.4K.bb-dd
b381efd87f17354cfb121dae49e3487a  AerrorB.4K.gnu-dd
b381efd87f17354cfb121dae49e3487a  AerrorB.512.bb-dd
b381efd87f17354cfb121dae49e3487a  AerrorB.512.gnu-dd
3c101af5623fe8c6f3d764631582a18e  AerrorB.64K.bb-dd
6f60e9d5ec06eb7721dbfddaaa625473  AerrorB.64K.gnu-dd
b381efd87f17354cfb121dae49e3487a  AerrorB.ddrescue

ddddrescue仅对于恰好与我们的错误区域对齐的块大小才同意( 5124K)。

让我们检查一下原始数据。

# grep -a -b --only-matching B130000 *
AerrorB.16K.bb-dd:  2096768:B130000
AerrorB.16K.gnu-dd: 2047616:B130000
AerrorB.1M.bb-dd:   2113152:B130000
AerrorB.1M.gnu-dd:  2064000:B130000
AerrorB.42.bb-dd:   2088578:B130000
AerrorB.42.gnu-dd:  2039426:B130000
AerrorB.4K.bb-dd:   2088576:B130000
AerrorB.4K.gnu-dd:  2088576:B130000
AerrorB.512.bb-dd:  2088576:B130000
AerrorB.512.gnu-dd: 2088576:B130000
AerrorB.64K.bb-dd:  2113152:B130000
AerrorB.64K.gnu-dd: 2064000:B130000
AerrorB.ddrescue:   2088576:B130000

虽然数据本身似乎存在,但显然不同步;对于 bs=16K、1M、42、64K...,偏移量完全不正常,只有有偏移量的2088576才是正确的,这可以通过原始设备进行验证。

# dd bs=1 skip=2088576 count=8 if=/dev/mapper/AerrorB 
B130000

这是预期的行为吗dd conv=noerror,sync?我不知道,dd我手头的两种实现甚至彼此不一致。如果您使用dd高性能块大小选择,结果将毫无用处。

以上内容是使用dd (coreutils) 8.25BusyBox v1.24.2、生成的GNU ddrescue 1.21

相关内容