How to Shrink a KVM Virtual Machine Disk Image: Step-by-Step Guide for LVM and Ext4


2 views

When working with KVM virtual machines, you might find yourself needing to reclaim unused disk space from an over-provisioned virtual disk. Unlike expanding disk images (which is relatively straightforward), shrinking them requires careful handling of both the filesystem and underlying storage layers.

Before proceeding, ensure you have:

  • A backup of your VM
  • Root access to the host system
  • The libguestfs-tools package installed
  • Enough free space on your host for temporary operations

First, we need to shrink the Ext4 filesystem within the LVM:

# Connect to your VM
virsh console vm1

# Check filesystem size
df -h

# Unmount if possible (recommended for safety)
umount /dev/vda5

# Run filesystem check
e2fsck -f /dev/vda5

# Resize the filesystem (adjust size as needed)
resize2fs /dev/vda5 250G

Now we'll adjust the LVM structures:

# Display current PV information
pvs

# Resize the physical volume
pvresize --setphysicalvolumesize 250G /dev/vda5

# Verify the changes
pvdisplay

# Resize the logical volume (adjust to your needs)
lvresize -L 250G /dev/vgname/lvname

After shrinking the internal structures, we can reclaim space from the disk image:

# Shut down the VM
virsh shutdown vm1

# Convert the image to a sparse file
qemu-img convert -O qcow2 vm1.img vm1_new.img

# Verify the new size
qemu-img info vm1_new.img

# Replace the old image (after confirming the new one works)
mv vm1_new.img vm1.img

For raw disk images, virt-resize can be more efficient:

# Install required tools
apt-get install libguestfs-tools

# Create a new smaller disk image
qemu-img create -f qcow2 vm1_resized.img 250G

# Resize the VM
virt-resize --shrink /dev/vda5 vm1.img vm1_resized.img

# Verify the operation
virt-filesystems --long -h --all -a vm1_resized.img
  • Always maintain backups before resizing operations
  • The process may take significant time for large disks
  • Some filesystems may require additional steps (e.g., XFS needs different tools)
  • Check for filesystem errors after resizing

If you encounter errors about minimum size requirements:

# Find minimum size for your filesystem
resize2fs -P /dev/vda5

# If pvresize doesn't work, try forcing with --yes
pvresize --setphysicalvolumesize 250G --yes /dev/vda5

For LVM activation issues:

# Activate volume group if needed
vgchange -ay vgname

# Deactivate before finalizing changes
vgchange -an vgname

Shrinking KVM disk images is more complex than expanding them because:

  • Filesystem must be reduced before the underlying storage
  • LVM requires careful handling of physical/logical volumes
  • Partition table modifications are risky without proper backups

Before beginning:


sudo apt-get install lvm2 gparted libguestfs-tools e2fsprogs
sudo virsh shutdown vm1

First check current usage and reduce ext4:


sudo e2fsck -f /dev/vg0/lv_root
sudo resize2fs /dev/vg0/lv_root 200G

Reduce the logical volume (add 5% buffer):


sudo lvreduce -L 210G /dev/vg0/lv_root
sudo pvresize --setphysicalvolumesize 215G /dev/vda5

Using fdisk to modify partition table:


sudo fdisk /dev/vda
# Delete partition 5 (LVM)
# Create new smaller partition (set start sector same as original)
# Set partition type to 8e (Linux LVM)
# Write changes
sudo partprobe

Convert and shrink the image file:


sudo qemu-img convert -O qcow2 vm1.img vm1-smaller.qcow2
sudo qemu-img resize --shrink vm1-smaller.qcow2 250G

After restarting the VM:


df -h
sudo vgs
sudo pvs
lsblk

For raw images without LVM:


sudo virt-resize --shrink /dev/sda1 vm1-original.img vm1-resized.img
  • If resize2fs fails: sudo e2fsck -fy /dev/vg0/lv_root
  • When pvresize doesn't work: sudo vgchange -an vg0 then retry
  • For partition table errors: sudo gdisk /dev/vda

Always:

  1. Create full VM snapshot before operations
  2. Have backups of critical data
  3. Verify filesystem integrity at each step
  4. Monitor progress with dmesg -w