我有一个来自可启动闪存驱动器的磁盘映像。它是用于 EFI 启动的 GPT,因此有一个小的 Vfat32 分区和另外三个 Linux 分区,后面还有大约 3G 的可用空间。
我需要将磁盘映像复制到稍小的闪存驱动器,因此我需要将空间从 15G 缩小到 14G 左右。我将在 Linux 上使用 dd 进行复制。
gparted 非常适合修改和调整分区大小,但它无法缩小最后的可用空间。理论上应该可以截断文件,但当我尝试时,它会炸毁(“磁盘表”?猜测),因此没有分区,文件被毁了。我很确定如果我使用旋转磁盘和/或 MBR 磁盘,下面的技术会起作用,但我没有测试过。
尝试过:
dd bs=1M count=14000 iflag=fullblock if=/dev/sda of=myfile.raw
没有缩水
rsync --sparse filename filename
这并没有破坏磁盘表,但缩小了交换空间并保留了未分配区域。
qemu-img convert -f raw -O qcow2 -S 4k filename filename
(计划转换回原始)
炸毁桌子
truncate size=140000M <filename>
还炸毁了桌子
cp --sparse=always filename filename
没有用
答案1
所创建的原始文件的开头应该有一个主 GUID 分区表,结尾应该有一个辅助(备份)GUID 分区表dd
。截断文件会破坏辅助 GUID 分区表。有一种方法可以修复它。
让我们从未截断且末尾有可用空间的文件开始。运行gdisk -l myfile.raw
。注意逻辑扇区大小(可能512B
,或可能4096B
)。找到最大末端区域(可能是最后一个分区的分区,但分区条目可能按顺序排列,也可能不按顺序排列,因此请仔细查找最大的分区)。扇区从 开始编号0
,因此您需要(扇区大小)*(最大末端扇区+1)字节来存储所有分区。
此外,您最后还需要至少 33 个完整的可用空间扇区来存储新的辅助 GPT。请参阅这张图片来自维基百科。
总共你需要(扇区大小)*(最大末端扇区+ 34) 字节的文件。将文件截断为以下大小或更大的大小:
truncate -s <new_size> myfile.raw
下次调用
gdisk myfile.raw
您将获得(除其他外):
警告!磁盘大小小于主标头指示的大小!
注意:备份 GPT 标头无效,但主标头有效;从主标头重新生成备份标头。
键入w
,点击Enter写入正确的分区表。您将看到警告,因为次要 GPT 即将移动。文件末尾有足够的可用空间,因此无需担心。询问时确认。
使用q
,退出Enter。再次运行gdisk
– 应该不会有任何警告。GPT 已修复。
如果您需要使用gparted
您的图像,我有一些提示。
该命令sudo gparted myfile.raw
要求文件myfile.raw1
等myfile.raw2
存在并与 内的分区相对应myfile.raw
。如果是特殊文件,/dev/sdb
则udev
需要处理/dev/sdb1
,/dev/sdb2
… 常规文件则不是这种情况。gparted
如果没有myfile.rawN
文件,许多功能将失败。
要创建此类文件,请使用kpartx
(或partx
+losetup
串联):
sudo kpartx -av myfile.raw
观察其输出(loopXpY
创建了哪些设备)并创建指向所有分区的符号链接。第一个可能是:
ln -s /dev/mapper/loop0p1 myfile.raw1
现在gparted
应该运行并操作这些分区。但是有一个陷阱:当分区发生变化(例如,移动/调整大小)时,由 创建的映射kpartx
不会更新。通常gparted
会调用partprobe
或其他东西来更新/dev/sd*
;这在我们的例子中不起作用。您应该销毁映射并重新创建它们。在移动/调整分区大小时,运行一个gparted
任务,关闭程序,修复映射,运行gparted
第二个任务,依此类推。
要销毁映射,请调用sudo kpartx -dv myfile.raw
。删除最后的孤立符号链接。