Creating backups of running VMs in XenServer

With XenServer it is possible to create backups of VMs, even if they are running. The process is as follows:

  • Search for the uuid of the VMs to backup
  • Create a snapshot of each (running) VM
  • Save the snapshot to file
  • Remove the created snapshot

First look for the uuid of the VMs to backup. We don’t want to backup the control domain itself, so we add is-control-domain=false to the vm-list command and we also don’t want backups of snapshots so we add is-a-snapshot=false:

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

Now we create a snapshot of the VMs we want to backup, replacing the uuid one by one with the ones we found with the previous command. Also replace the name of the snapshot if desired:

xe vm-snapshot uuid=d61bfc1a-33b2-5406-7ea5-76e4f7113220 new-name-label=snapshotname

This command has a return value: the uuid of the created snapshot. Then we transform the snapshot into a VM to be able to save it to a file, replacing uuid with the return value of the previous command:

xe template-param-set is-a-template=false ha-always-run=false uuid=b759625c-eab5-4e0f-be5e-a05bcbad869a

In the next step we save the snapshot to a file, replacing uuid with the snapshot uuid and providing a meaningful filename:

xe vm-export vm=b759625c-eab5-4e0f-be5e-a05bcbad869a filename=filename.xva

In the final step we delete the snapshot:

xe vm-uninstall uuid=b759625c-eab5-4e0f-be5e-a05bcbad869a force=true

Python is installed by default on XenServer hosts, so the following script will work out of the box. Download the script from this location to save it to your XenServer host, replacing the .txt extension with .py.

#!/usr/bin/python

import commands, time

def get_backup_vms():
   result = []

   cmd = "xe vm-list is-control-domain=false is-a-snapshot=false"
   output = commands.getoutput(cmd)

   for vm in output.split("nnn"):
      lines = vm.splitlines()
      uuid = lines[0].split(":")[1][1:]
      name = lines[1].split(":")[1][1:]
      result += [(uuid, name)]

   return result

def backup_vm(uuid, filename, timestamp):
   cmd = "xe vm-snapshot uuid=" + uuid + " new-name-label=" + timestamp
   snapshot_uuid = commands.getoutput(cmd)

   cmd = "xe template-param-set is-a-template=false ha-always-run=false uuid=" +
   snapshot_uuid
   commands.getoutput(cmd)

   cmd = "xe vm-export vm=" + snapshot_uuid + " filename=" + filename
   commands.getoutput(cmd)

   cmd = "xe vm-uninstall uuid=" + snapshot_uuid + " force=true"
   commands.getoutput(cmd)

