[libvirt] [PATCHv5 25/28] qemu: snapshot: Improve approach to deal with snapshot metadata

Peter Krempa pkrempa at redhat.com
Fri Jul 4 11:29:40 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 | 122 ++++++++++++++-----------------------------------
 1 file changed, 34 insertions(+), 88 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 15c5f3b..e648108 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12810,14 +12810,11 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
                                          qemuDomainAsyncJob asyncJob)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virStorageSourcePtr newDiskSrc = NULL;
+    virStorageSourcePtr persistDiskSrc = NULL;
     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;
@@ -12831,26 +12828,27 @@ 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.  */
-    virStorageSourceBackingStoreClear(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)
+    if (!(newDiskSrc = virStorageSourceCopy(snap->src, false)))
         goto cleanup;

-    if (persistDisk &&
-        VIR_STRDUP(persistSource, snap->src->path) < 0)
+    if (virStorageSourceInitChainElement(newDiskSrc, disk->src, false) < 0)
         goto cleanup;

+    if (persistDisk) {
+        if (!(persistDiskSrc = virStorageSourceCopy(snap->src, false)))
+            goto cleanup;
+
+        if (virStorageSourceInitChainElement(persistDiskSrc, persistDisk->src,
+                                             false) < 0)
+            goto cleanup;
+    }
+
     switch ((virStorageType)snap->src->type) {
     case VIR_STORAGE_TYPE_BLOCK:
     case VIR_STORAGE_TYPE_FILE:
@@ -12876,15 +12874,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:
@@ -12935,45 +12924,24 @@ 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;
-
-    newsource = NULL;
-    newhosts = NULL;
+    newDiskSrc->backingStore = disk->src;
+    disk->src = newDiskSrc;
+    newDiskSrc = NULL;

     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;
-
-        persistSource = NULL;
-        persistHosts = NULL;
+        persistDiskSrc->backingStore = persistDisk->src;
+        persistDisk->src = persistDiskSrc;
+        persistDiskSrc = NULL;
     }

  cleanup:
     if (need_unlink && virStorageFileUnlink(snap->src))
         VIR_WARN("unable to unlink just-created %s", source);
     virStorageFileDeinit(snap->src);
+    virStorageSourceFree(newDiskSrc);
+    virStorageSourceFree(persistDiskSrc);
     VIR_FREE(device);
     VIR_FREE(source);
-    VIR_FREE(newsource);
-    VIR_FREE(persistSource);
-    virStorageNetHostDefFree(snap->src->nhosts, newhosts);
-    virStorageNetHostDefFree(snap->src->nhosts, persistHosts);
     return ret;
 }

@@ -12983,21 +12951,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 &&
@@ -13005,35 +12967,20 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver,
         virStorageFileUnlink(disk->src) < 0)
         VIR_WARN("Unable to remove just-created %s", disk->src->path);

-    /* 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);
+    virStorageFileDeinit(disk->src);
+
+    /* Update vm in place to match changes. */
+    tmp = disk->src;
+    disk->src = tmp->backingStore;
+    tmp->backingStore = NULL;
+    virStorageSourceFree(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;
+        persistDisk->src = tmp->backingStore;
+        tmp->backingStore = NULL;
+        virStorageSourceFree(tmp);
     }
-
- cleanup:
-    virStorageFileDeinit(disk->src);
-    VIR_FREE(source);
-    VIR_FREE(persistSource);
 }

 /* The domain is expected to be locked and active. */
@@ -13137,7 +13084,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