Migrate / Restore VMs with XCP-ng
I recently had hardware issues on one of my XCP‑ng hosts. Several VMs were lost and I had to rebuild the host from scratch. To rescue the remaining VMs I exported them to a new host I built recently.
Because the host is reachable only remotely and is experiencing hardware failures, migration via the Xen Orchestra (XOA) integrated tool is not straightforward.
Network difficulty – I managed to connect my local XOA instance to the remote host, but I cannot initiate a migration because the remote host lacks a network route to my local XCP‑ng host.
Hardware difficulties – The host suffers from disk or back‑plane/controller problems, which complicates VM export; the CLI tools fail for several VMs.
Below are three methods I used to back up all VMs.
After installing XOA (Xen Orchestra), the simplest way to export a VM for migration is to use the xe vm-export command.
xe vm-list | grep -C2 myvirtualmachine
Example output (showing the UUID you need):
uuid (RO) : b63b8285-94b5-3d26-9fe2-4be3ab046cd9
name-label (RW) : myvirtualmachine-1
power-state (RO) : halted
Export the VM – Using that UUID, export the VM to an XVA file:
xe vm-export vm=b63b8285-94b5-3d26-9fe2-4be3ab046cd9 \
filename=/run/sr-mount/a8f6df31-434f-d5e9-4163-99975b1df8ad/myvirtualmachine-1.xva
Note: An XVA is essentially a tarball containing the VHD (virtual hard disk) and an XML descriptor of the VM.
Transfer the XVA – After the SCP transfer finishes (it can take many hours), import the XVA on the destination host:
xe vm-import filename=/run/sr-mount/SMB/Data/Backup/VirtualMachines/XCP-NG-NG/myvirtualmachine-1.xva \
sr-uuid=54b7eaaa-b873-410a-cef6-6be9999edfdd
Although XOA does not provide a UI import function for XVA, you can monitor the import job in XOA after invoking vm-import from the CLI.
When network isolation makes XOA migration impossible and xe vm-export fails with I/O errors, I booted a SystemRescueCD live environment and created an image of the virtual disk for later import.
Boot the failing VM with SystemRescueCD and mount a network share where the image will be saved. In my case I mounted the XCP‑ng host via sshfs:
sshfs backup@172.16.16.16:/run/sr-mount/a7f6df31-437e-dr88-4132-8af9999df8ad /mnt/sgxcp
Convert the raw block device to a VHD using qemu-img:
qemu-img convert -p -f raw -O vpc /dev/xvdb /mnt/sgxcp/mydifficultvm.vhd
Options:
Create a VDI on the destination host (the VDI acts as a wrapper that XCP‑ng can attach to a VM). First retrieve the UUID of the storage repository (SR) where the VDI will reside:
xe sr-list
Sample output:
uuid (RO) : 54b98dd-b785-410a-cef6-6b999dfaa
name-label (RW) : SR1
name-description (RW): local storage on NVME1
host (RO) : xcp
type (RO) : ext
content-type (RO) : user
Then create the VDI (choose a size equal to or larger than the source VHD):
xe vdi-create name-label=myvirtualmachine-1-xvda \
sr-uuid=54b98dd-b785-410a-cef6-6b999dfaa \
virtual-size=255GiB
The command returns a VDI UUID; keep note of it. If you missed it, retrieve it with:
xe vdi-list | grep -C1 myvirtualmachine
Import the VHD into the newly created VDI:
xe vdi-import filename=mydifficultvm.vhd \
format=vhd \
uuid=e0ae1995-4c6b-4a12-99a0-b70d3c9995ab \
progress=true
Create a VM that boots from the VDI
Congratulations! You can now start the VM.
Another option I tried for a single VM when the previous methods failed was to copy the raw VHD file directly:
This method worked intermittently; some copies still produced read errors.
For one VM, none of the above worked. I attempted a guest‑side backup using Windows’ built‑in Backup utility, planning to:
Unfortunately this method also failed.
The final approach involved manually dumping databases and files, then rebuilding the VM on the new host. I’m currently at this stage; it’s unrelated to XCP‑ng specifics, so I won’t elaborate further.
At this point only two VMs remain to be rebuilt.
Repeating these procedures has allowed me to recover the majority of my workloads despite severe hardware failure and network isolation. The combination of:
provides a flexible toolbox for any XCP‑ng disaster‑recovery scenario.
Doing and re‑doing is still working…