for (uuid, name) in get_backup_vms():
   timestamp = time.strftime("%Y%m%d-%H%M", time.gmtime())
   print timestamp, uuid, name
   filename = """ + timestamp + " " + name + ".xva""
   backup_vm(uuid, filename, timestamp)

40 thoughts on “Creating backups of running VMs in XenServer

  1. Permalink  ⋅ Reply

    paul

    April 20, 2011 at 2:43pm

    This is a great tutorial, thanks for the insights!
    –P

  2. Permalink  ⋅ Reply

    Fabiano

    February 15, 2012 at 3:59pm

    Very nice tutorial thanks, I’m not a Python programmer and I have a question, why are you doing this?:
    filename = filename.replace(” “, ” “)
    filename = filename.replace(“(“, “(“)
    filename = filename.replace(“)”, “)”)

    it looks like you are replacing the characters with identical ones… is there any subtle reason?

    Thanks in advance

    • Permalink  ⋅ Reply

      jansipke

      February 19, 2013 at 3:38pm

      In posting this to WordPress, the backslash characters were removed. This section used to make it possible to have spaces and brackets in filenames. Now it is replaced with better code, thanks to some comments made below.

  3. Permalink  ⋅ Reply

    Renato Mendonca

    May 2, 2012 at 5:55pm

    Thank u, works 100%

  4. Permalink  ⋅ Reply

    chapay

    August 2, 2012 at 2:38pm

    lines = vm.split(“n”)
    this line doesnt work if vm have space in name
    Put this instead
    lines = vm.splitlines()

  5. Permalink  ⋅ Reply

    chapay

    August 2, 2012 at 2:51pm

    and
    filename = timestamp + ” ” + name + “.xva”
    to
    filename = “”” + timestamp + ” ” + name + “.xva” +”””

  6. Permalink  ⋅ Reply

    Stephen

    September 18, 2012 at 12:01pm

    I think that control character are being removed from the quoted script. A lot of the splitting just doesn’t make sense and nor does the regex stuff if this isn’t the case. Good ideas though.

    • Permalink  ⋅ Reply

      jansipke

      February 19, 2013 at 3:42pm

      Fixed. You are right, the control characters were removed by WordPress.

  7. Permalink  ⋅ Reply

    Johan Barelds

    November 21, 2012 at 6:33pm

    What happens if you don’t delete the snapshot in the last step? Would it enable you to only backup a delta (file) since the last backup? I looking for such a possibility since the total size of our VM is quite large for a daily backup.

  8. Permalink  ⋅ Reply

    Leroy

    February 26, 2013 at 4:31pm

    So if I want to export the created backup to another disk or mount the source will be:


    for (uuid, name) in get_backup_vms():
    timestamp = time.strftime("%Y%m%d-%H%M", time.gmtime())
    print timestamp, uuid, name
    filename = ""/mnt/backups/" + timestamp + " " + name + ".xva""
    backup_vm(uuid, filename, timestamp)

  9. Permalink  ⋅ Reply

    TuxedoMan

    March 1, 2013 at 10:19pm

    When I run the python script these are the results I’m getting… why? What do I need to change?

    cmd = “xe template-param-set is-a-template=false ha-always-run=false uuid=” +
    ^
    SyntaxError: invalid syntax

    • Permalink  ⋅ Reply

      TuxedoMan

      March 1, 2013 at 10:19pm

      The ^ is by the + sign

      • Permalink  ⋅ Reply

        RonC

        June 25, 2013 at 8:56pm

        There appears to be a carriage return between the + and snapshot_uuid if you cut and paste the script.
        Delete anything between those two and add just a space between them, that should work.

        Ron

  10. Permalink  ⋅ Reply

    Craig

    August 8, 2013 at 6:40pm

    This is really cool! What is considered the ‘control domain’? Thanks!

  11. Permalink  ⋅ Reply

    Laura Tonino

    September 29, 2013 at 4:00am

    add a “–compress” option to the vm-export which will cause VM exports to be compressed via gzip saving some percent space

  12. Permalink  ⋅ Reply

    Vova

    October 16, 2013 at 12:29pm

    I have VM with disks 50 GB and 100 GB. How I can get minimum size of template.
    Thanks

  13. Permalink  ⋅ Reply

    Chandra

    January 22, 2014 at 6:48am

    Thanks for the real and nice tutorial

    thanks a lot

  14. Permalink  ⋅ Reply

    Chandra

    January 22, 2014 at 12:12pm

    using uuid is some what complicated we can use vm=vmname instead of uuid=xxdxxxxxxxxxxxxxxxxxxxxxxxx in the xe commands as it can we use full

  15. Permalink  ⋅ Reply

    Marcos F. V. Padilha

    March 12, 2014 at 7:37pm

    Hello, I have 3 vms running on my server, when running the script, make 3 times the backup procedure, but 3 times in the same vm, the first found in the vm-list command.
    How can I fix this?

  16. Permalink  ⋅ Reply

    Ismail Shareef

    March 14, 2014 at 7:06pm

    Hi Guys, i am using XenServer 6.2 and i have 2 VMs running on the Host. I wan to backup my VMs in a attached external drive. Can i use the above script and i did not understood why the python script is used for ? Kindly suggest

  17. Permalink  ⋅ Reply

    Thom

    June 10, 2014 at 4:11am

    Where are these xva files supposed to be backing up to?

    • Permalink  ⋅ Reply

      jansipke

      June 10, 2014 at 8:12am

      I’m backing up to an NFS share

  18. Permalink  ⋅ Reply

    giulio

    June 27, 2014 at 11:01am

    Hi,
    Is it possible to show a minimal procedure to restore the backup from this .xva files, preferably using Xencenter?
    Thx

  19. Permalink  ⋅ Reply

    Sergio

    July 24, 2014 at 1:31pm

    Hi. It is possible that the problem is resolved. The “xe vm-export” command breaks the filename into the firts space. To avoid it, its sufficient to put a double quotes at the beginning and the end of the filename:

    filename = “”” + timestamp + ” ” + name + “.xva”””

    or

    filename = “”” + timestamp + ” ” + name + “.xva””

    • Permalink  ⋅ Reply

      Sergio

      July 24, 2014 at 1:32pm

      Oh, I dont understand why not show backslashes.

  20. Permalink  ⋅ Reply

    shahif waqas

    August 26, 2014 at 10:36pm

    when i run this i got this error
    anybody knows about this ???
    Error parameters: INTERNAL_ERROR: [ Unix.Unix_error(56, “write”, “”) ]

  21. Permalink  ⋅ Reply

    jens

    September 5, 2014 at 6:14pm

    thank you 😉

  22. Permalink  ⋅ Reply

    Scr33ni

    November 19, 2014 at 4:03pm

    Is is possible to get the Backupfile into a new Directory with the name of the VM like this:

    filename = “”/mnt/backups/VMname” + timestamp + ” ” + name + “.xva”” ?

    Appreciate every answer

  23. Permalink  ⋅ Reply

    leonardo becerra

    March 21, 2015 at 7:46pm

    asi debe ser

    for (uuid, name) in get_backup_vms():
    timestamp = time.strftime(“%Y%m%d-%H%M”, time.gmtime())
    print timestamp, uuid, name
    filename =”\”/media/backup/” + timestamp + ” ” + name + “.xva\””
    backup_vm(uuid, filename, timestamp)

  24. Permalink  ⋅ Reply

    jfbaulme

    March 27, 2015 at 3:50pm

    Hello,
    I have more one vm in my xenserver and the script return error after the first one :

    20150327-1436 c81eb79e-28c0-fc34-4532-96ef057f493f CentOS 6 (32-bit) (Test video)
    20150327-1437 3314dae3-e226-fdef-df18-5337098a8095 CentOS 7
    sh: -c: line 1: syntax error near unexpected token `(‘
    sh: -c: line 1: `status: Xml.Error(_)’
    sh: -c: line 1: syntax error near unexpected token `(‘
    sh: -c: line 1: `status: Xml.Error(_)’
    sh: -c: line 1: syntax error near unexpected token `(‘
    sh: -c: line 1: `status: Xml.Error(_)’
    20150327-1437 852bd9fd-164b-9290-56df-07bbd00149b0 CentOS6-64
    sh: -c: line 1: syntax error near unexpected token `(‘
    sh: -c: line 1: `status: Xml.Error(_)’…

    Thanks for answer (and apologise for my poor english)

  25. Permalink  ⋅ Reply

    Fabio

    April 26, 2015 at 11:34pm

    what can i do?

    Ps.: My only change –> localtime, Brazil

    Line 33 timestamp = time.strftime(“%Y%m%d-%H%M”, time.localtime())

    [root@xenserver-1 7b396b0f-7d19-d8f9-a839-a5c2be20bd77]# ./backup-vms.py
    20150426-1921 21624a2c-931f-e531-d787-8f6eb9c0ce33 SRV_SAMBA
    20150426-1927 0e3e77a4-8475-b1a0-ddf3-f4e5400d8974 SRV_PROXY
    20150426-1928 9f1b48aa-39ff-848f-29bf-feca6a2381f8 SRV_XENCENTER
    sh: -c: line 3: syntax error near unexpected token `(‘
    sh: -c: line 3: `stderr: Traceback (most recent call last):’
    sh: -c: line 3: syntax error near unexpected token `(‘
    sh: -c: line 3: `stderr: Traceback (most recent call last):’
    sh: -c: line 3: syntax error near unexpected token `(‘
    sh: -c: line 3: `stderr: Traceback (most recent call last):’

  26. Permalink  ⋅ Reply

    Suman Chhetri

    March 23, 2016 at 5:09pm

    Hello Jan, could you help me with this issue? What does this mean and how do I resolve it?

    [root@ent-xen-002 ~]# xe vm-snapshot uuid=7acf1443-8f66-3ee9-4f7f-1d832369f342 new-name-label=ENT-APP-AFRT1_SnapTest1
    Error code: SR_BACKEND_FAILURE_82
    Error parameters: , Failed to snapshot VDI [opterr=Command [‘/usr/sbin/vhd-util’, ‘query’, ‘–debug’, ‘-vsf’, ‘-n’, ‘/dev/VG_XenStorage-24b411f9-ad00-aa26-3b58-a7db7d28740e/VHD-eb4b9461-7f10-4296-a4c5-cded62266259’] failed (5): ],
    [root@ent-xen-002 ~]#

Leave a Reply

Your email will not be published. Name and Email fields are required.