缩小总磁盘映像:UEFI GPT 闪存驱动器 - 最后的可用空间

Joh*_*her 5 linux boot ssd dd uefi

我有一个来自可启动闪存驱动器的磁盘映像。EFI启动是GPT,所以有一个小的Vfat32分区和另外三个Linux分区,后面还有大约3G的空闲空间。

我需要将磁盘映像复制到稍小的闪存驱动器,因此我需要或多或少地从 15G 缩小到 14G。我将在 linux 上使用 dd 来制作副本。

gparted 非常适合修改和调整分区大小,但最终无法缩小可用空间。理论上应该可以截断文件,但是当我尝试时它会炸毁(?磁盘表?猜测)所以没有分区并且文件被破坏了。如果我使用旋转磁盘和/或 MBR 磁盘,我很确定下面的技术会起作用,但我还没有测试过。

尝试:

dd bs=1M count=14000 iflag=fullblock if=/dev/sda  of=myfile.raw
Run Code Online (Sandbox Code Playgroud)

没有缩小

rsync --sparse filename filename 
Run Code Online (Sandbox Code Playgroud)

这并没有炸毁磁盘表,而是缩小了交换空间并保留了未分配的区域。

qemu-img convert -f raw -O qcow2 -S 4k filename filename (计划转换回原始)

炸毁桌子

truncate size=140000M <filename>
Run Code Online (Sandbox Code Playgroud)

还炸了桌子

cp --sparse=always filename filename
Run Code Online (Sandbox Code Playgroud)

没用

Kam*_*ski 6

应该有一个主(主)GUID 分区表在开头,在由dd. 截断文件会破坏次要文件。有一种方法可以解决它。

让我们从最后带有可用空间的未截断文件开始。运行gdisk -l myfile.raw。注意逻辑扇区大小512B可能)。找到最大的结束扇区(可能是最后一个分区的扇区,但分区条目可能不按顺序排列,因此请仔细查找最大的扇区)。扇区从 开始编号0,因此您需要 (扇区大小)*(最大结束扇区+ 1) 个字节来存储所有分区。

此外,您最后需要至少 33 个完整的可用空间扇区来存储新的辅助 GPT。从维基百科看到这张图片

总共需要(扇区大小)*(最大结束扇区+ 34)字节的文件。将文件截断到这个或更大的大小:

truncate -s <new_size> myfile.raw
Run Code Online (Sandbox Code Playgroud)

下次调用

gdisk myfile.raw
Run Code Online (Sandbox Code Playgroud)

您将获得(除其他外):

警告!磁盘大小小于主标题指示的大小!
注意:无效的备份 GPT 标头,但有效的主标头;从主标题重新生成备份标题。

输入w, 点击Enter写入正确的分区表。您会看到警告,因为辅助 GPT 即将被移动。您在文件末尾有足够的可用空间,因此无需担心。询问时确认。

退出q, Entergdisk再次运行- 应该没有警告。GPT 是固定的


如果您需要使用gparted您的图像,我有一些提示。

命令sudo gparted myfile.raw期望的文件myfile.raw1myfile.raw2等等存在,并用内部的分区对应myfile.raw。如果它是特殊文件,/dev/sdb那么udev会处理/dev/sdb1/dev/sdb2......常规文件不是这种情况。gparted如果没有myfile.rawN文件,许多功能将失败。

要创建此类文件,请使用kpartx(或partx+losetup串联):

sudo kpartx -av myfile.raw
Run Code Online (Sandbox Code Playgroud)

观察其输出(loopXpY创建了哪些设备)并创建指向所有分区的符号链接。第一个可能是:

ln -s /dev/mapper/loop0p1 myfile.raw1
Run Code Online (Sandbox Code Playgroud)

现在gparted应该在这些分区上运行和操作。但是有一个陷阱:当分区更改(例如移动/调整大小)时,创建的映射kpartx不会更新。通常gparted会打电话partprobe或更新/dev/sd*;这在我们的情况下不起作用。您应该销毁映射并重新创建它们。在移动/调整分区大小时运行一项gparted任务、关闭程序、修复映射、运行gparted第二项任务等等。

要销毁映射调用sudo kpartx -dv myfile.raw. 最后删除孤立的符号链接。