Implementing VMware-like Snapshot/Rollback Functionality in Libvirt+KVM: Best Practices for Developers


2 views

After transitioning from VMware to KVM for my development environment, the most noticeable gap was the snapshot functionality. While VMware's snapshot system allowed quick state preservation and rollback without downtime, KVM's native snapshot implementation requires guest shutdown and manual disk image management.

Libvirt supports several snapshot types that behave differently:


# Internal snapshots (stored in disk image)
virsh snapshot-create-as --domain vm1 snapshot1 --atomic

# External snapshots (better for production)
virsh snapshot-create-as --domain vm1 snapshot1 \
--disk-only --atomic --no-metadata

Internal snapshots are convenient but limited to qcow2 format. External snapshots create overlay files but offer more flexibility.

For a more VMware-like experience, consider implementing these approaches:


#!/bin/bash
# Create rotating snapshots
VM_NAME="dev-vm"
SNAP_PREFIX="auto-"
MAX_SNAPS=5

current_snaps=$(virsh snapshot-list $VM_NAME | grep "$SNAP_PREFIX" | wc -l)
if [ $current_snaps -ge $MAX_SNAPS ]; then
    oldest=$(virsh snapshot-list $VM_NAME | grep "$SNAP_PREFIX" | head -1 | awk '{print $1}')
    virsh snapshot-delete $VM_NAME $oldest
fi

virsh snapshot-create-as $VM_NAME "${SNAP_PREFIX}$(date +%Y%m%d-%H%M%S)" \
--description "Automatic rotation snapshot" --atomic

For better performance with frequent snapshots:


# LVM thin provisioning example
lvcreate -V10G -T vg0/lvthinpool -n lvvm1
virsh attach-disk vm1 /dev/vg0/lvvm1 vda --config

# Create LVM snapshot
lvcreate -s -n vm1-snap1 -L1G /dev/vg0/lvvm1

For near-zero downtime snapshots:


# Transactional snapshot creation
virsh qemu-monitor-command vm1 --hmp \
"savevm snap1"

# With blockdev mirroring for live operations
virsh qemu-monitor-command vm1 --hmp \
"drive-mirror virtio0 /var/lib/libvirt/images/vm1-snap.qcow2 format=qcow2"
  • virt-snapshot: CLI tool for managing external snapshots
  • snapctl: Python-based snapshot manager with rotation policies
  • Cockpit UI: Web interface with basic snapshot controls

When implementing frequent snapshots:

  1. Monitor chain length (qemu-img info shows backing files)
  2. Periodically commit snapshots to base images
  3. Consider snapshot storage location (SSD preferred)
  4. Test rollback speed during non-critical periods

After transitioning from VMware to KVM/libvirt, many developers encounter the snapshot behavior difference: virsh snapshot-create requires guest shutdown. While this ensures data consistency, it disrupts workflow compared to VMware's live snapshot capability.

For testing environments where absolute consistency isn't critical, consider these approaches:

# Create external snapshot (live)
virsh snapshot-create-as --domain vm1 snap1 --disk-only --atomic --quiesce

# Revert using backing files:
virsh blockcommit vm1 vda --active --pivot

The underlying QEMU provides more flexibility than libvirt's abstraction:

# Live snapshot to new file:
qemu-img create -f qcow2 -b original.qcow2 snapshot.qcow2
# Later merge changes:
qemu-img commit snapshot.qcow2

LVM thin provisioning offers excellent snapshot performance:

# Create thin LV
lvcreate -V 10G -T vg0/lvthin -n vm1

# Take snapshot
lvcreate -s -n snap1 /dev/vg0/vm1 --thinpool vg0/lvthin

Here's a bash script for snapshot rotation:

#!/bin/bash
VM=$1
SNAP_PREFIX=dev_snap
MAX_SNAPS=5

# Rotate existing snapshots
for ((i=$MAX_SNAPS-1; i>=0; i--)); do
  if [ $i -eq 0 ]; then
    virsh snapshot-delete $VM $SNAP_PREFIX
  else
    virsh snapshot-delete $VM $SNAP_PREFIX$i
  fi
done

# Create new snapshot
virsh snapshot-create-as $VM $SNAP_PREFIX \
  --description "Dev environment snapshot" \
  --disk-only --atomic

For mission-critical states, clone the entire VM:

virt-clone --original vm1 --name vm1_snap1 \
  --file /var/lib/libvirt/images/vm1_snap1.qcow2