Plain libvirt has no built-in backup scheduler, but you can make consistent backups of running VMs with an external snapshot: new writes go to a temporary overlay while you copy the now-static base disk, then the overlay is merged back. This guide turns that into a script to back up running KVM VMs with virsh.
Before you start
- A KVM host with file-based disks (qcow2 or raw files). For LVM or ZFS, use their snapshot tools instead.
- The QEMU guest agent running in each VM for filesystem freeze.
- A backup destination off the host (NFS, another server, or object storage).
- Enough free space on the host for overlay files during backup.
How it works
virsh snapshot-create-as --disk-only --quiescefreezes filesystems, creates an overlay and redirects writes to it.- The original disk is now read-only and consistent, so you copy it.
virsh blockcommit --active --pivotmerges the overlay back and switches the VM to the original disk.- Remove the overlay and snapshot metadata.
The backup script
Save as /usr/local/bin/kvm-backup.sh and adapt paths:
#!/bin/bash
set -euo pipefail
VM="$1"
DEST="/mnt/backup/$VM/$(date +%F)"
mkdir -p "$DEST"
virsh dumpxml "$VM" > "$DEST/$VM.xml"
DISK=$(virsh domblklist "$VM" --details | awk '$2=="disk"{print $3; exit}')
SRC=$(virsh domblklist "$VM" --details | awk '$2=="disk"{print $4; exit}')
virsh snapshot-create-as "$VM" bk --disk-only --atomic --quiesce --no-metadata
cp --sparse=always "$SRC" "$DEST/"
virsh blockcommit "$VM" "$DISK" --active --pivot --wait
rm -f "${SRC%.*}.bk"
echo "Backup of $VM done: $DEST"Notes:
- The script handles the first disk only; loop over all disks for multi-disk VMs.
- The overlay file name depends on libvirt's default naming (the base name plus
.bk); check it on your system before relying on thermline. - Remove
--quiesceif the agent is unavailable (the backup will be crash-consistent).
Schedule it
chmod +x /usr/local/bin/kvm-backup.shIn root's crontab:
0 3 * * * /usr/local/bin/kvm-backup.sh web01 >> /var/log/kvm-backup.log 2>&1Add retention, for example deleting folders older than 14 days with find /mnt/backup -mindepth 2 -maxdepth 2 -type d -mtime +14 -exec rm -rf {} +. Copy to another site too, e.g. with rclone.
Restore a VM
- Copy the disk back to its original path.
virsh define /mnt/backup/web01/2025-08-05/web01.xmlvirsh start web01
Troubleshooting
- quiesce fails: guest agent missing or not running.
- blockcommit fails, VM still on overlay: do not delete the overlay; check
virsh domblklistand retry the commit. - Host disk fills during backup: heavy writes grow the overlay; schedule backups at quiet times.
Frequently asked questions
Is there a ready-made tool?
Yes, tools such as virtnbdbackup use libvirt's newer backup API for incremental backups, and Proxmox includes vzdump.
Can I copy the disk without a snapshot?
Only with the VM shut down; copying a live disk gives an inconsistent image.
Should I compress backups?
Yes, with zstd or by converting to compressed qcow2 using qemu-img convert -c.
