[libvirt] [PATCH RFC 23/40] qemu: checkpoint: Split out checkpoint creation code

Peter Krempa pkrempa at redhat.com
Fri Oct 18 16:11:08 UTC 2019


Separate out individual steps of creating a checkpoint from
qemuCheckpointCreateXML into separate functions. This makes the function
more readable and understandable and also some of the new functions will
be reusable when we will be creating a checkpoint along with a backup
in the upcoming patches.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_checkpoint.c | 160 ++++++++++++++++++++++++-------------
 src/qemu/qemu_checkpoint.h |   8 ++
 2 files changed, 111 insertions(+), 57 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 54719e7f5c..946ae78368 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -348,6 +348,90 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
 }


+static virDomainMomentObjPtr
+qemuCheckpointRedefine(virQEMUDriverPtr driver,
+                       virDomainObjPtr vm,
+                       virDomainCheckpointDefPtr *def,
+                       bool *update_current)
+{
+    virDomainMomentObjPtr chk = NULL;
+
+    if (virDomainCheckpointRedefinePrep(vm, def, &chk, driver->xmlopt,
+                                        update_current) < 0)
+        return NULL;
+
+    /* XXX Should we validate that the redefined checkpoint even
+     * makes sense, such as checking that qemu-img recognizes the
+     * checkpoint bitmap name in at least one of the domain's disks?  */
+
+    if (chk)
+        return chk;
+
+    chk = virDomainCheckpointAssignDef(vm->checkpoints, *def);
+    *def = NULL;
+    return chk;
+}
+
+
+int
+qemuCheckpointCreateCommon(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virCapsPtr caps,
+                           virDomainCheckpointDefPtr *def,
+                           virJSONValuePtr *actions,
+                           virDomainMomentObjPtr *chk)
+{
+    g_autoptr(virJSONValue) tmpactions = NULL;
+    virDomainMomentObjPtr parent;
+
+    if (qemuCheckpointPrepare(driver, caps, vm, *def) < 0)
+        return -1;
+
+    if ((parent = virDomainCheckpointGetCurrent(vm->checkpoints))) {
+        if (VIR_STRDUP((*def)->parent.parent_name, parent->def->name) < 0)
+            return -1;
+    }
+
+    if (!(tmpactions = virJSONValueNewArray()))
+        return -1;
+
+    if (qemuCheckpointAddActions(vm, tmpactions, parent, *def) < 0)
+        return -1;
+
+    if (!(*chk = virDomainCheckpointAssignDef(vm->checkpoints, *def)))
+        return -1;
+
+    *def = NULL;
+
+    *actions = g_steal_pointer(&tmpactions);
+    return 0;
+}
+
+
+static virDomainMomentObjPtr
+qemuCheckpointCreate(virQEMUDriverPtr driver,
+                     virDomainObjPtr vm,
+                     virCapsPtr caps,
+                     virDomainCheckpointDefPtr *def)
+{
+    g_autoptr(virJSONValue) actions = NULL;
+    virDomainMomentObjPtr chk = NULL;
+    int rc;
+
+    if (qemuCheckpointCreateCommon(driver, vm, caps, def, &actions, &chk) < 0)
+        return NULL;
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    rc = qemuMonitorTransaction(qemuDomainGetMonitor(vm), &actions);
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0) {
+        virDomainCheckpointObjListRemove(vm->checkpoints, chk);
+        return NULL;
+    }
+
+    return chk;
+}
+
+
 virDomainCheckpointPtr
 qemuCheckpointCreateXML(virDomainPtr domain,
                         virDomainObjPtr vm,
@@ -361,11 +445,8 @@ qemuCheckpointCreateXML(virDomainPtr domain,
     bool update_current = true;
     bool redefine = flags & VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE;
     unsigned int parse_flags = 0;
-    virDomainMomentObjPtr other = NULL;
     g_autoptr(virQEMUDriverConfig) cfg = NULL;
     g_autoptr(virCaps) caps = NULL;
-    g_autoptr(virJSONValue) actions = NULL;
-    int ret;
     g_autoptr(virDomainCheckpointDef) def = NULL;

     virCheckFlags(VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE, NULL);
@@ -400,44 +481,30 @@ qemuCheckpointCreateXML(virDomainPtr domain,
         return NULL;

     if (redefine) {
-        if (virDomainCheckpointRedefinePrep(vm, &def, &chk,
-                                            driver->xmlopt,
-                                            &update_current) < 0)
-            goto endjob;
-    } else if (qemuCheckpointPrepare(driver, caps, vm, def) < 0) {
-        goto endjob;
+        chk = qemuCheckpointRedefine(driver, vm, &def, &update_current);
+    } else {
+        chk = qemuCheckpointCreate(driver, vm, caps, &def);
     }

-    if (!chk) {
-        if (!(chk = virDomainCheckpointAssignDef(vm->checkpoints, def)))
-            goto endjob;
-
-        def = NULL;
-    }
+    if (!chk)
+        goto endjob;

-    other = virDomainCheckpointGetCurrent(vm->checkpoints);
-    if (other) {
-        if (!redefine &&
-            VIR_STRDUP(chk->def->parent_name, other->def->name) < 0)
-            goto endjob;
+    if (update_current)
+        virDomainCheckpointSetCurrent(vm->checkpoints, chk);
+
+    if (qemuCheckpointWriteMetadata(vm, chk, driver->caps,
+                                    driver->xmlopt,
+                                    cfg->checkpointDir) < 0) {
+        /* if writing of metadata fails, error out rather than trying
+         * to silently carry on without completing the checkpoint */
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("unable to save metadata for checkpoint %s"),
+                       chk->def->name);
+        virDomainCheckpointObjListRemove(vm->checkpoints, chk);
+        goto endjob;
     }

-    /* actually do the checkpoint */
-    if (redefine) {
-        /* XXX Should we validate that the redefined checkpoint even
-         * makes sense, such as checking that qemu-img recognizes the
-         * checkpoint bitmap name in at least one of the domain's disks?  */
-    } else {
-        if (!(actions = virJSONValueNewArray()))
-            goto endjob;
-        if (qemuCheckpointAddActions(vm, actions, other,
-                                     virDomainCheckpointObjGetDef(chk)) < 0)
-            goto endjob;
-        qemuDomainObjEnterMonitor(driver, vm);
-        ret = qemuMonitorTransaction(priv->mon, &actions);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0)
-            goto endjob;
-    }
+    virDomainCheckpointLinkParent(vm->checkpoints, chk);

     /* If we fail after this point, there's not a whole lot we can do;
      * we've successfully created the checkpoint, so we have to go
@@ -446,27 +513,6 @@ qemuCheckpointCreateXML(virDomainPtr domain,
     checkpoint = virGetDomainCheckpoint(domain, chk->def->name);

  endjob:
-    if (checkpoint) {
-        if (update_current)
-            virDomainCheckpointSetCurrent(vm->checkpoints, chk);
-        if (qemuCheckpointWriteMetadata(vm, chk, driver->caps,
-                                        driver->xmlopt,
-                                        cfg->checkpointDir) < 0) {
-            /* if writing of metadata fails, error out rather than trying
-             * to silently carry on without completing the checkpoint */
-            virObjectUnref(checkpoint);
-            checkpoint = NULL;
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("unable to save metadata for checkpoint %s"),
-                           chk->def->name);
-            virDomainCheckpointObjListRemove(vm->checkpoints, chk);
-        } else {
-            virDomainCheckpointLinkParent(vm->checkpoints, chk);
-        }
-    } else if (chk) {
-        virDomainCheckpointObjListRemove(vm->checkpoints, chk);
-    }
-
     qemuDomainObjEndJob(driver, vm);

     return checkpoint;
diff --git a/src/qemu/qemu_checkpoint.h b/src/qemu/qemu_checkpoint.h
index 49f51b1fdd..7fcbc99541 100644
--- a/src/qemu/qemu_checkpoint.h
+++ b/src/qemu/qemu_checkpoint.h
@@ -53,3 +53,11 @@ int
 qemuCheckpointDelete(virDomainObjPtr vm,
                      virDomainCheckpointPtr checkpoint,
                      unsigned int flags);
+
+int
+qemuCheckpointCreateCommon(virQEMUDriverPtr driver,
+                           virDomainObjPtr vm,
+                           virCapsPtr caps,
+                           virDomainCheckpointDefPtr *def,
+                           virJSONValuePtr *actions,
+                           virDomainMomentObjPtr *chk);
-- 
2.21.0




More information about the libvir-list mailing list