Increasing Disk Size on a QEMU Disk Image
A disk image is a file that contains the data of a virtual disk, often used to simulate computational environments in virtualization. In the context of QEMU (Quick Emulator), the two most commonly used disk image formats are QCOW2 (QEMU Copy-On-Write version 2).

One important concept in disk images is virtual size. Virtual size refers to the total disk capacity that is visible to the guest operating system (guest OS). The virtual size represents the maximum storage space that can be utilized by the guest OS, even though the disk image file itself may not use all of that space on the host.

Displaying Virtual Size and Actual Size Information

To display information about the virtual size and actual size of a disk image, we can use the qemu-img command, which is a built-in utility of QEMU.

qemu-img info ubuntu.img

Output:

image: ubuntu.img
file format: qcow2
virtual size: 3.5 GiB (3758096384 bytes)
disk size: 582 MiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
    extended l2: false
  • virtual size: the maximum disk capacity visible to the guest OS, 3.5GB.
  • disk size: the actual size of the disk image file on the host, 582MB.

Another example, the Rocky Linux disk image:

image: rocky.qcow2
file format: qcow2
virtual size: 10 GiB (10737418240 bytes)
disk size: 582 MiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
    extended l2: false

Increasing Disk Image Capacity (Resize)

If more space is needed for the guest OS, we can increase the virtual size of the disk image using the qemu-img resize command. This process only adds free space; you will still need to expand the partition within the guest OS afterward.

To increase the disk capacity to 30GB:

qemu-img resize ubuntu.img 30G

Output:

Image resized.

Verify the resize results:

qemu-img info ubuntu.img

Output:

image: ubuntu.img
file format: qcow2
virtual size: 30 GiB (32212254720 bytes)
disk size: 582 MiB
cluster_size: 65536
Format specific information:
    compat: 1.1
    compression type: zlib
    lazy refcounts: false
    refcount bits: 16
    corrupt: false
    extended l2: false

Expanding the Partition

Log in to the guest OS or virtual machine, then view the existing partitions and their capacities.

lsblk

Output:

NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda     253:0    0   30G  0 disk 
├─vda1  253:1    0  2.5G  0 part /
├─vda14 253:14   0    4M  0 part 
├─vda15 253:15   0  106M  0 part /boot/efi
└─vda16 259:0    0  913M  0 part /boot

In this example, vda has a size of 30GB, while the partition vda1 is only 2.5GB. The remaining disk space will be entirely allocated to the vda1 partition.

Expanding the vda1 partition:

growpart /dev/vda 1

Output:

CHANGED: partition=1 start=2099200 old: size=5240799 end=7339998 new: size=60815327 end=62914526

Then resize2fs:

resize2fs /dev/vda1

Output:

resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/vda1 is mounted on /; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 4
The filesystem on /dev/vda1 is now 7601915 (4k) blocks long.

Verify the results using lsblk or df -h:

root@ubuntu:~# lsblk 
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
vda     253:0    0   30G  0 disk 
├─vda1  253:1    0   29G  0 part /
├─vda14 253:14   0    4M  0 part 
├─vda15 253:15   0  106M  0 part /boot/efi
└─vda16 259:0    0  913M  0 part /boot


root@ubuntu:~# df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs            97M  1.0M   96M   2% /run
/dev/vda1        29G  1.6G   27G   6% /
tmpfs           481M     0  481M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
/dev/vda16      881M   61M  758M   8% /boot
/dev/vda15      105M  6.1M   99M   6% /boot/efi
tmpfs            97M   12K   97M   1% /run/user/0

The disk and partition sizes have been successfully increased.