[libvirt] [RFC PATCH 5/5] qemu: snapshot: Improve approach to deal with snapshot metadata

Peter Krempa pkrempa at redhat.com
Thu Jun 12 15:02:19 UTC 2014


Until now we were changing information about the disk source via
multiple steps of copying data. Now that we changed to a pointer to
store the disk source we might use it to change the approach to track
the data.

Additionally this will allow proper tracking of the backing chain.
---
 src/qemu/qemu_driver.c | 108 +++++++++----------------------------------------
 1 file changed, 19 insertions(+), 89 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e147d28..92abdc9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12842,14 +12842,10 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
                                          enum qemuDomainAsyncJob asyncJob)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virStorageSourcePtr tmp;
     char *device = NULL;
     char *source = NULL;
-    char *newsource = NULL;
-    virStorageNetHostDefPtr newhosts = NULL;
-    virStorageNetHostDefPtr persistHosts = NULL;
-    int format = snap->src->format;
     const char *formatStr = NULL;
-    char *persistSource = NULL;
     int ret = -1;
     int fd = -1;
     bool need_unlink = false;
@@ -12863,26 +12859,12 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     if (virAsprintf(&device, "drive-%s", disk->info.alias) < 0)
         goto cleanup;

-    /* XXX Here, we know we are about to alter disk->src->backingStore if
-     * successful, so we nuke the existing chain so that future commands will
-     * recompute it.  Better would be storing the chain ourselves rather than
-     * reprobing, but this requires modifying domain_conf and our XML to fully
-     * track the chain across libvirtd restarts.  */
-    virStorageSourceClearBackingStore(disk->src);
-
     if (virStorageFileInit(snap->src) < 0)
         goto cleanup;

     if (qemuGetDriveSourceString(snap->src, NULL, &source) < 0)
         goto cleanup;

