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:
- Create full VM snapshot before operations
- Have backups of critical data
- Verify filesystem integrity at each step
- Monitor progress with
dmesg -w