如何将 Linux 磁盘映像转换为稀疏文件?

如何将 Linux 磁盘映像转换为稀疏文件?

我在 EXT 分区上有一堆用 ddrescue 制作的磁盘映像,我想在不丢失数据的情况下减小它们的大小,同时仍然可以安装。

如何用零填充图像文件系统中的空白区域,然后将文件转换为稀疏文件那么这个空白空间实际上并没有存储在磁盘上?

例如:

> du -s --si --apparent-size Jimage.image 
120G Jimage.image
> du -s --si Jimage.image 
121G Jimage.image

但实际上,这只有 50G 的真实数据,因此第二次测量应该小得多。

据称这将用零填充空白处:

cat /dev/zero > zero.file
rm zero.file

但如果稀疏文件被透明地处理,它实际上可能会创建一个稀疏文件而不将任何内容写入虚拟磁盘,讽刺的是,这会阻止我将虚拟磁盘映像本身变成稀疏文件。:) 是吗?

注意:由于某种原因,当不在已安装的磁盘映像上sudo dd if=/dev/zero of=./zero.file时可以工作。cat

答案1

首先,仅当您查找时,稀疏文件才会被透明地处理,而不是在您写入零时。

为了更清楚起见,下面是来自维基百科的例子

dd if=/dev/zero of=sparse-file bs=1k count=0 seek=5120

不是写入任何零,它将打开输出文件,寻找(跳过)5MB,然后写入为零(即什么都没有)。此命令(不是(摘自维基百科)

dd if=/dev/zero of=sparse-file bs=1k count=5120

将写入 5MB 的零并且不会创建稀疏文件!

因此,已经非稀疏的文件以后不会神奇地变得稀疏。

其次,要使包含大量零的文件变得稀疏,你必须cp

cp --sparse=always original sparsefile

或者你可以使用柏油同步的 --sparse 选项也是如此。

答案2

也许最简单的方法来稀疏一个文件就是使用fallocate如下实用程序:

fallocate -v --dig-holes {file_name}

错误定位(1)由提供util-linux包装Debian

答案3

为了完整性,编辑我的答案:

  1. 用零填充清空的 FS 空间(警告:这会更改您的磁盘映像):

losetup --partscan --find --show disk.img

假设它将 /dev/loop1 作为磁盘并且只有一个分区,否则我们需要对其中具有可安装 FS 的每个分区重复此操作(忽略交换分区等)。

mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile

让它通过 ENOSPC 失败而告终。

/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1

  1. 复制到稀疏图像中:

‘dd’ 有一个选项可以将包含零的文件转换为稀疏文件:

dd if=disk.img of=disk-sparse.img conv=sparse

答案4

部分图像可以创建仅存储文件系统已使用块的磁盘映像,从而通过忽略未使用的块大幅减少所需空间。我认为您不能直接挂载生成的映像,但可以:

image -> partimage -> image -> cp --sparse=alway

应该会产生你想要的东西(甚至可能坚持最后一步,还没有尝试过)。

相关内容