Created
August 22, 2018 17:58
-
-
Save NickCrew/4e101cfb247432a5a0db3b65bd1cdd5a to your computer and use it in GitHub Desktop.
Libvirt Live Snapshot with Block Commit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Take an external snapshot with virsh using live block commit feature | |
# | |
# Usage: ./snap domain-name backup-destination prune_lvl(integer) | |
# | |
# Creates log collection directory in backup-destination | |
# | |
# PRUNE_LVL variable determines how many snapshots will be kept for each | |
# domain. 4 is the default. | |
# | |
# You must have the qemu-guest-agent installed and enabled on the guest, otherwise | |
# the --quiesce argument must be removed from the snapshot-create command | |
# before the script will function. | |
# | |
# Nicholas Ferguson 2018 MIT License https://gitlab.com/nickopotamus/ | |
DOMAIN=$1 | |
# check if guest is running | |
if [[ $(virsh list --all | grep "$DOMAIN" | awk '{print $3}' | awk 'NR==1{print $1}') == "running" ]]; then | |
echo "Guest running...continuing..." | |
else | |
echo "Guest is not running...stopping..." | |
exit 1 | |
fi | |
# check for correct arguments | |
if [ "$#" -ne 2 ]; then | |
echo "Missing arguments! Provide domain and backup directory." >&2 | |
exit 1 | |
fi | |
# does the backup destination exit | |
if ! [ -e "$2" ]; then | |
echo "$2 not found!" >&2 | |
exit 1 | |
fi | |
# is the backup destination a directory | |
if ! [ -d "$2" ]; then | |
echo "$2 is not a directory!" >&2 | |
exit 1 | |
fi | |
# generate time stamp | |
TIME=`date "+%Y%m%d-%H%M%S"` | |
BACKUP_DEST="$2"/"$1" | |
# create backup dir if it does not exist | |
[ -d "$BACKUP_DEST" ] || mkdir -p "$BACKUP_DEST" | |
# label snapshot with timestamp | |
STATE="$1"_"$TIME" | |
# take care of logging | |
LOG_DIR="$2"/snapshot_logs | |
[ -d "$LOG_DIR" ] || mkdir -p "$LOG_DIR" | |
SNAP_LOG="$LOG_DIR"/"$DOMAIN"_latest.log | |
rm "$SNAP_LOG" | |
touch "$SNAP_LOG" | |
exec 3>&1 4>&2 | |
trap 'exec 2>&4 1>&3' 0 1 2 3 | |
exec 1>"$SNAP_LOG" 2>&1 | |
# name the overlay file | |
OVERLAY="$STATE"_overlay | |
# target is domain name, image is virtual disk file | |
TARGET=`virsh domblklist --details "$1" | grep ^file | awk '{print $3}'` | |
IMAGE=`virsh domblklist --details "$1" | grep ^file | awk '{print $4}'` | |
POOLDIR=`dirname "$IMAGE"` | |
# take the snapshot. will fail without a working qemu-guest-agent | |
virsh snapshot-create-as --domain "$1" "$STATE" \ | |
--diskspec "$TARGET",file="$POOLDIR"/"$OVERLAY".qcow2 \ | |
--disk-only \ | |
--atomic \ | |
--quiesce | |
# perform the backup | |
echo "Copying image to backup location..." | |
cp -a "$IMAGE" "$BACKUP_DEST"/"$STATE" | |
# live block commit | |
echo "Performing live block commit..." | |
virsh blockcommit "$1" "$TARGET" --active --verbose --pivot | |
# remove the overlay file | |
rm "$POOLDIR"/"$OVERLAY".qcow2 | |
# remove the snapshot from domain | |
virsh snapshot-delete $1 --metadata "$STATE" | |
echo 'Current snapshots attached to this guest:' | |
virsh snapshot-list $1 | |
echo '------------------------' | |
echo 'Most recent external snapshots:' | |
ls "$BACKUP_DEST" | |
echo '------------------------' | |
echo 'Current disk image in use:' | |
virsh domblklist $DOMAIN |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment