xen_backup.sh

See also XenServer Backup

#!/bin/bash
# xen_backup.sh by Gene Cooper (gcooper at sonoracomm.com)
#
# This script provides a fairly quick and clean method for backing up an OSS 
# Xen server.  
# 
# I searched for a tool to do this, but I couldn't find one...hence, this script.
#
# I use this script as a pre-exec script for my regular backup system.  Unfortunately,
# there is downtime during the backup and amount of it will depend on the speed of your
# hardware.  If you need better uptime than this script provides, you should look 
# into LVM snapshots.
#
# The logic of this script is simple and it is designed to minimize downtime.  
# It will determine the running Xen domains and then, one at a time, it will suspend each
# domain, save (checkpoint) the running state, create a compressed copy of the disk image
# file then resume the domain.  Afterward, your primary backup can be performed. 
#
# IMPORTANT NOTE: This version of the script depends on sufficient free disk space to save
# the gzip'd disk image files and the checkpoint (memory state) files!  

# The checkpoint files appear to be memory snapshots of the running domains and are the
# size of the allocated memory.
#
# Your main backup should probably back up the /etc/xen directory, the compressed Xen disk
# image files as well as the checkpoint files ($dest as set below). 
#
# Restoring a domain from backup would mainly involve restoring the xen config files 
# from /etc/xen, restoring/uncompressing the disk image and checkpoint files to their
# original locations then running a command like: 
#
# xm restore /path/to/checkpointfile
#

# Log file
log=/var/log/xen/xen_backup.log

# Temp directory for checkpoint files
dest=/vm/xen/backup

# Xen configuration files location
xenconfig=/etc/xen

# Xen domains (VMs) to be backed up
#alldomains=( dom1 dom2 dom3 dom4 ) 
alldomains=( ISPConfig appserv mgmt ) 

# Delete old backups - Assume they were backed up to tape or disk and are no longer needed
# This may help keep your backups smaller by avoiding duplicate backups.
delold=yes

############## end of variables ################

# Create temp dir if not exist
if [ ! -d ${dest} ]
then
  echo "Temp directory for checkpoint files doesn't exist - creating..." >> $log 
  echo "" >> $log
 /bin/mkdir -p ${dest}
fi

# Subroutine Definitions

delete-old()
# Here we delete all old backups, if that is desirable.
# This may help keep our tape backups smaller.
{   if [ "$delold" = "yes" ]; then
       rm -f $dest/*
    fi
}

pre-backup()
{
 echo "" >> $log
 /bin/date >> $log
 echo "Running pre-backup on running VMs (checkpointing)..." >> $log
 if [ -f $dest/$runningdomain.chk ]; then 
    echo "Deleting pre-existing checkpoint file $dest/$runningdomain.chk..." >> $log
    rm -f $dest/$runningdomain.chk
 fi
 echo "Checkpointing the $runningdomain VM to $dest/$runningdomain.chk..." >> $log
 /usr/sbin/xm save $domain $dest/$runningdomain.chk >> $log
 /bin/date >> $log
}

compress-image()
{
 echo "" >> $log
 /bin/date >> $log
    # Now we create a compressed copy of the VM (.img file) ready to be backed up
    # by the primary backup system.  I am not sure the next line will work in all cases
    # to extract the .img filename from the xen config file, but it works on my domains.
    imgfile=`cat $xenconfig/$domain |grep disk|cut -f3 -d ":"|cut -f1 -d ","`
    echo "Compressing the $domain disk image file to $dest/$domain.img.gz..." >> $log
    gzip -c $imgfile > $dest/$domain.img.gz
 /bin/date >> $log
}

post-backup()
{
 echo "" >> $log
 /bin/date >> $log
 echo "Restoring the $domain domain to on-line status..." >> $log
 /usr/sbin/xm restore $dest/$domain.chk >> $log 
 /bin/date >> $log
}

# Processing begins
delete-old

# Here we checkpoint only the currently running domains.
for runningdomain in `xm list|grep -v Name|grep -v Domain-0|cut -f1 -d" "`; do
   pre-backup
   post-backup
done

# Here we back up all specified domains, not just running VMs.
for domain in ${alldomains[@]}; do
   compress-image
done

# Just closing out the log...
echo "" >> $log
echo "Backup Completed" >> $log
/bin/date >> $log

exit