扩展 QEMU 虚拟磁盘容量

2022-11-20 ⏳2.6分钟(1.0千字) 🕸️

最近使用 QEMU 测试 ARM 平台,使用的虚拟磁盘是从网上下载的,总空间不到两吉字节。我安装 clang 工具链,装到一半就把磁盘占满了。所以从网上查到了扩展虚拟磁盘容量的办法,分享给大家。

首先是扩展虚拟磁盘文件的实际容量。这一步需要使用qemu-image命令:

$ qemu-img resize disk1.img +2G

想加多少就指定多少。扩容结束后会输出image resized

使用扩容后的磁盘文件启动 Linux 系统,查看磁盘信息:

$ lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda         8:0    0  3.7G  0 disk
├─sda1      8:1    0  256M  0 part /boot
└─sda2      8:2    0  3.5G  0 part / # 已扩容
sr0        11:0    1 1024M  0 rom
mtdblock0  31:0    0   64M  0 disk

这时候/dev/sda2已经是扩容后的容量了。但是 Linux 各分区的容量并没有变化:

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       1.5G  1.3G   28M  98% /
/dev/sda1       253M   53M  200M  21% /boot

这是为什么呢?Linux 系统无法直接使用/dev/sda设备,而是要先对它进行分区。分区之后还要把各分区格式化成不同的文件系统。每个磁盘设备都有一个分区表,记录分区的数量、开始和结束位置等信息。每个分区格式化后又会预留特殊的区域保存当前文件系统的大小等信息。如果这些信息不更新,Linux 系统就无法使用新扩展的磁盘容量。

所以,接下来我们还得修改修改分区表。这一步需要用fdisk命令。

先查看当前分区列表。打开fdisk后执行p子命令:

$ fdisk
Command (m for help): p
Disk /dev/sda: 3.7 GiB, 3997171712 bytes, 7806976 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x738a4d67

Device     Boot  Start     End Sectors  Size Id Type
/dev/sda1         8192  532479  524288  256M  c W95 FAT32 (LBA)
/dev/sda2       532480 3612671 3080192  1.5G 83 Linux

这个时候/dev/sda2还是扩容之前的大小。fdisk没有专门的扩容命令。只能先删除再创建。这一步一定要小心,如果操作失误,所有文件就找不回来了😂删除之前要记录分区开始的位置,本例中是532480

删除分区使用d子命令,fdisk默认会删除最后一个分区:

Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

删除之后可以执行p查看效果:

Command (m for help): p
Disk /dev/sda: 3.7 GiB, 3997171712 bytes, 7806976 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x738a4d67

Device     Boot Start    End Sectors  Size Id Type
/dev/sda1        8192 532479  524288  256M  c W95 FAT32 (LBA)

紧接着使用n子命令创建新的分区:

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p):

Using default response p.
Partition number (2-4, default 2):
First sector (2048-7806975, default 2048): 532480
Last sector, +/-sectors or +/-size{K,M,G,T,P} (532480-7806975, default 7806975):

Created a new partition 2 of type 'Linux' and of size 3.5 GiB.
Partition #2 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: No

因为是 DOS 分区表,需要选择是主分区还是扩展分区。如果是 GPT 分区表则没有这一步。我这里是主分区。然后选择分区编号。 DOS 分区表最多支持四个主分区,或者三个主分区外加多个扩展分区。我这里只有两个分区,都是主分区。需要扩展的分区编号为二。最后是输入分区开始的位置,也就在删除老分区前记录的位置。结束位置不需要输入,直接按回车,默认会占满磁盘剩余容量。确认之后fdisk会修改分区表。修改完成会提示 Do you want to remove the signature?。这一步很关键,一定要选No

在保存之预览一下效果:

Command (m for help): p

Disk /dev/sda: 3.7 GiB, 3997171712 bytes, 7806976 sectors
Disk model: QEMU HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x738a4d67

Device     Boot  Start     End Sectors  Size Id Type
/dev/sda1         8192  532479  524288  256M  c W95 FAT32 (LBA)
/dev/sda2       532480 7806975 7274496  3.5G 83 Linux

第二个分区已经扩容了。执行子命令w保存修改并退出。这就完成了分区表的修改。

此时新扩展的空间还是没有生效,因为我们还需要修改文件系统信息:

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       1.5G  1.3G   28M  98% /
/dev/sda1       253M   53M  200M  21% /boot

最后我们修改文件系统信息。不同的文件系统需要使用不同的工具。我用的是 EXT4,扩展需要resize2fs命令。如果是 XFS 系统,则需要xfs_growfs命令。

resize2fs /dev/sda2
# 或者 resize2fs /
resize2fs 1.44.5 (15-Dec-2018)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/sda2 is now 909312 (4k) blocks long.

到这里才彻底完成扩容:

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       3.4G  1.4G  2.0G  41% /
/dev/sda1       253M   53M  200M  21% /boot

最后总结一下,Linux 下的磁盘系统包括设备、分区表和文件系统三个层面的信息。扩容需要先给设置扩容,同时还要修改分区表和文件系统信息。整个过程一定要慎重,一不小心就会损坏整个文件系统,进而丢失所有文件。大家可以先搞一个测试用的虚拟机,多演练几遍。等真正熟练之后再操作生产环境。数据无价,慎重操作。

参考链接: