我在 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
答案2
也许最简单的方法来稀疏一个文件就是使用fallocate
如下实用程序:
fallocate -v --dig-holes {file_name}
错误定位(1)由提供util-linux包装Debian。
答案3
为了完整性,编辑我的答案:
- 用零填充清空的 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
- 复制到稀疏图像中:
‘dd’ 有一个选项可以将包含零的文件转换为稀疏文件:
dd if=disk.img of=disk-sparse.img conv=sparse
答案4
部分图像可以创建仅存储文件系统已使用块的磁盘映像,从而通过忽略未使用的块大幅减少所需空间。我认为您不能直接挂载生成的映像,但可以:
image -> partimage -> image -> cp --sparse=alway
应该会产生你想要的东西(甚至可能坚持最后一步,还没有尝试过)。