如何调整用dd创建的img文件的大小?


19

我有一个来自4GB SD卡的DD映像,该映像具有两个分区,这两个分区仅占用约800 MB的空间,因此,我希望减小img fie的大小。

有谁知道从img文件中删除“可用空间”的方法吗?


您可能需要添加所需的结果。即:将图像返回卡,以存储在CD上。
韦恩

Answers:


8

首先,请确保可用空间实际上是空的,并且不包含已删除文件的剩余空间。实现此目的的最简单方法是在磁盘上创建一个仅包含空字节的巨大文件,然后将其删除。

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

然后使用诸如gzip或的工具将其压缩xz。即使在最低压缩级别下,一连串的零也会很好地压缩:

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

请注意,将映像写回到磁盘时必须解压缩映像。这将“实时”解压缩:

# cat foo.img.gz | gunzip | dd of=/dev/sda

请注意,输出设备(sda)的大小必须足以容纳原始图像,否则数据将丢失或损坏。


如果要继续使用该映像(例如与虚拟机一起使用),另一种方法是将原始映像转换为虚拟化软件使用的一种映像格式。例如,用于Qemu的qcow2,用于VirtualBox的VDI或用于VMware的VMDK。

请注意,这仍然需要您使用上述方法通过清洁可用空间来准备图像。

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

但是,如果要将其再次写入实际磁盘,则必须将其转换回原始映像。


1
您如何确定当前存储在分区上的所有文件没有物理分散在磁盘上?
Valerio Santinelli 2014年

因为我认为文件没有按顺序写入磁盘,并且如果文件位于存储的末尾,那么当我减小大小时,我将丢失该文件的内容。
Valerio Santinelli 2014年

因为OP正在询问如何缩小磁盘映像而不丢失数据。如果您以特定大小截断图像,则无法确保将保留数据。
Valerio Santinelli 2014年

@ValerioSantinelli:我到底建议在哪里截断图像?
user1686

1
@ValerioSantinelli:在将文件写入较小的设备之前,通过对文件系统使用适当的文件系统调整大小工具(例如resize2fsntfsresize(Linux没有FAT工具),或者通过创建新的文件系统并仅复制文件来进行调整。
user1686 2014年

22

使用resize2fs要容易得多

resize2fs -M xxx.img

您将被要求先使用e2fsck-因此:

e2fsck -f -y xxx.img

(不得安装映像!)

注意:这仅在映像属于单个分区的情况下才有效,如果它是具有多个分区的整个块设备,请参见上面的答案...


请注意:对于多个分区,用于losetup --find --partscan xxx.img将映像文件设置为循环设备。然后运行lsblk以查找循环设备的分区。
熊义辉

看来它不适用于包含操作系统的ISO映像。调整大小后,系统无法启动。
SR

@SR Linux操作系统?
罗尔夫

1
这是一个很好的答案,但resize2fs仅适用于extN类型分区。其他类型的分区将需要其他工具。
罗尔夫

2

我也使用qemu-img尝试了一下,它就像一个魅力:

qemu-img resize test.img 2G

我们正在调整其大小test.img以使其达到2G(2GB)。

为我工作完美。


1
太棒了,对我来说也完美无缺,压缩了Raspbian图像。充分工作!
ffleandro

好了,一切正常,但是在启动后,运行df -h显示原始大小。这怎么可能?
ffleandro

显然,qemu-img不是分区表,那么它如何压缩.img?
ffleandro '19

我可以将.img磁盘的大小调整为1M,这肯定会破坏磁盘映像。有什么想法可以使调整大小更安全吗?
lesca

1

我在我的Ubuntu 16.10计算机上使用了gparted方法:

1)使用,将img文件映射到下一个可用的循环分区losetup,如上述先前文章所述

2)检查 lsblk图像文件映射到哪个循环驱动器,例如/dev/loop0

3)执行 sudo gparted /dev/loop0

4)适当缩小环路分区;请确保卸载这些分区。

5)执行fdisk /dev/loop0,然后输入p,这将向您显示各个分区的块大小和结束块号。

6)执行dd if=/dev/loop0 of=shrunk_image_file.img,适用于该命令的选项bs=[BlockSize]count=[EndBlockNumberOfLastLoopPartition+1],你将有一个缩水,rightsized图像文件。

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.