-    if (VIR_STRDUP(newsource, snap->src->path) < 0)
-        goto cleanup;
-
-    if (persistDisk &&
-        VIR_STRDUP(persistSource, snap->src->path) < 0)
-        goto cleanup;
-
     switch ((virStorageType)snap->src->type) {
     case VIR_STORAGE_TYPE_BLOCK:
         reuse = true;
@@ -12910,15 +12892,6 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     case VIR_STORAGE_TYPE_NETWORK:
         switch (snap->src->protocol) {
         case VIR_STORAGE_NET_PROTOCOL_GLUSTER:
-            if (!(newhosts = virStorageNetHostDefCopy(snap->src->nhosts,
-                                                      snap->src->hosts)))
-                goto cleanup;
-
-            if (persistDisk &&
-                !(persistHosts = virStorageNetHostDefCopy(snap->src->nhosts,
-                                                          snap->src->hosts)))
-                goto cleanup;
-
             break;

         default:
@@ -12969,33 +12942,18 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     /* Update vm in place to match changes.  */
     need_unlink = false;

-    VIR_FREE(disk->src->path);
-    virStorageNetHostDefFree(disk->src->nhosts, disk->src->hosts);
-
-    disk->src->path = newsource;
-    disk->src->format = format;
-    disk->src->type = snap->src->type;
-    disk->src->protocol = snap->src->protocol;
-    disk->src->nhosts = snap->src->nhosts;
-    disk->src->hosts = newhosts;
+    if (!(tmp = virStorageSourceCopy(snap->src, false)))
+        goto cleanup;

-    newsource = NULL;
-    newhosts = NULL;
+    tmp->backingStore = disk->src;
+    disk->src = tmp;

     if (persistDisk) {
-        VIR_FREE(persistDisk->src->path);
-        virStorageNetHostDefFree(persistDisk->src->nhosts,
-                                 persistDisk->src->hosts);
-
-        persistDisk->src->path = persistSource;
-        persistDisk->src->format = format;
-        persistDisk->src->type = snap->src->type;
-        persistDisk->src->protocol = snap->src->protocol;
-        persistDisk->src->nhosts = snap->src->nhosts;
-        persistDisk->src->hosts = persistHosts;
+        if (!(tmp = virStorageSourceCopy(snap->src, false)))
+            goto cleanup;

-        persistSource = NULL;
-        persistHosts = NULL;
+        tmp->backingStore = persistDisk->src;
+        persistDisk->src = tmp;
     }

  cleanup:
@@ -13004,10 +12962,6 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     virStorageFileDeinit(snap->src);
     VIR_FREE(device);
     VIR_FREE(source);
-    VIR_FREE(newsource);
-    VIR_FREE(persistSource);
-    virStorageNetHostDefFree(snap->src->nhosts, newhosts);
-    virStorageNetHostDefFree(snap->src->nhosts, persistHosts);
     return ret;
 }

@@ -13017,21 +12971,15 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
 static void
 qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
                                        virDomainObjPtr vm,
-                                       virDomainDiskDefPtr origdisk,
                                        virDomainDiskDefPtr disk,
                                        virDomainDiskDefPtr persistDisk,
                                        bool need_unlink)
 {
-    char *source = NULL;
-    char *persistSource = NULL;
+    virStorageSourcePtr tmp;
     struct stat st;

     ignore_value(virStorageFileInit(disk->src));

-    if (VIR_STRDUP(source, origdisk->src->path) < 0 ||
-        (persistDisk && VIR_STRDUP(persistSource, source) < 0))
-        goto cleanup;
-
     qemuDomainPrepareDiskChainElement(driver, vm, disk, disk->src,
                                       VIR_DISK_CHAIN_NO_ACCESS);
     if (need_unlink &&
@@ -13039,35 +12987,18 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
         virStorageFileUnlink(disk->src) < 0)
         VIR_WARN("Unable to remove just-created %s", disk->src->path);

+    virStorageFileDeinit(disk->src);
+
     /* Update vm in place to match changes.  */
-    VIR_FREE(disk->src->path);
-    disk->src->path = source;
-    source = NULL;
-    disk->src->format = origdisk->src->format;
-    disk->src->type = origdisk->src->type;
-    disk->src->protocol = origdisk->src->protocol;
-    virStorageNetHostDefFree(disk->src->nhosts, disk->src->hosts);
-    disk->src->nhosts = origdisk->src->nhosts;
-    disk->src->hosts = virStorageNetHostDefCopy(origdisk->src->nhosts,
-                                                origdisk->src->hosts);
+    tmp = disk->src->backingStore;
+    virStorageSourceFree(disk->src);
+    disk->src = tmp;
+
     if (persistDisk) {
-        VIR_FREE(persistDisk->src->path);
-        persistDisk->src->path = persistSource;
-        persistSource = NULL;
-        persistDisk->src->format = origdisk->src->format;
-        persistDisk->src->type = origdisk->src->type;
-        persistDisk->src->protocol = origdisk->src->protocol;
-        virStorageNetHostDefFree(persistDisk->src->nhosts,
-                                 persistDisk->src->hosts);
-        persistDisk->src->nhosts = origdisk->src->nhosts;
-        persistDisk->src->hosts = virStorageNetHostDefCopy(origdisk->src->nhosts,
-                                                           origdisk->src->hosts);
+        tmp = persistDisk->src->backingStore;
+        virStorageSourceFree(persistDisk->src);
+        persistDisk->src = tmp;
     }
-
- cleanup:
-    virStorageFileDeinit(disk->src);
-    VIR_FREE(source);
-    VIR_FREE(persistSource);
 }

 /* The domain is expected to be locked and active. */
@@ -13170,7 +13101,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
                 }

                 qemuDomainSnapshotUndoSingleDiskActive(driver, vm,
-                                                       snap->def->dom->disks[i],
                                                        vm->def->disks[i],
                                                        persistDisk,
                                                        need_unlink);
-- 
1.9.3




More information about the libvir-list mailing list