![如何在不破坏 GPT 分区表(结束指针)的情况下截断磁盘映像文件中未使用的空间](https://linux22.com/image/1169221/%E5%A6%82%E4%BD%95%E5%9C%A8%E4%B8%8D%E7%A0%B4%E5%9D%8F%20GPT%20%E5%88%86%E5%8C%BA%E8%A1%A8%EF%BC%88%E7%BB%93%E6%9D%9F%E6%8C%87%E9%92%88%EF%BC%89%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E6%88%AA%E6%96%AD%E7%A3%81%E7%9B%98%E6%98%A0%E5%83%8F%E6%96%87%E4%BB%B6%E4%B8%AD%E6%9C%AA%E4%BD%BF%E7%94%A8%E7%9A%84%E7%A9%BA%E9%97%B4.png)
大量关于获取磁盘映像并缩小根 (bionic) 文件系统分区以及截断映像以删除变为可用空间的部分的信息。例如 https://softwarebakery.com//shrinking-images-on-linux
所以基本上有三个步骤。使用 resize2fs 缩小分区上的文件系统,然后减小分区的大小。最后删除映像文件中现在未使用的空间。
这是我遇到问题的第三部分。每次我尝试 dd 或截断时,映像的所有分区都会被删除,就好像映像文件中的 GPT 分区表被破坏了一样。
这是原始图片
GPT fdisk (gdisk) version 1.0.3
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present
Found valid GPT with protective MBR; using GPT.
Disk rock64-base.img: 30310400 sectors, 14.5 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 159DCEDE-DBEA-4657-96D9-2CE178A96B7E
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 30310366
Partitions will be aligned on 64-sector boundaries
Total free space is 30 sectors (15.0 KiB)
Number Start (sector) End (sector) Size Code Name
1 64 8063 3.9 MiB 8300 loader1
2 8064 8191 64.0 KiB 8300 reserved1
3 8192 16383 4.0 MiB 8300 reserved2
4 16384 24575 4.0 MiB 8300 loader2
5 24576 32767 4.0 MiB 8300 atf
6 32768 262143 112.0 MiB 0700 boot
7 262144 30310366 14.3 GiB 8300 root
然后经过前两个步骤
Found valid GPT with protective MBR; using GPT.
Disk test.img: 30310400 sectors, 14.5 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 159DCEDE-DBEA-4657-96D9-2CE178A96B7E
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 30310366
Partitions will be aligned on 64-sector boundaries
Total free space is 23555002 sectors (11.2 GiB)
Number Start (sector) End (sector) Size Code Name
1 64 8063 3.9 MiB 8300 loader1
2 8064 8191 64.0 KiB 8300 reserved1
3 8192 16383 4.0 MiB 8300 reserved2
4 16384 24575 4.0 MiB 8300 loader2
5 24576 32767 4.0 MiB 8300 atf
6 32768 262143 112.0 MiB 0700 boot
7 262144 6755394 3.1 GiB 8300 primary
您可以看到根文件系统分区已减少到 3.1G
我可以正常加载该图像。我可以将其放回 SD 卡并启动我的设备。因此步骤 1 和 2 都没问题。
现在...
如果我完成该过程执行'truncate --size=$[(6755394+1)*512]'test.img'
和
GPT fdisk (gdisk) version 1.0.3
Warning! Disk size is smaller than the main header indicates! Loading
secondary header from the last sector of the disk! You should use 'v' to
verify disk integrity, and perhaps options on the experts' menu to repair
the disk.
Caution: invalid backup GPT header, but valid main header; regenerating
backup header from main header.
Warning! Error 25 reading partition table for CRC check!
Warning! One or more CRCs don't match. You should repair the disk!
Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: damaged
****************************************************************************
Caution: Found protective or hybrid MBR and corrupt GPT. Using GPT, but disk
verification and recovery are STRONGLY recommended.
****************************************************************************
Disk test2.img: 6755395 sectors, 3.2 GiB
Sector size (logical): 512 bytes
Disk identifier (GUID): 159DCEDE-DBEA-4657-96D9-2CE178A96B7E
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 30310366
Partitions will be aligned on 64-sector boundaries
Total free space is 23555002 sectors (11.2 GiB)
Number Start (sector) End (sector) Size Code Name
1 64 8063 3.9 MiB 8300 loader1
2 8064 8191 64.0 KiB 8300 reserved1
3 8192 16383 4.0 MiB 8300 reserved2
4 16384 24575 4.0 MiB 8300 loader2
5 24576 32767 4.0 MiB 8300 atf
6 32768 262143 112.0 MiB 0700 boot
7 262144 6755394 3.1 GiB 8300 primary
显然,truncate(或 dd)与 GPT 配合得并不好。在此文件上运行 gdisk 可确认 gpt 已被破坏
如果我在截断的文件上运行 gdisk,它会报告 GPT 被破坏。
显然我在这里遗漏了一些东西。显然,当磁盘文件的末尾发生变化时,GPT 会损坏或需要修复(不匹配)。即使它在第 2 步结束时没有问题/存在。我摆弄了 gdisk 却无法修复它。除此之外,我想要一个可以用脚本完成的解决方案,但对于这个 GPT 它不起作用。
因此,因为它是 GPT,我是否需要使用除截断或 dd 之外的其他方法,或者我是否必须在截断后手动“修复” GPT。
gdisk verify 报告的内容如下
Caution: The CRC for the backup partition table is invalid. This table may
be corrupt. This program will automatically create a new backup partition
table when you save your partitions.
Problem: The secondary header's self-pointer indicates that it doesn't reside
at the end of the disk. If you've added a disk to a RAID array, use the 'e'
option on the experts' menu to adjust the secondary header's and partition
table's locations.
Problem: Disk is too small to hold all the data!
(Disk size is 6755395 sectors, needs to be 30310400 sectors.)
The 'e' option on the experts' menu may fix this problem.
Problem: GPT claims the disk is larger than it is! (Claimed last usable
sector is 30310366, but backup header is at
30310399 and disk size is 6755395 sectors.
The 'e' option on the experts' menu will probably fix this problem
Partition(s) in the protective MBR are too big for the disk! Creating a
fresh protective or hybrid MBR is recommended.
答案1
GPT 包括磁盘开头的主分区表和磁盘结尾的备份分区表。(字面意思是磁盘的结尾——磁盘的最后几个扇区。)因此,当您截断磁盘映像时,您会删除备份分区表。此外,主分区表中的一些指针和元数据变得无效,因为它们指向(虚拟)磁盘的末尾。这就是命令所v
抱怨gdisk
的大部分内容。
这些都不意味着磁盘已完全损坏。只要主分区表的数据有效,gdisk
(以及大多数其他 GPT 分区工具)就可以恢复。在 中gdisk
,您将键入x
以进入专家菜单,然后键入e
以将备份分区表数据移动到磁盘的新末端,然后键入w
以将更改写入磁盘。(我建议v
再次键入w
,以防我忽略了另一个问题;另请参见下文……)
但请注意,还有一个问题:根据 ,您的磁盘映像大小为 6,755,395 个扇区gdisk
;但最后一个分区的最后一个扇区位于扇区 6,755,394。这没有为备份分区表留下足够的空间(默认情况下,它占用 33 个扇区)。如果您可以重新执行整个过程,您可能应该将磁盘映像缩小一点。如果不行,请尝试将磁盘映像扩大 33*512(16,896)字节,然后再使用 重新创建备份分区表gdisk
。