Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 4ae49a0148
Fetching contributors…

Cannot retrieve contributors at this time

executable file 272 lines (238 sloc) 7.44 kb
#!/bin/bash
# Script which backups metadata into a VDI
# Citrix Systems Inc, 2008
trap "cleanup" TERM INT
if [ ! -e @INVENTORY@ ]; then
echo Must run on a XenServer host.
exit 1
fi
. @INVENTORY@
XE="@BINDIR@/xe"
master_uuid=$(${XE} pool-list params=master --minimal)
if [ $? -gt 0 ]; then
echo Error: unable to determine master host uuid
exit 1
fi
if [ "${master_uuid}" != "${INSTALLATION_UUID}" ]; then
echo Error: must run this script on the master host in the resource pool.
exit 1
fi
history_kept=25
metadata_version=1
debug=/bin/true
function usage {
echo "Usage: $0 [-h] [-i] [-u <SR UUID>]"
echo
echo " -h: Display this help message"
echo " -c: Create a backup VDI if one cannot be found (default: false)"
echo " -i: Initialize the backup VDI before performing the backup"
echo " -u: UUID of the SR you wish to backup to"
echo " -d: Dont perform a backup, but leave the disk mounted in a shell"
echo " -k: Number of older backups to preserve (default: ${history_kept})"
echo " -n: Just try to find a backup VDI and stop the script after that"
echo " -v: Verbose output"
echo
echo
echo "Use the -d option to examine the backup VDI, and restore it if necessary."
echo "It is a good idea to copy the backup onto the control domain before"
echo "restoring it via the xe pool-database-restore CLI command."
exit 1
}
function test_sr {
sr_uuid_found=$(${XE} sr-list uuid="$1" --minimal)
if [ "${sr_uuid_found}" != "$1" ]; then
echo Invalid SR UUID specified: $1
usage
fi
}
leave_mounted=0
init_fs=0
create_vdi=0
just_find_vdi=0
fs_uninitialised=0
while getopts "hvink:u:dc" opt ; do
case $opt in
h) usage ;;
c) create_vdi=1 ; fs_uninitialised=1 ;;
i) init_fs=1 ; fs_uninitialised=1 ;;
k) history_kept=${OPTARG} ;;
u) sr_uuid=${OPTARG} ;;
d) leave_mounted=1 ;;
n) just_find_vdi=1 ;;
v) debug="" ;;
*) echo "Invalid option"; usage ;;
esac
done
# get pool uuid
IFS=,
pool_uuid=$(${XE} pool-list params=uuid --minimal)
if [ -z "${pool_uuid}" ]; then
echo Unable to determine pool UUID.
exit 1
fi
# determine if the SR UUID is vaid
if [ -z "${sr_uuid}" ]; then
# use the default-SR from the pool
sr_uuid=$(${XE} pool-param-get uuid=${pool_uuid} param-name=default-SR)
fi
test_sr "${sr_uuid}"
sr_name=$(${XE} sr-param-get uuid=${sr_uuid} param-name=name-label)
# see if a backup VDI already exists on the selected SR
vdi_uuid=$(${XE} vdi-list other-config:ctxs-pool-backup=true sr-uuid=${sr_uuid} params=uuid --minimal)
mnt=
function cleanup {
trap "" TERM INT
cd /
if [ ! -z "${mnt}" ]; then
umount ${mnt} >/dev/null 2>&1
rmdir ${mnt}
fi
if [ ! -z "${vbd_uuid}" ]; then
${debug} echo -n "Unplugging VBD: "
${XE} vbd-unplug uuid=${vbd_uuid} timeout=20
# poll for the device to go away if we know its name
if [ "${device}" != "" ]; then
device_gone=0
for ((i=0; i<10; i++)); do
${debug} echo -n "."
if [ ! -b ${device} ]; then
${debug} echo " done"
device_gone=1
break
fi
sleep 1
done
if [ ${device_gone} -eq 0 ]; then
${debug} echo " failed"
echo Please destroy VBD ${vbd_uuid} manually.
else
${XE} vbd-destroy uuid=${vbd_uuid}
fi
fi
fi
if [ ${fs_uninitialised} -eq 1 -a -n "${vdi_uuid}" ] ; then
${XE} vdi-destroy uuid=${vdi_uuid}
fi
}
echo Using SR: ${sr_name}
if [ -z "${vdi_uuid}" ]; then
if [ "${create_vdi}" -gt 0 ]; then
echo -n "Creating new backup VDI: "
vdi_uuid=$(${XE} vdi-create virtual-size=250MiB sr-uuid=${sr_uuid} type=user name-label="Pool Metadata Backup")
init_fs=1
if [ $? -ne 0 ]; then
echo failed
exit 1
fi
else
echo "Backup VDI not found, aborting. You can initialise one using the '-c' flag."
exit 3
fi
echo ${vdi_uuid}
${XE} vdi-param-set uuid=${vdi_uuid} other-config:ctxs-pool-backup=true
else
${debug} echo "Using existing backup VDI: ${vdi_uuid}"
fs_uninitialised=0
fi
if [ ${just_find_vdi} -gt 0 ]; then
exit 0
fi
${debug} echo -n "Creating VBD: "
vbd_uuid=$(${XE} vbd-create vm-uuid=${CONTROL_DOMAIN_UUID} vdi-uuid=${vdi_uuid} device=autodetect)
${debug} echo ${vbd_uuid}
if [ $? -ne 0 -o -z "${vbd_uuid}" ]; then
echo error creating VBD
cleanup
exit 1
fi
${debug} echo -n "Plugging VBD: "
${XE} vbd-plug uuid=${vbd_uuid}
device=/dev/$(${XE} vbd-param-get uuid=${vbd_uuid} param-name=device)
if [ ! -b ${device} ]; then
${debug} echo ${device}: not a block special
cleanup
exit 1
fi
${debug} echo ${device}
if [ $init_fs -eq 1 ]; then
${debug} echo -n "Creating filesystem: "
mkfs.ext3 -j -F ${device} > /dev/null 2>&1
${debug} echo "done"
fs_uninitialised=0
fi
${debug} echo -n "Mounting filesystem: "
mnt=/var/run/pool-backup-${vdi_uuid}
mkdir -p ${mnt}
/sbin/fsck -a ${device} >/dev/null 2>&1
if [ $? -ne 0 ]; then
${debug} fsck failed. Please correct manually
cleanup
exit 1
fi
mount ${device} ${mnt} > /dev/null 2>&1
if [ $? -ne 0 ]; then
${debug} echo failed
cleanup
exit 1
fi
${debug} echo ${mnt}
if [ ${leave_mounted} -eq 0 ]; then
lrconf=${mnt}/conf/${vdi_uuid}
if [ ! -f ${lrconf} ]; then
${debug} echo -n "Initialising rotation: "
mkdir -p ${mnt}/conf/
echo "${mnt}/${pool_uuid}.db {" >> ${lrconf}
echo " rotate ${history_kept}" >> ${lrconf}
echo " missingok" >> ${lrconf}
echo "}" >> ${lrconf}
echo done
echo ${metadata_version} >> ${mnt}/.ctxs-metadata-backup
fi
# invoke logrotate to rotate over old pool db backups
echo -n "Rotating old backups: "
logrotate -f ${lrconf}
num_found=$(find ${mnt} -name \*.db\.* | wc -l)
echo found ${num_found}
# perform the pool database dump
echo -n "Backing up pool database: "
${XE} pool-dump-database file-name=${mnt}/${pool_uuid}.db
echo done
# backup the VM metadata for each VM in the pool into a dated directory
datetime=$(date +%F-%H-%M-%S)
metadir=${mnt}/metadata/${datetime}
mkdir -p ${metadir}
echo -n "Cleaning old VM metadata: "
IFS=" "
todelete=$(cd ${mnt}/metadata && ls -1 |sort -n | head -n -${history_kept} | xargs echo)
for dir in ${todelete}; do
rm -rf ${mnt}/metadata/${dir}
done
echo done
IFS=","
echo -n "Backing up SR metadata: "
mkdir -p ${metadir}
"@LIBEXECDIR@/backup-sr-metadata.py" -f ${metadir}/SRMETA.xml
echo "done"
echo -n "Backing up VM metadata: "
${debug} echo ""
mkdir -p ${metadir}/all
for vmuuid in $(${XE} vm-list params=uuid is-control-domain=false --minimal); do
${debug} echo -n .
${XE} vm-export --metadata uuid=${vmuuid} filename=${metadir}/all/${vmuuid}.vmmeta >/dev/null 2>&1
done
echo "done"
echo -n "Backing up Template metadata: "
${debug} echo ""
template_uuids=$("@LIBEXECDIR@/print-custom-templates")
if [ $? -eq 0 ]; then
for tmpl_uuid in ${template_uuids}; do
${XE} template-export --metadata template-uuid=${tmpl_uuid} filename=${metadir}/all/${tmpl_uuid}.vmmeta >/dev/null 2>&1
done
fi
echo "done"
"@LIBEXECDIR@/link-vms-by-sr.py" -d ${metadir}
else
cd ${mnt}
env PS1="Mounted backup VDI on: ${mnt}\nPress ^D to exit shell and safely detach it.\n\n[\u@\h \W]\$ " bash
fi
cleanup
Jump to Line
Something went wrong with that request. Please try again.