Skip to content

Instantly share code, notes, and snippets.

@maxim-gorkin
Forked from cabal95/vm-backup.sh
Last active January 28, 2022 04:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save maxim-gorkin/f0e8a2c01a93ca65ad2ad10566a78d72 to your computer and use it in GitHub Desktop.
Save maxim-gorkin/f0e8a2c01a93ca65ad2ad10566a78d72 to your computer and use it in GitHub Desktop.
I use this script to backup my KVM - QEMU virtual machines. More detail: https://wiki.libvirt.org/page/Live-disk-backup-with-active-blockcommit
# Set the language to English so virsh does it's output
# in English as well
# LANG=en_US
SCRIPTNAME=kvm-backup
# Local backup folder
LOCALBKFOLDER=/arc/vm
# Clean local backup folders older then days
ERASEBCKPDAYS=3
# Mounted network backup folder
NETBKFOLDER=/mnt/backup/VMs
echo "Start backup script at $(date +'%d-%m-%Y %H:%M:%S')" | systemd-cat -p info -t $SCRIPTNAME
# List domains
DOMAINS=$(virsh list | tail -n +3 | awk '{print $2}')
for DOMAIN in $DOMAINS; do
echo "Starting backup for $DOMAIN on $(date +'%d-%m-%Y %H:%M:%S')" | systemd-cat -p info -t $SCRIPTNAME
# Generate the backup folder URI - this is something you should
# change/check
BACKUPFOLDER=$LOCALBKFOLDER/$DOMAIN/$(date +%d-%m-%Y)
NBACKUPFOLDER=$NETBKFOLDER/$DOMAIN
echo "Create BACKUPFOLDER = $BACKUPFOLDER" | systemd-cat -p info -t $SCRIPTNAME
mkdir -p $BACKUPFOLDER
echo "Create NBACKUPFOLDER = $NBACKUPFOLDER" | systemd-cat -p info -t $SCRIPTNAME
mkdir -p $NBACKUPFOLDER
# Get the target disk
TARGETS=$(virsh domblklist $DOMAIN --details | grep disk | awk '{print $3}')
# Get the image page
IMAGES=$(virsh domblklist $DOMAIN --details | grep disk | awk '{print $4}')
# Create the snapshot/disk specification
DISKSPEC=""
for TARGET in $TARGETS; do
DISKSPEC="$DISKSPEC --diskspec $TARGET,snapshot=external"
done
echo "Create snapshot for $DOMAIN, DISKSPEC = $DISKSPEC" | systemd-cat -p info -t $SCRIPTNAME
virsh snapshot-create-as --domain $DOMAIN --name "backup-$DOMAIN" --no-metadata --atomic --disk-only $DISKSPEC
if [ $? -ne 0 ]; then
echo "Failed to create snapshot for $DOMAIN" | systemd-cat -p warning -t $SCRIPTNAME
exit 1
fi
# Copy disk image
for IMAGE in $IMAGES; do
NAME=$(basename $IMAGE)
echo "Sync $IMAGE and $BACKUPFOLDER/$NAME" | systemd-cat -p info -t $SCRIPTNAME
rsync -ahW --no-o --no-g --progress $IMAGE $BACKUPFOLDER/$NAME
done
# Merge changes back
BACKUPIMAGES=$(virsh domblklist $DOMAIN --details | grep disk | awk '{print $4}')
for TARGET in $TARGETS; do
echo "Blockcommit for $DOMAIN, TARGET = $TARGET" | systemd-cat -p info -t $SCRIPTNAME
virsh blockcommit $DOMAIN $TARGET --active --pivot # 1>/dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Could not merge changes for disk of $TARGET of $DOMAIN. VM may be in invalid state." | systemd-cat -p warning -t $SCRIPTNAME
exit 1
fi
done
# Cleanup left over backups
for BACKUP in $BACKUPIMAGES; do
echo "Remove $BACKUP" | systemd-cat -p info -t $SCRIPTNAME
rm -f $BACKUP
done
# Dump the configuration information.
echo "Create xml for $DOMAIN - $BACKUPFOLDER/$DOMAIN.xml" | systemd-cat -p info -t $SCRIPTNAME
virsh dumpxml $DOMAIN > $BACKUPFOLDER/$DOMAIN.xml # 1>/dev/null 2>&1
echo "Create xml for $DOMAIN - $NBACKUPFOLDER/$DOMAIN.xml" | systemd-cat -p info -t $SCRIPTNAME
virsh dumpxml $DOMAIN > $NBACKUPFOLDER/$DOMAIN.xml
# Copy disk to network backup disk
for IMAGE in $IMAGES; do
NAME=$(basename $IMAGE)
echo "Copy $BACKUPFOLDER/$NAME to $NBACKUPFOLDER/$NAME" | systemd-cat -p info -t $SCRIPTNAME
cp $BACKUPFOLDER/$NAME $NBACKUPFOLDER/$NAME
done
echo "Finished backup of $DOMAIN at $(date +'%d-%m-%Y %H:%M:%S')" | systemd-cat -p info -t $SCRIPTNAME
done
# Cleanup local backup folders
echo "Delete local backups $LOCALBKFOLDER older then $ERASEBCKPDAYS days" | systemd-cat -p info -t $SCRIPTNAME
find $LOCALBKFOLDER/* -ctime +$ERASEBCKPDAYS -type d -exec rm -r {} +
echo "Finished backup script at $(date +'%d-%m-%Y %H:%M:%S')" | systemd-cat -p info -t $SCRIPTNAME
exit 0
@maxim-gorkin
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment