]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: snapshot: Introduce qemuSnapshotDiskContext
authorPeter Krempa <pkrempa@redhat.com>
Mon, 21 Sep 2020 13:52:43 +0000 (15:52 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Thu, 24 Sep 2020 09:49:13 +0000 (11:49 +0200)
Add a container struct which holds all data needed to create and clean
up after a (for now external) snapshot. This will aggregate all the
'qemuSnapshotDiskDataPtr' the 'actions' of a transaction QMP command and
everything needed for cleanup at any given point.

This aggregation allows to simplify the arguments of the functions which
prepare the snapshot data and additionally will simplify the code
necessary for creating overlays on top of <transient/> disks.

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

index 6fdc187d836af7c97b2cf6532a53f9c9b1e9f5ac..b9b640058cd634a8686d0fc403aa66848a54a3c1 100644 (file)
@@ -842,6 +842,52 @@ qemuSnapshotDiskCleanup(qemuSnapshotDiskDataPtr data,
 }
 
 
+struct _qemuSnapshotDiskContext {
+    qemuSnapshotDiskDataPtr dd;
+    size_t ndd;
+
+    virJSONValuePtr actions;
+
+    /* needed for automatic cleanup of 'dd' */
+    virDomainObjPtr vm;
+    qemuDomainAsyncJob asyncJob;
+};
+
+typedef struct _qemuSnapshotDiskContext qemuSnapshotDiskContext;
+typedef qemuSnapshotDiskContext *qemuSnapshotDiskContextPtr;
+
+
+static qemuSnapshotDiskContextPtr
+qemuSnapshotDiskContextNew(size_t ndisks,
+                           virDomainObjPtr vm,
+                           qemuDomainAsyncJob asyncJob)
+{
+    qemuSnapshotDiskContextPtr ret = g_new0(qemuSnapshotDiskContext, 1);
+
+    ret->dd = g_new0(qemuSnapshotDiskData, ndisks);
+    ret->ndd = ndisks;
+    ret->actions = virJSONValueNewArray();
+    ret->vm = vm;
+    ret->asyncJob = asyncJob;
+
+    return ret;
+}
+
+
+static void
+qemuSnapshotDiskContextCleanup(qemuSnapshotDiskContextPtr snapctxt)
+{
+    if (!snapctxt)
+        return;
+
+    virJSONValueFree(snapctxt->actions);
+
+    qemuSnapshotDiskCleanup(snapctxt->dd, snapctxt->ndd, snapctxt->vm, snapctxt->asyncJob);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(qemuSnapshotDiskContext, qemuSnapshotDiskContextCleanup);
+
+
 /**
  * qemuSnapshotDiskBitmapsPropagate:
  *
@@ -1046,25 +1092,19 @@ qemuSnapshotDiskPrepareOne(virDomainObjPtr vm,
  * Collects and prepares a list of structures that hold information about disks
  * that are selected for the snapshot.
  */
-static int
+static qemuSnapshotDiskContextPtr
 qemuSnapshotDiskPrepare(virDomainObjPtr vm,
                         virDomainMomentObjPtr snap,
                         virQEMUDriverConfigPtr cfg,
                         bool reuse,
                         virHashTablePtr blockNamedNodeData,
-                        qemuDomainAsyncJob asyncJob,
-                        qemuSnapshotDiskDataPtr *rdata,
-                        size_t *rndata,
-                        virJSONValuePtr actions)
+                        qemuDomainAsyncJob asyncJob)
 {
+    g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
     size_t i;
-    qemuSnapshotDiskDataPtr data;
-    size_t ndata = 0;
     virDomainSnapshotDefPtr snapdef = virDomainSnapshotObjGetDef(snap);
-    int ret = -1;
 
-    if (VIR_ALLOC_N(data, snapdef->ndisks) < 0)
-        return -1;
+    snapctxt = qemuSnapshotDiskContextNew(snapdef->ndisks, vm, asyncJob);
 
     for (i = 0; i < snapdef->ndisks; i++) {
         if (snapdef->disks[i].snapshot == VIR_DOMAIN_SNAPSHOT_LOCATION_NONE)
@@ -1072,21 +1112,15 @@ qemuSnapshotDiskPrepare(virDomainObjPtr vm,
 
         if (qemuSnapshotDiskPrepareOne(vm, cfg, vm->def->disks[i],
                                        snapdef->disks + i,
-                                       data + ndata++,
+                                       snapctxt->dd + snapctxt->ndd++,
                                        blockNamedNodeData,
                                        reuse,
                                        asyncJob,
-                                       actions) < 0)
-            goto cleanup;
+                                       snapctxt->actions) < 0)
+            return NULL;
     }
 
-    *rdata = g_steal_pointer(&data);
-    *rndata = ndata;
-    ret = 0;
-
- cleanup:
-    qemuSnapshotDiskCleanup(data, ndata, vm, asyncJob);
-    return ret;
+    return g_steal_pointer(&snapctxt);
 }
 
 
@@ -1159,42 +1193,34 @@ qemuSnapshotCreateActiveExternalDisks(virQEMUDriverPtr driver,
                                       qemuDomainAsyncJob asyncJob)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
-    g_autoptr(virJSONValue) actions = NULL;
     int rc;
-    int ret = -1;
     size_t i;
     bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0;
-    qemuSnapshotDiskDataPtr diskdata = NULL;
-    size_t ndiskdata = 0;
+    g_autoptr(qemuSnapshotDiskContext) snapctxt = NULL;
 
     if (virDomainObjCheckActive(vm) < 0)
         return -1;
 
-    actions = virJSONValueNewArray();
-
     /* prepare a list of objects to use in the vm definition so that we don't
      * have to roll back later */
-    if (qemuSnapshotDiskPrepare(vm, snap, cfg, reuse,
-                                blockNamedNodeData, asyncJob,
-                                &diskdata, &ndiskdata, actions) < 0)
-        goto cleanup;
+    if (!(snapctxt = qemuSnapshotDiskPrepare(vm, snap, cfg, reuse,
+                                             blockNamedNodeData, asyncJob)))
+        return -1;
 
     /* check whether there's anything to do */
-    if (ndiskdata == 0) {
-        ret = 0;
-        goto cleanup;
-    }
+    if (snapctxt->ndd == 0)
+        return 0;
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
-        goto cleanup;
+        return -1;
 
-    rc = qemuMonitorTransaction(priv->mon, &actions);
+    rc = qemuMonitorTransaction(priv->mon, &snapctxt->actions);
 
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
         rc = -1;
 
-    for (i = 0; i < ndiskdata; i++) {
-        qemuSnapshotDiskDataPtr dd = &diskdata[i];
+    for (i = 0; i < snapctxt->ndd; i++) {
+        qemuSnapshotDiskDataPtr dd = snapctxt->dd + i;
 
         virDomainAuditDisk(vm, dd->disk->src, dd->src, "snapshot", rc >= 0);
 
@@ -1203,18 +1229,14 @@ qemuSnapshotCreateActiveExternalDisks(virQEMUDriverPtr driver,
     }
 
     if (rc < 0)
-        goto cleanup;
+        return -1;
 
     if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0 ||
         (vm->newDef && virDomainDefSave(vm->newDef, driver->xmlopt,
                                         cfg->configDir) < 0))
-        goto cleanup;
-
-    ret = 0;
+        return -1;
 
- cleanup:
-    qemuSnapshotDiskCleanup(diskdata, ndiskdata, vm, asyncJob);
-    return ret;
+    return 0;
 }