For many years, I’ve been immersed in the world of Citrix XenServer, managing a fleet of XenServers via XenCenter on a dedicated Windows machine. Traditionally, our approach to VM backup has been a manual process, always necessitating a shutdown of the VM. This practice has understandably led to some frustration among VM owners due to the extended downtime. However, a recent search revealed a more efficient method that allows for backing up VMs without the need to shut them down, thereby eliminating downtime.

Advertisement

Backup Virtual Machine on XenServer

In this tutorial, we’re going to guide you through the process of backing up active VMs step by step. Additionally, we’ll introduce you to a shell script that automates the backup of all VMs or specific ones of your choice. This script can be easily integrated into a crontab to schedule regular backups, making the process seamless and efficient.

Method 1: Manual Backup of Running VM

For those who prefer the command line over using XenCenter, especially Linux enthusiasts, here are the steps to manage your VM backups using terminal commands.

1.1. Identifying VM UUIDs

To begin, locate the UUIDs of all your VMs, which are essential for the following steps. Execute the command below to list all VMs, noting their UUIDs and other details:

xe vm-list is-control-domain=false is-a-snapshot=false

Example output might look like this:

uuid ( RO)           : 8ac95696-94f3-83c1-bc89-8bb2603f832b
     name-label ( RW): test-vm
    power-state ( RO): running

From the output, you can see the UUID for test-vm is 8ac95696-94f3-83c1-bc89-8bb2603f832b, though yours will vary.

1.2. Creating a VM Snapshot

Next, create a snapshot of the VM using its UUID from the previous step. Ensure the UUID is accurate:

xe vm-snapshot uuid=8ac95696-94f3-83c1-bc89-8bb2603f832b new-name-label=testvmsnapshot

This command will return a snapshot UUID. Use this new UUID to set the snapshot as a non-template VM, preparing it for export:

xe template-param-set is-a-template=false ha-always-run=false uuid=b15c0531-88a5-98a4-e484-01bc89131561

1.3. Exporting Snapshot to File

With the snapshot prepared, export it to an .xva file, which can be restored later via command line or XenCenter:

xe vm-export vm=b15c0531-88a5-98a4-e484-01bc89131561 filename=vm-backup.xva

1.4. Deleting the Snapshot

After backing up the VM, you can safely remove the snapshot from the XenServer:

xe vm-uninstall uuid=b15c0531-88a5-98a4-e484-01bc89131561 force=true

Method 2: Using Script for Backup Running VMs

To automate backups for all running VMs on XenServer, consider using a shell script. This approach involves mounting a remote filesystem shared via NFS. While the following script has been effective in my experience, its performance may vary for you. Proceed with caution and understand the risks involved.


#!/bin/bash

# Script for backing up running Virtual Machines in XenServer
# Written by: Mr. Rahul Kumar
# Creation date: Jun 14, 2014
# Last updated: Mar 14, 2024
# Version: 1.3
# More information at: https://tecadmin.net/backup-running-virtual-machine-in-xenserver/

DATE=$(date +%d%b%Y)
XS_HOSTNAME=$(hostname)
UUIDFILE="/tmp/xen-uuids.txt"
NFS_SERVER_IP="192.168.10.100"
MOUNTPOINT="/xenmnt"
FILE_LOCATION_ON_NFS="/backup/citrix/vms"

# Create mount point
mkdir -p "${MOUNTPOINT}"

# Mounting remote NFS share backup drive
if [ ! -d "${MOUNTPOINT}" ]; then
  echo "No mount point found, kindly check"
  exit 1
fi

mount -F nfs "${NFS_SERVER_IP}:${FILE_LOCATION_ON_NFS}" "${MOUNTPOINT}"

BACKUPPATH="${MOUNTPOINT}/${XS_HOSTNAME}/${DATE}"
mkdir -p "${BACKUPPATH}"
if [ ! -d "${BACKUPPATH}" ]; then
  echo "No backup directory found"
  exit 1
fi

# Fetching list UUIDs of all VMs running on XenServer
xe vm-list is-control-domain=false is-a-snapshot=false | grep uuid | cut -d":" -f2 | tr -d ' ' > "${UUIDFILE}"

if [ ! -f "${UUIDFILE}" ]; then
  echo "No UUID list file found"
  exit 1
fi

