How to Hot-Resize KVM Virtual Disks Without Rebooting Guests: A Practical Guide


15 views

During my recent infrastructure evaluation for Linux virtualization with KVM, one persistent operational requirement emerged: the need to expand disk capacity for running guests without service interruption. Traditional methods like shutting down VMs or adding secondary disks through hotplugging present maintainability challenges - especially when managing dozens of VMs with varying disk configurations.

Since QEMU 1.5 and libvirt 1.0.6, the qemu-img resize command supports online expansion when using qcow2 format with LVM storage. The critical prerequisites:

# On the KVM host
qemu-img resize /var/lib/libvirt/images/guest.qcow2 +10G

# Then inside the guest OS (assuming LVM):
lsblk # Identify the expanded device
pvresize /dev/vda2
lvextend -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv
resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv

For environments requiring absolute reliability or using raw disk formats, I've developed this workflow combining libvirt hooks and LVM automation:

# 1. Add new disk via virsh
virsh attach-disk guest1 /dev/sdb vdb --persistent

# 2. Automated LVM expansion script (/etc/libvirt/hooks/qemu):
#!/bin/bash
if [ "$2" = "guest1" ] && [ "$1" = "started" ]; then
  ssh root@guest1 <<'EOF'
    pvcreate /dev/vdb
    vgextend ubuntu-vg /dev/vdb
    lvextend -l +100%FREE /dev/ubuntu-vg/root
    resize2fs /dev/ubuntu-vg/root
EOF
fi

Through benchmarking three expansion methods (native resize, LVM stripe expansion, and separate disk hotplug), I observed:

  • Native resize shows 12-15% better IOPS for sequential workloads
  • Multi-disk LVM configurations provide better parallel I/O for database workloads
  • Hotplugged disks add ~300ms latency during peak loads

When the guest OS doesn't detect the new space after host-side expansion:

# Force kernel to rescan SCSI devices
echo 1 > /sys/class/scsi_device/0\:0\:0\:0/device/rescan

# For virtio-blk devices:
virsh qemu-monitor-command guest1 --hmp "info block"
virsh qemu-monitor-command guest1 --hmp "block_resize drive-virtio-disk0 20G"

When working with KVM virtualization, one of the most common operational challenges is expanding disk capacity for running virtual machines. Traditional approaches require:

  • Shutting down the guest VM
  • Using qemu-img resize on the host
  • Rebooting and manually expanding partitions/filesystems

This downtime becomes unacceptable in production environments where continuous availability is critical.

The workaround you mentioned - adding new virtual disks via hotplug and extending LVM volumes - is technically sound but introduces management complexity. Here's how it typically works:

# On the host
virsh attach-disk vm1 /path/to/newdisk vdb --cache none --persistent

# Inside the guest
pvcreate /dev/vdb
vgextend vg_main /dev/vdb
lvextend -l +100%FREE /dev/vg_main/lv_root
resize2fs /dev/vg_main/lv_root

The main disadvantages are:

  • Multiple disk devices to track (vda, vdb, vdc...)
  • Potential performance impact from striped storage
  • Complicated snapshot and backup procedures

Modern QEMU versions support true online resizing of existing virtual disks without requiring additional devices. Here's the complete workflow:

# On the KVM host (example for raw format)
qemu-img resize vm1-disk1.raw +20G

# Notify the guest about size change
virsh blockresize vm1 vda --size 30G

# Inside the guest (for LVM)
echo 1 > /sys/class/block/vda/device/rescan
pvresize /dev/vda
lvextend -r -l +100%FREE /dev/vg_main/lv_root

Several factors affect the success of online resizing:

Requirement Details
QEMU Version Minimum 2.5 for reliable operation
Disk Format Works with raw/qcow2 (qcow2 requires free host space)
Guest OS Linux with LVM recommended (Windows requires special handling)
Storage Backend Local/SAN works, some cloud storage may have limitations

Here's a complete example expanding a CentOS 7 VM from 40GB to 60GB:

# Host operations
qemu-img info /var/lib/libvirt/images/web1.qcow2
# Current size: 40G

qemu-img resize /var/lib/libvirt/images/web1.qcow2 +20G
virsh blockresize web1 vda --size 60G

# Guest operations (as root)
lsblk # Verify vda shows new size
pvresize /dev/vda
lvextend -r -l +100%FREE /dev/centos/root
df -h # Verify expanded filesystem

If the size change isn't detected:

  • Check kernel messages with dmesg | grep capacity
  • Manually trigger rescan: echo 1 > /sys/block/vda/device/rescan
  • For older kernels (3.x), may need to delete/re-add device:
echo 1 > /sys/block/vda/device/delete
echo "- - -" > /sys/class/scsi_host/host0/scan

For Windows guests, use Disk Management console to extend volumes after the virtual disk resize.