Live backup of QEMU/KVM/libVirt virtual machines via Duplicity
Submitted by itefix on Mon, 07/08/2017 - 21:26
The script below can be used to implement an efficient, secure and live backup of QEMU/KVM/libVirt virtual machines via Duplicity. It accepts the domain name and mode (snapshot/suspend) parameters and can handle offline domains and multiple disks as well. XML domain definition is also made as a part of the backup. The Duplicity part is configured for an sftp transfer in our example, but can be adjusted for other types of operations Duplicity supports.
#!/bin/bash # DOMAIN="$1" MODE="$2" if [ -z "$DOMAIN" -o -z $MODE ]; then echo "Usage: ./vm-backup <domain> mode:snapshot|suspend" exit 1 fi logfile=$DOMAIN.virsh.log # check domain state - we handle 'running' or 'shut off' STATE=`virsh dominfo "$DOMAIN" | awk '/State:/ {print $2$3}'` if [ "$STATE" != 'running' -a "$STATE" != 'shutoff' ]; then echo "Domain $DOMAIN is not in a deterministic state ($STATE). Only 'running' or 'shut off' is acceptable." exit 1 fi echo "Beginning backup for $DOMAIN (state $STATE)" # # Get the list of targets (disks) and the image paths. # TARGETS=`virsh domblklist "$DOMAIN" --details | awk '/^file\s+disk/ {print $3}'` IMAGES=`virsh domblklist "$DOMAIN" --details | awk '/^file\s+disk/ {print $4}'` if [ "$STATE" == 'running' ]; then if [ "$MODE" == 'snapshot' ]; then DISKSPEC="" for t in $TARGETS; do DISKSPEC="$DISKSPEC --diskspec $t,snapshot=external" done echo "Create a snapshot for $DOMAIN" virsh snapshot-create-as --domain "$DOMAIN" --name backup --no-metadata --atomic --disk-only $DISKSPEC > $logfile 2>&1 if [ $? -ne 0 ]; then echo "Failed to create snapshot for $DOMAIN" exit 1 fi fi if [ "$MODE" == 'suspend' ]; then virsh suspend "$DOMAIN" fi fi # # Copy disk images # echo "Copy disk images/definition xml for $DOMAIN via Duplicity" FILELIST="" for t in $IMAGES; do FILELIST="$FILELIST --include $t" done # Dump vm definition xml and add to the files list virsh dumpxml "$DOMAIN" > /tmp/$DOMAIN.xml FILELIST="$FILELIST --include /tmp/$DOMAIN.xml" # Duplicity export PASSPHRASE=<backup encryption key> export FTP_PASSWORD=<sftp user password> sftpdest=pexpect+sftp://user@sftp.ser.ver/vm/$DOMAIN duplicity remove-all-but-n-full 3 --force $sftpdest # NB! Keep max-blocksize big (default 2048) for best performance duplicity --full-if-older-than 2M --asynchronous-upload --allow-source-mismatch --verbosity INFO --max-blocksize=20480 --volsize 256 $FILELIST --exclude '**' / $sftpdest # # # Merge changes back if running. # if [ "$STATE" == 'running' ]; then if [ "$MODE" == 'snapshot' ]; then echo "Merge changes back for $DOMAIN" >>$logfile BACKUPIMAGES=`virsh domblklist "$DOMAIN" --details | awk '/^file\s+disk/ {print $4}'` for t in $TARGETS; do virsh blockcommit "$DOMAIN" "$t" --verbose --active --pivot >>$logfile if [ $? -ne 0 ]; then echo "Could not merge changes for disk $t of $DOMAIN. VM may be in invalid state." >>$logfile exit 1 fi done # # Cleanup left over backup images. # for t in $BACKUPIMAGES; do rm -f "$t" done fi if [ "$MODE" == 'suspend' ]; then virsh resume "$DOMAIN" fi fi echo "Finished backup" >>$logfile echo "" |
Related links:
Featured product
Release Announcements
- 2024-11-25 Copssh client 8.0.0
- 2024-11-17 OpenSSL tool 2.0.1
- 2024-11-17 Wrbldnsd 5.0.2