while IFS= read -r VMUUID; do
  VMNAME=$(xe vm-list uuid="$VMUUID" | grep "name-label" | cut -d":" -f2 | sed 's/^ *//g')
  SNAPUUID=$(xe vm-snapshot uuid="$VMUUID" new-name-label="SNAPSHOT-$VMUUID-$DATE")

  xe template-param-set is-a-template=false ha-always-run=false uuid="${SNAPUUID}"
  xe vm-export vm="${SNAPUUID}" filename="${BACKUPPATH}/${VMNAME}-${DATE}.xva"
  xe vm-uninstall uuid="${SNAPUUID}" force=true

done 

Download this script directly from Github.com

Conclusion

In conclusion, backing up virtual machines without shutting them down is not only possible but also efficient and practical. This guide and the provided script make it easy to regularly backup your VMs, reducing downtime and keeping your data safe. With these tools, you can automate the backup process, ensuring your VMs are always protected with minimal disruption. This method marks a significant improvement in managing VM backups, offering a solution that is both user-friendly and highly effective.

Share.

24 Comments

  1. Protect your XEN VM with Spectrum Protect using SPFS
    =================================================
    Mount your Spectrum Protect filespace anywhere on your XEN server

    # mount -t spfs /backup

    Backup the XEN VM nodes using above example

  2. On Xen 7.2 the fix for the
    [ ! -d ${BACKUPPATH} ] && echo “No backup directory found”; exit 0
    is
    [ ! -d ${BACKUPPATH} ] && (echo “No backup directory found”; exit 0)

  3. I ran into situations where customers did not have enough bandwidth on their storage hardware to complete a backup in a nightly backup. However they still needed some level of protection in the event of malware or admin error. I modified the backup script to only create snapshots of the running VM, and only keep the last 15 days of snapshots. I changed the SNAPSHOT name variable format so that it would not conflict with their existing backup script, so that it could be used in conjunction to the backup script. Just another layer of protection . I installed it into the crontab using * */4 * * * so that it runs every four hours. I hope some will find this useful

    DATE=`date +%F`
    XSNAME=`echo $HOSTNAME`
    MOUNTPOINT=/xenmnt
    UUIDFILE=”/tmp/xen-uuids.txt”
    NFS_SERVER_IP=”10.10.20.230″

    xe vm-list is-control-domain=false is-a-snapshot=false | grep uuid | cut -d”:” -f2 > ${UUIDFILE}

    while read VMUUID
    do
    VMNAME=`xe vm-list uuid=$VMUUID | grep name-label | cut -d”:” -f2 | sed ‘s/^ *//g’`

    SNAPUUID=`xe vm-snapshot uuid=$VMUUID new-name-label=”SNAPSHOT-$DATE”`

    xe template-param-set is-a-template=false ha-always-run=false uuid=${SNAPUUID}

    done ${UUIDFILE}

    while read VMUUID
    do

    xe snapshot-uninstall uuid=$VMUUID –force

    done < ${UUIDFILE}

  4. Please find below sample instructions for restoring using my modified backup script. If anyone would like to help automate this that would be greatly appreciated.

    Contained in the VM backup set you will find several files, an xva file and a VHD image of the hard drives. The XVA file is the definition and or metadata of the vm itself without the VHD or Hard disk.

    Get list of SR
    xe sr-list

    record the sr-uuid you will be using
    example:
    uuid ( RO) : 0c67c214-5041-2d9e-14db-2d2b7e92a8a2
    name-label ( RW): XENSR1
    name-description ( RW): iSCSI SR [10.10.20.221 (iqn.1992-04.com.emc:cx.apm00155221699.b5; LUN 2: APM00155221699: 10240 GB (DGC))]
    host ( RO):
    type ( RO): lvmoiscsi
    content-type ( RO):

    Import Metadata of VM
    xe vm-import preservce=false filename=hylafax-12Mar2017.xva –force sr-uuid=0c67c214-5041-2d9e-14db-2d2b7e92a8a2

    Get uuid of imported vm

    [root@xenbl460-1 hylafax]# xe vm-list name-label=hylafax
    uuid ( RO) : b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    name-label ( RW): hylafax
    power-state ( RO): haltedGet list of snapshots of MV

    Get list of snapshot of vm

    [root@xenbl460-1 hylafax]# xe snapshot-list snapshot-of=b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    uuid ( RO) : 002ad76c-c281-5ef8-e1dd-afa637c63822
    name-label ( RW): SNAPSHOT-6edb308d-4cb7-e16e-f565-fbe95609ab79-12Mar2017
    name-description ( RW):

    Destroy Snapshot of VM
    [root@xenbl460-1 hylafax]# xe snapshot-destroy uuid=002ad76c-c281-5ef8-e1dd-afa637c63822

    get list of VBD for VM
    [root@xenbl460-1 hylafax]# xe vbd-list vm-uuid=b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    uuid ( RO) : e8c9b02a-f73d-907b-b717-ed19b6d5e751
    vm-uuid ( RO): b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    vm-name-label ( RO): hylafax
    vdi-uuid ( RO): a2eea760-6131-4afa-ac7e-87faec69a818
    empty ( RO): false
    device ( RO):

    uuid ( RO) : 893b1267-d3bf-6520-2416-3e7bbadd61d9
    vm-uuid ( RO): b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    vm-name-label ( RO): hylafax
    vdi-uuid ( RO): 53a07b39-eac0-4e72-b0c0-69702474bd4d
    empty ( RO): false
    device ( RO):

    uuid ( RO) : aae311d1-847a-b67c-056c-fd367136889e
    vm-uuid ( RO): b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    vm-name-label ( RO): hylafax
    vdi-uuid ( RO):
    empty ( RO): true
    device ( RO):

    Get VDI info for each VBD
    xe vdi-list uuid=53a07b39-eac0-4e72-b0c0-69702474bd4d
    xe vdi-list uuid=a2eea760-6131-4afa-ac7e-87faec69a818

    Pay attention to the size of the output

    [root@xenbl460-1 hylafax]# xe vdi-list uuid=a2eea760-6131-4afa-ac7e-87faec69a818
    uuid ( RO) : a2eea760-6131-4afa-ac7e-87faec69a818
    name-label ( RW): hylafax_1
    name-description ( RW): hylafax_1
    sr-uuid ( RO): 0c67c214-5041-2d9e-14db-2d2b7e92a8a2
    virtual-size ( RO): 17179869184
    sharable ( RO): false
    read-only ( RO): false

    Import VDI
    Now you will import each vhd file that matches the size of the vdi. if your unsure of the size use the following command as an example

    Get VHD file information
    [root@xenbl460-1 hylafax]# vhd-util scan -f -p -m *.vhd
    vhd=hylafax_0-d9d6c6ff-f862-44ca-afc9-48b29c4b4c31.vhd capacity=5368709120 size=365006336 hidden=0 parent=none
    vhd=hylafax_1-d487610b-12dc-4d9a-9981-9a97c33fa74b.vhd capacity=17179869184 size=12214732800 hidden=0 parent=none

    Manually match the VHD to the VDI based on size or name label of the filename and or VDI
    example: xe vdi-import format=VHD filename=hylafax_0-d9d6c6ff-f862-44ca-afc9-48b29c4b4c31.vhd uuid=53a07b39-eac0-4e72-b0c0-69702474bd4d

    Do this for each VDI / VHD

    Start VM
    xe vm-start uuid=b2fb074f-b024-6d1d-364c-8ac2c73c90b8
    or
    xe vm-start name-label=hylafax

    Repeat this process for each VM

  5. Hi,

    thanks for the script, but I got some problems with it so here are some questions:

    On what Xenserver Version this script is running?

    I tried that script on Xenserver 7.1 and there are a few serious problems:

    your script says ‘mount -F nfs’ -> “mount” on my Xenserver says “-F = fork off for each device” Wrong paramter???
    your script says ‘[ ! -d ${MOUNTPOINT} ] && echo “No mount point found, kindly check”; exit 0’ maybe I am wrong but doesnt this ALWAYS mean that your scripts ends at this line? “;” just seperates two commands?! What system are you using? Greetings

    • Hi,

      The script will only exist if mount point directory is not created already.
      You can also use the script given by REVERSEARP in the comments section box.
      This is a simple bash script. So if required you can modify it as per your requirements.

      • Hi Rahul,

        thanks for your quick response.

        I will try the script of REVERSEARP, (he uses mount -t nfs).
        Ofcourse exiting the script when the Mount point directory is not created makes sense. I see ur goal here. But please have a closer look to this line:

        ‘[ ! -d ${MOUNTPOINT} ] && echo “No mount point found, kindly check”; exit 0’

        I did some tests:

        [root@xenhost ~]# false && echo “ok” —> nothing happens
        [root@xenhost ~]# true && echo “ok” —> shell outputs “ok” (makes sense)
        [root@xenhost ~]# false && echo “ok”; exit 0 –> Shell closes
        [root@xenhost ~]# true && echo “ok”; exit 0 –> Shell closes

        To my mind this script cant work because you always exit the script no matter the mount point directory exist or not… Sorry, just wanna verify this line. I am just wondering why this script works for you?? Where is my mistake …

        • I had the same problem. I ended up changing this line to :

          if [ ! -d “$MOUNTPOINT” ] ; then echo “Mount point ${MOUNTPOINT} not found, kindly check”; exit 0; fi

          A little wordier, but it works on my system. I changed the other ‘if exists’ type statements as well to explicit if’s and it all works as expected.

  6. thank you for sharing your script,

    I am trying to use it

    #########################################################
    #Ubuntu-server-1 Backup
    TDY=`date +%Y%m%d%H-%M`
    SNAPUUID=`xe vm-snapshot uuid=$384b41b6-eaac-c2d9-48e5-c169c2be5968 new-name-label=Ubuntu-server-1`
    xe template-param-set is-a-template=false ha-always-run=false uuid=${SNAPUUID}
    xe vm-export vm=${SNAPUUID} filename=”Ubuntu-server-1-$TDY”.xva
    xe vm-uninstall uuid=${SNAPUUID} force=true
    #########################################################

    restored backup

    xe vm-import filename=/media/xen-vm-backup/Ubuntu-server-1-11-9-2016.xva
    #########################################################

    The problem is when import the VM, It works fine but it does not have all the files.

    can you help me please

  7. I saw this, and tried it, and I like it, thank you for sharing its very useful. Only problem was that in my environment is that it took 16.3 hours to complete . So I got to thinking, there needs to be a faster way to do this. Forgive the syntax and formatting , I am not a bash programmer by any standpoint. Basically this modification takes a snapshot, grabs the metadata, of the actual vm and does a vdi-export on the snapshot. then uninstalls the snapshot. In my environment it took 6 hours to run. (4.7TB) I am dumping my VM’s to a ZFS based san , I highly recommend some sort of compressed FS ( I like zfs), as the vhd’s are large however they are highly compressible. I am going to test the dedupe ratio on an EMC Datadomain to see what type of ratios I get, as I would like to keep 3 months of weekly snapshots at a minimum on site and replicated to our DR.

    To restore you will need to do a vm-import on the metadata, then import the individual vhd’s . Which means creating new vdi and then doing the vdi-import to that vdi. If you don’t know the size of the vdi you will need to query the vhd using vhd-util.

    #!/bin/bash
    #
    # Written By: Mr Rahul Kumar
    # Created date: Jun 14, 2014
    # Last Updated: Jan 22, 2016
    # Version: 1.2
    # Visit: http://tecadmin.net
    #

    DATE=`date +%d%b%Y`
    XSNAME=`echo $HOSTNAME`
    MOUNTPOINT=/xenmnt
    UUIDFILE=”/tmp/xen-uuids.txt”
    NFS_SERVER_IP=”10.10.20.212″

    ### Create mount point

    mkdir -p ${MOUNTPOINT}

    ### Mounting remote nfs share backup drive

    # [ ! -d ${MOUNTPOINT} ] && echo “No mount point found, kindly check”; exit 0

    mount -t nfs ${NFS_SERVER_IP}:/mnt/pool1/vm_backups ${MOUNTPOINT} -o async,rsize=32768,wsize=32768,soft

    BACKUPPATH=${MOUNTPOINT}/${XSNAME}/${DATE}
    mkdir -p ${BACKUPPATH}

    # [ ! -d ${BACKUPPATH} ] && echo “No backup directory found”; exit 0

    # Fetching list UUIDs of all VMs running on XenServer
    xe vm-list is-control-domain=false is-a-snapshot=false | grep uuid | cut -d”:” -f2 > ${UUIDFILE}

    # [ ! -f ${UUIDFILE} ] && echo “No UUID list file found”; exit 0

    while read VMUUID
    do
    VMNAME=`xe vm-list uuid=$VMUUID | grep name-label | cut -d”:” -f2 | sed ‘s/^ *//g’`

    SNAPUUID=`xe vm-snapshot uuid=$VMUUID new-name-label=”SNAPSHOT-$VMUUID-$DATE”`

    xe template-param-set is-a-template=false ha-always-run=false uuid=${SNAPUUID}
    NEWPATH=${BACKUPPATH}/${VMNAME}
    mkdir “${NEWPATH}”
    echo “${NEWPATH}/$VMNAME-$DATE.xva”
    xe vm-export metadata=true vm=${VMUUID} filename=”${NEWPATH}/${VMNAME}-${DATE}.xva”

    #######GET VBD######
    for VBDUUID in $(xe vbd-list vm-uuid=${SNAPUUID} empty=false –minimal | sed “s/,/ /g” );

    do
    VDIUUID=$( xe vdi-list vbd-uuids=$VBDUUID –minimal)
    VDINAME=$( xe vdi-param-get param-name=name-label uuid=$VDIUUID )
    xe vdi-export progress=true uuid=$VDIUUID format=vhd filename=$NEWPATH/$VDINAME-$VDIUUID.vhd

    done

    xe vm-uninstall uuid=${SNAPUUID} force=true

    done < ${UUIDFILE}

    umount ${MOUNTPOINT}

  8. I would like to know if the snapshots would also backup the disks that are attached to the VM. I have few VM that have 4TB and 2TB disks attached for file storage and those don’t need to be on the snapshots. If the attached disks are also on the snapshots, is there a way to ignore them? Thanks for the great tutorial.

      • This is kinda like the blind leading the deaf, but since nobody else answered:

        The line

        #######GET VBD######
        for VBDUUID in $(xe vbd-list vm-uuid=${SNAPUUID} empty=false –minimal | sed “s/,/ /g” );

        is what controls which volumes are backed up. You can run it “by hand” to see what exactly is include, for example:

        # get a list of the VM UUIDS
        xe vm-list

        # Show the volues attached to the VM you want to look at
        xe vbd-list uuid=(enter the UUID you got from the previous command)

        So, yes it can be done, but would take some hacking of the script – particularly to have it deal with different situations for different VM’s

    • So after some testing – the script will backup any size hard drive or VHD that it has access to. However upon doing a restore of that VHD it will fail. It appears that the VHD has to be less than 2000G. The way I overcame this limitation was to use smaller VHD’s and use LVM in linux or in windows spanned disks. If you absolutely need to use a disk that large, create a new SR via nfs and move the vid
      s that SR (via mv or cp from cli). them rename the VHD with a valid GUID keeping the VHD extension. Then you can do a SRscan and then attach the disk to the VM. It is literally the only way to deal with restoring VHD’s of that size

  9. I have to question
    1 you have,t specify the path for the backup file
    2 if i want the backup over network then what should be the procedure
    Thanks

  10. Hi everyone

    i am just confuse because where is the location of backup file.

    Secondly if i want to do the backup over the network then what will be the procedure for that.
    If possible please give the reply on my mail

    Thanks
    ihsan

  11. The information I search for – thanks.

    But on a XenServer 6.2.0 you don’t need to create a file with the uuids. It can done with a for-loop.
    Here a little loop to list the uuids and name-labels:
    for vmuuid in $(xe vm-list is-control-domain=false is-a-snapshot=false is-a-template=false params=uuid –minimal | tr ‘,’ ‘ ‘)
    do echo “UUID: $vmuuid – Name-Label: $(xe vm-list uuid=$vmuuid params=name-label –minimal)”
    done

  12. Luiz Henrique Prudencio Camacho on

    ———————————————————————————-
    1º – LISTAR VMS para encontra a identificação ( UUID ) da maquina que será exportada
    COMANDO: xe vm-list is-control-domain=false
    ———————————————————————————-
    ———————————————————————————-
    ##### CRIAR SNAPSHOT DA MAQINA QUE DESEJA EXPORTAR
    COMANDO: xe vm-snapshot uuid= AQUI VOCE COLOCA O UUID DA MAQUINA QUE SERA EXPORTADA new-name-label=bkp_vm_xp

    ———————————————————————————-
    ———————————————————————————-
    ##### APOS CRIAR O SNAPSHOT ESSE COMANDO TRANSFORMA O SNAPSHOT EM vm
    COMANDO: xe template-param-set is-a-template=false ha-always-run=false uuid=AQUI VOCE COLOCA O UUID DO SNAPSHOT
    ———————————————————————————-
    ———————————————————————————-
    ##### CRIAR PASTA PARA BACKUP DA VM
    COMANDO: mkdir /mnt/pasta_bkp
    ———————————————————————————-
    ———————————————————————————-
    ##### COLOQUE AQUI OS DADOS DA PASTA COMPARTILHADA EM REDE
    COMANDO: mount -t cifs “//10.0.0.45/bkp-vm/BKP-SCRIPT/windows-xp” -o username=”dominiousuario”,password=”senha” “/mnt/pasta_bkp”
    ———————————————————————————-
    ———————————————————————————-
    ##### ESSE COMANDO COPIA A VM PARA SUA PASTA NA REDE
    COMANDO: xe vm-export vm=AQUI VOCE COLOCA O UUID DO SNAPSHOT filename=/mnt/pasta_bkp/win_xp_bkp.xva
    ———————————————————————————-
    ———————————————————————————-
    ##### ESSE COMANDO Remover VM Snapeshot
    COMANDO: xe vm-uninstall uuid=b759625c-eab5-4e0f-be5e-a05bcbad869a force=true
    ———————————————————————————-

Exit mobile version