]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: snapshot: Fix inactive external snapshots when backing chain is present
authorPeter Krempa <pkrempa@redhat.com>
Tue, 12 Nov 2019 16:37:36 +0000 (17:37 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 14 Nov 2019 11:42:09 +0000 (12:42 +0100)
The inactive external snapshot code replaced the file name in the
virStorageSource but did not touch the backing files. This meant that
after an inactive snapshot the backing chain recorded in the inactive
XML (which is used with -blockdev) would be incorrect.

Fix it by adding a new layer if there is an existing chain and replacing
the virStorageSource struct fully when there is no chain.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_driver.c

index c969a3d463a81836ed876aad0cd0b9bd91505fe6..c1b404adfacd8d7c36d5fa31d4995218ac243fa4 100644 (file)
@@ -14613,19 +14613,32 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
 
     /* update disk definitions */
     for (i = 0; i < snapdef->ndisks; i++) {
+        g_autoptr(virStorageSource) newsrc = NULL;
+
         snapdisk = &(snapdef->disks[i]);
         defdisk = vm->def->disks[snapdisk->idx];
 
-        if (snapdisk->snapshot == VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL) {
-            VIR_FREE(defdisk->src->path);
-            defdisk->src->path = g_strdup(snapdisk->src->path);
-            defdisk->src->format = snapdisk->src->format;
+        if (snapdisk->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL)
+            continue;
 
-            if (virDomainSaveConfig(cfg->configDir, driver->caps, vm->def) < 0)
-                goto cleanup;
+        if (!(newsrc = virStorageSourceCopy(snapdisk->src, false)))
+            goto cleanup;
+
+        if (virStorageSourceInitChainElement(newsrc, defdisk->src, false) < 0)
+            goto cleanup;
+
+        if (virStorageSourceHasBacking(defdisk->src)) {
+            newsrc->backingStore = g_steal_pointer(&defdisk->src);
+        } else {
+            virObjectUnref(defdisk->src);
         }
+
+        defdisk->src = g_steal_pointer(&newsrc);
     }
 
+    if (virDomainSaveConfig(cfg->configDir, driver->caps, vm->def) < 0)
+        goto cleanup;
+
     ret = 0;
 
  cleanup: