Cloning KVM snapshots
Tags: tutorial, kvm, linux, devops
Published: 2021-04-27 20:22:59

If you ever work with Virtual Machines, you will definitely come across Kernel-based Virtual Machine ([KVM](https://www.linux-kvm.org/page/Main_Page)).

The focus of this article is cloning Snapshots to another VM, this is something I've been trying to do via the Virtual Manager GUI but there is no direct way.

I tried multiple articles but they all resulted in the following error, 
`"Device 'libvirt-2-format' does not have the requested snapshot"`

I finally came over a stackoverflow question that showed how to do it, the key to all of this seems to be
`virt-sysrep`. 
```
What is virt-sysrep?
=> virt-sysprep - Reset, unconfigure or 
customize a virtual machine
so clones can be made
```

Let's get started.

To begin you would need to first generate a XML definition using the following command
```
virt-clone --original $Source_VM_Name  --name $Destination_VM_Name  --file /var/lib/libvirt/images/$Destination_VM_Name.qcow2  --print-xml > $Destination_VM_Name.xml
```
After that you copy the qcow2 image
```
cp --progress  /var/lib/libvirt/images/centos8.qcow2 /var/lib/libvirt/images/centos8-mig.qcow2
```
Now for the most important command, virt-sysrep.
```
virt-sysprep -a $Destination_VM_Name.qcow2
```
In my case virt-sysrep was failing that is because the latest version `file-5.40-2` introduced some bugs due to which virt-sysrep would fail, I had to downgrade using the packages cached
```
pacman  -U /var/cache/pacman/pkg/file-5.39-1-x86_64.pkg.tar.zst
```
We'll use the xml file generated in step file in order to define the destination machine using a virsh command:
`virsh define $Destination_VM_Name.xml`

Once you've done the above its time for some work. Depending on the number of snapshots you have this could get tiring you can use `sed` to automate this.

```
$ virsh snapshot-list $Source_VM_Name --tree
snapshot1
  |
  +- snapshot2
      |
      +- snapshot3
```
*Note*: You need to restore the snapshots starting from the root then go to the leaf.

For each snapshot do this.
```
virsh snapshot-dumpxml $Source_VM_Name $Snapshot_Name --security-info > Snapshot_Name.xml
```
Can be automated like this
```
virsh snapshot-list $Source_VM_Name |sed -e '1,2d' -e '/^$/d'|cut -d' ' -f2| while read -r line; do virsh snapshot-dumpxml $Source_VM_Name --snapshotname $line --security-info > "${line}.xml" ;done
```

We need to change the UUID and domain name in the snapshot xml definition.

Fire up your command line fu and edit the files
```vim Snapshot_Name.xml```

Change(This will come up twice)
```
<domain type='kvm'>
  <name>$Source_VM_Name</name>
  <uuid>$Source_UUID<uuid>

to

<domain type='kvm'>
  <name>$Destination_VM_Name</name>
  <uuid>$Destination_UUID<uuid>
```

Also change the MAC Address field to the destination MAC Address(This will come up twice):
```
<mac address='$Destination_MACADDRESS'/>
```

And change the backing disk file to the destination disk file:
```
<source file='/var/lib/libvirt/images/$Destination_VM_Name.qcow2'/>
```

Time to redefine the snapshot.
```
virsh snapshot-create $Destination_VM_Name Snapshot_Name.xml --redefine
```
That's it you should be able to see the snapshots in the Virtual Machine Gui or via the command line.

Reference: https://stackoverflow.com/questions/43456433/how-to-keepimport-kvm-snapshots-after-virt-clone-a-vm

Thank you for reading!