将整个分区或硬盘驱动器克隆到稀疏文件


35

我喜欢将整个分区或整个硬盘驱动器克隆到更大的外部磁盘上,但喜欢创建一个稀疏文件。我经常dd用于克隆,但它不支持稀疏文件。作为解决方法,我使用了类似的方法:

cp --sparse=always <(dd if=/dev/sda1 bs=8M) /mount/external/backup/sda1.raw

但是,这对于我的口味来说有点棘手,并且如果中止,也不允许我继续该过程。有趣的是,有一个用于此(ntfsclone)的NTFS工具,但是对于Linux(EXT2-4)的本机文件系统不存在这样的工具。

有没有更好的工具,例如dd,支持稀疏的变体?我没有寻找用于磁盘备份的某些专有软件,而只是想制作一个稀疏的克隆副本,如果需要的话,我可以将其安装为循环设备。


7
+1用于创造性地使用cp,我从未想到您可以稀疏复制磁盘映像。如果需要节省空间,我总是压缩它们。现在为什么在一个问题中不是答案?
Caleb

Answers:


21

你要dd_rescue

dd_rescue -a -b 8M /dev/sda1 /mount/external/backup/sda1.raw

1
大!该手册说:“如果用户中断了复印过程,则以后可以在任何位置继续进行。” 和“ -a spArse文件写入(默认=否)”。正是我想要的!谢谢!
Martin Scharrer 2011年

3
dd_rescue网上寻找时,我发现还有一个名为ddrescue(不带下划线)的工具是独立于其他工具开发的,dd_rescue但似乎基本相同。我只是在此提及,仅供参考。
Martin Scharrer 2011年

是啊,dd_rescue而且ddrescue是不一样的东西。从理论上讲,他们做的是相同的工作,但总的来说,我对年长的/原创的人比较幸运dd_rescue
史蒂文·普里查德

1
万一有人怀疑,可以随时使用Ctrl-C停止复制。它将显示您的当前位置,并且您可以使用该值通过将-s位置添加到原始命令来重新启动。(所以看起来像dd_rescue -a -b 8M -s 42000k /dev/sda1 /mount/external/backup/sda1.raw。)
史蒂文·普里查德

1
@Steven Pritchard:无需记住位置。指定第三个文件名,它将是日志文件,并且在重新启动时,它将读取该文件名并从上次中断的地方继续。
Tanith Rosenbaum 2014年

20

为了完整起见,请致电ddrescue。该--sparse-S标志允许稀疏写入的目标:

$ ddrescue -S -b8M /dev/sda1 /mount/external/backup/sda1.raw

或使用长选项:

$ ddrescue --sparse --block-size 8M /dev/sda1 /mount/external/backup/sda1.raw

或者,如果您喜欢MiB

$ ddrescue -S -b8Mi /dev/sda1 /mount/external/backup/sda1.raw

为了允许救援被中断并继续进行,您还可以使用日志文件:

$ ddrescue -S -b8Mi /dev/sda1 /mount/external/backup/sda1.raw ~/sda1.rescue.log

注意,GNU ddrescuedd_rescue是不同的程序。但是GNU ddrescue似乎更普遍。例如,它已经与GRML打包在一起。


还原时是否需要对映像进行任何特殊处理,是否可以提供用于还原ddrescue的命令?
user12439 '16

从理论上讲,您用于救援的存储介质应该更可靠,因此通常可以使用dd写入替换磁盘:dd if=sda1.raw of=/dev/sdb1。但是,要将ddrescue用于还原,只需将用于救援的源/目标更改为新的源/目标,最好使用新的日志文件。如果可能(通常不是),您当然可以使用ddrescue将数据直接从错误的源磁盘复制到替换磁盘。
zaTricky

3

2007年提供了一个修补程序,以在GNU dd中提供稀疏文件支持,但它似乎尚未纳入coreutils(至少从8.4起)。我怀疑dd从那时以来变化太大,该补丁可能适用于当前版本而无需进行大量工作。

cp问题的创造性用法也给我留下了深刻的印象,它使我走上了用它来完成恢复的轨道(此处从〜80M恢复到源代码):

cp --sparse=always \
  <(dd if=/dev/sda1 bs=8M skip=10) /dev/stdout \
  | dd bs=8M seek=10 of=/mount/external/backup/sda1.raw

编辑:刮擦。第二个dd当然会在输出文件中寻找错误的位置,因为它的长度与输入的长度不同。


1
就像bhinesley的答案一样,最好记录dd的进度以进行准确的恢复。如果要对首次运行和恢复都使用此方法,并分别记录两个并行dd,则可以知道要查找的输出有多远。如果有时间,我会尽力而为。
伊莱·黑迪

2
感谢您提供补丁的链接。我开始考虑自己编写类似的程序:-)无法插入稀疏文件,因此您的代码将无法工作。
马丁·沙勒

是的,我只是发现自己。哦,很好,找到疯狂的新用途很有趣cp-谢谢!
Eli Heady

1
dd在2012年提交:git.savannah.gnu.org/cgit/coreutils.git/commit/… “ dd:添加对conv = sparse选项的支持”(“(iwrite):将NUL块的写入转换为seek如果需要的话。”)
osgx

1

只需加上我的2美分。从原始磁盘创建稀疏文件的另一种方法是使用qemu-img,例如:

qemu-img convert -f raw /dev/sda /tmp/sda.raw

您也可以在单个分区上使用它。另外,您还可以选择将原始磁盘/分区转换为qemu-img支持的任何其他格式(QCOW2,VHD [x],vmdk等)


1

另一个选择是rsync。例如:

rsync -SP --copy-devices /dev/sda1 /mount/external/backup/sda1.raw

说明:

  • -S/ --sparse在写入时跳过稀疏块
  • -P/ --partial --progress显示进度并保留部分传输的文件
  • --copy-devices 复制设备内容

您可以添加--append以恢复中断的副本(或--append-verify确认新旧数据匹配的校验和)。

编辑:我刚刚意识到copy-devices.diff正在考虑中,可能不会出现在许多系统上(尽管FedoraUbuntuDebian等包含了它)


0

注意:由于注释中所述的原因,此方法不起作用,这里将其留作参考。

通过使用kill -USR1监视dd的统计信息:

$ cp --sparse=always <(dd if=/dev/urandom bs=8M) \
    /mount/external/backup/sda1.raw&
$ watch kill -USR1 `pidof -s /bin/dd`

通过使用跳过/搜索来恢复:

$ i_bytes= # get from the last dd statistic
$ o_bytes=`du -b /mount/external/backup/sda1.raw | cut -f 1`   
$ cp --sparse=always <(dd if=/dev/urandom bs=8M skip=$i_bytes \
    seek=$o_bytes) /mount/external/backup/sda1.raw&
$ watch kill -USR1 `pidof -s /bin/dd`

没有$ i_bytes,恢复将更加困难。万一机器崩溃或其他原因,将dd统计信息记录到文件中可能是最容易的。


第二个cp将覆盖现有文件,不是吗?我知道的skip和其他选择dd。问题是cp一部分。
马丁·沙勒

嗯,是的,你是对的。
bhinesley 2011年


0

为什么不简单地:

cp --sparse=always /dev/sda1 /mount/external/backup/sda1.raw
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.