在我们通过 qemu 工具创建镜像,并通过 parted 工具划分镜像时,且镜像格式设置为 msdos 时可能遇上这样的问题
qemu-img create system.img "${IMG_SIZE}G"
local BOOT_PATH=${TMP_MOUNT_PATH}/boot/grub2
parted system.img -s mklabel msdos
parted system.img -s mkpart primary 1MiB 80MiB
parted system.img -s mkpart primary 80MiB 3180MiB
parted system.img -s mkpart primary 3180MiB 4280MiB
parted system.img -s mkpart extended 4280MiB 100%
parted system.img -s mkpart logical 4280MiB 6380MiB
parted system.img -s mkpart logical 6380MiB 7380MiB
parted system.img -s mkpart logical 7380MiB 100%
parted system.img -s set 1 boot on
当我在分配空间时,提示
错误: 您要求将分区从 4280MB 移动到 21.5GB (扇区 8359375..41943039)
我们可以管理的最近的分区是从4488MB 到 21.5GB (扇区 8765440..41943006)
奇怪的是,我临近分区的大小以 4280 为边界,逻辑分区为什么不能以 4280 开始呢?
查了很久的资料,很有可能是 parted 为了防止分区冲突,在每个分区边界附近保留了一个小的缓冲区导致的这个问题。
从操作系统的角度来看,分区表和文件系统的区别需要注意:
- 分区表操作是在块设备的元数据中定义分区起止位置,并不真正占用空间。
- 而初始化文件系统是在这些分区内真正写入数据占用空间。
parted在移动分区位置时,是操作分区表的元数据,调整起止位置信息。这时可能会在分区边界留出很小的缓冲区(比如512字节),从而造成实际可用空间比显示的少一点。
但文件系统在格式化分区时,会将整个分区空间全部使用。所以文件系统格式化后,可用空间会比parted显示的稍大。这个细微的差异,加上parted内部为防止重叠保留的缓冲区,就可能导致这种奇怪的错误。
解决方案:我们可以通过验证一下重叠情况,确认自己系统的工具会为缓冲区预留多大的空间,然后在划分之后的分区时预留上这部分缓冲区,就能够解决这个问题了。