当启用复制设备时,如何验证 rsync 是否正确复制了设备?

当启用复制设备时,如何验证 rsync 是否正确复制了设备?

这是一个扩展为什么 rsync 尝试复制已经是最新的文件?

我正在尝试使用该--copy-devices补丁来rsync复制整个磁盘驱动器并将其作为映像存储在另一台计算机上。

复制似乎已正确运行,但是,当我rsync使用相同的值再次运行时,它似乎每次都会再次复制一些数据。

rsync带着冗长的内容运行并得到了这个:

$ sudo rsync -vvz --partial --progress --copy-devices /dev/sdb me@otherserver:/backupdisks/mydisk.img
opening connection using: ssh -l me otherserver rsync --server -vvze.Lsfx --partial --copy-devices . /backupdisks/mydisk.img  (11 args)
me@otherserver's password: 
delta-transmission enabled
sdb
320,071,851,520 100%   63.47MB/s    1:20:09 (xfr#1, to-chk=0/1)
total: matches=2441955  hash_hits=2441955  false_alarms=204015955 data=0

sent 188 bytes  received 21,979,001 bytes  2,837.31 bytes/sec
total size is 0  speedup is 0.00

我知道 rsync 按时间确定更改,但磁盘在 rsync 之间没有更改(它如何确定磁盘的修改时间?)但是,远程映像上的时间每次都会更新。所以这可能是问题所在。

另一种可能性是磁盘有一个坏扇区,每次返回不同的值并否定正在使用的任何校验和。

我的问题有两个:

  1. 我的映像是否已成功传输?如果是,为什么当我再次运行它时,它会重新传输大部分磁盘? (这也可以作为我的推论问题的一部分得到部分回答rsync 输出中的“matches”、“hash_hits”和“false_alarms”是什么,“data=0”是否意味着成功?

  2. 我是否缺少一个开关来使其正常工作? (也许--checksum?)是否可以列出 rsync 算法使用的块级故障?

答案1

默认情况下,rsync 按大小和时间戳比较文件,但设备没有大小,因此必须使用 delta 算法来计算差异,这在本节中进行了描述。技术报告。松散地,远程文件被分成选定大小的块,并且这些块的校验和被发送回。本地文件同样以块为单位进行校验和,并与列表进行比较。然后,远程设备被告知如何重新组装它必须重新制作文件的块,并且发送不匹配的块的数据。

您可以通过仅针对带选项的 deltasum 算法在级别 3 请求调试输出来看到这一点--debug=deltasum3。您可以指定块大小以-B简化数字。例如,对于已经复制过一次的文件,第二次运行

rsync -B 100000 --copy-devices -avv --debug=deltasum3 --no-W /dev/sdd /tmp/mysdd

生成如下所示的输出,显示每个块的校验和:

count=164 rem=84000 blength=100000 s2length=2 flength=16384000
chunk[0] offset=0      len=100000 sum1=61f6893e
chunk[1] offset=100000 len=100000 sum1=32f30ba3
chunk[2] offset=200000 len=100000 sum1=45b1f9e5
...

然后您可以看到它与其他设备的校验和相当简单地匹配,因为没有差异:

potential match at 0      i=0 sum=61f6893e
match at 0      last_match=0      j=0 len=100000 n=0
potential match at 100000 i=1 sum=32f30ba3
match at 100000 last_match=100000 j=1 len=100000 n=0
potential match at 200000 i=2 sum=45b1f9e5
match at 200000 last_match=200000 j=2 len=100000 n=0
...

最后该data=字段为 0,表示没有发送新数据。

total: matches=164  hash_hits=164  false_alarms=0 data=0

如果我们现在通过覆盖文件的中间部分来损坏副本:

echo test | dd conv=block,notrunc seek=80 bs=100000 of=/tmp/mysdd 
touch -r /dev/sdd /tmp/mysdd

然后 rsync 调试向我们显示了块 80 的新校验和,但没有匹配。我们从第 79 场比赛转到第 81 场比赛:

chunk[80] offset=8000000 len=100000 sum1=a73cccfe
...
potential match at 7900000 i=79 sum=58eabec6
match at 7900000 last_match=7900000 j=79 len=100000 n=0
potential match at 8100000 i=81 sum=eba488ba
match at 8100000 last_match=8000000 j=81 len=100000 n=100000

最后我们data=100000表明必须发送一个全新的数据块。

total: matches=163  hash_hits=385  false_alarms=0 data=100000

对于无法匹配的损坏块校验和,匹配数已减少 1。也许哈希命中率上升是因为我们失去了顺序匹配。


如果我们看更远在同一份技术报告中,显示了一些测试结果误报 被描述为“32 位滚动校验和匹配但强校验和不匹配的次数”。每个块都有一个简单的校验和和一个 md5 校验和(旧版本中为 md4)。简单的校验和很容易使用哈希表进行搜索,因为它是一个 32 位整数。一旦匹配到某个条目,还会比较较长的 16 字节 md5 校验和,如果不匹配则误报,继续搜索。

我的示例使用一个非常小的(且旧的)16MB 的 USB 密钥设备,最小哈希表大小为 2**16,即 65536 个条目,因此当保存我拥有的 164 个块条目时,它非常空。如此多的误报是正常的,而且比其他任何事情都更能表明效率。

答案2

您需要考虑使用rsync --partial --inplace以及其他选项,因为否则它将在工作时在目标端制作光盘映像的完整副本。我也一直在使用,-B 4096因为它是设备的自然扇区大小,而 rsync 默认块大小对于此类操作来说太小。

为了再次检查图像是否全部正确复制,我建议sha1sum在源端和目标端都进行独立的操作。这应该不是必需的,但如果您想确定的话,这很简单并且您可以信任它。我假设您的源磁盘不是实时安装或类似的东西,否则所有的赌注都会被取消,并且没有可靠的方法来发送它。

相关内容