[libvirt] [PATCH RFC 15/40] qemu: checkpoint: Fix rollback and access to unlocked 'vm' when deleting checkpoints

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


Delete/merge bitmaps when deleting checkpoints using a 'transaction' so
that we don't have to deal with halfway-failed scenarios and also fix
access to 'vm' while in the monitor lock.

Signed-off-by: Peter Krempa <pkrempa at redhat.com>
---
 src/qemu/qemu_checkpoint.c | 47 +++++++++++++++++++-------------------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 4b4ad8bb83..a225f04831 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -133,11 +133,14 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,

     if (!metadata_only) {
         qemuDomainObjPrivatePtr priv = vm->privateData;
-        bool success = true;
         bool search_parents;
         virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
+        int rc;
+        g_autoptr(virJSONValue) actions = NULL;
+
+        if (!(actions = virJSONValueNewArray()))
+            return -1;

-        qemuDomainObjEnterMonitor(driver, vm);
         parent = virDomainCheckpointFindByName(vm->checkpoints,
                                                chk->def->parent_name);
         for (i = 0; i < chkdef->ndisks; i++) {
@@ -167,31 +170,29 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
                         continue;
                     search_parents = false;

-                    arr = virJSONValueNewArray();
-                    if (!arr ||
-                        virJSONValueArrayAppendString(arr, disk->bitmap) < 0) {
-                        success = false;
-                        break;
-                    }
-                    if (chk == virDomainCheckpointGetCurrent(vm->checkpoints) &&
-                        qemuMonitorEnableBitmap(priv->mon, node,
-                                                disk2->bitmap) < 0) {
-                        success = false;
-                        break;
-                    }
-                    if (qemuMonitorMergeBitmaps(priv->mon, node,
-                                                disk2->bitmap, &arr) < 0) {
-                        success = false;
-                        break;
+                    if (!(arr = virJSONValueNewArray()))
+                        return -1;
+
+                    if (virJSONValueArrayAppendString(arr, disk->bitmap) < 0)
+                        return -1;
+
+                    if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)) {
+                        if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
+                            return -1;
                     }
+
+                    if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
+                        return -1;
                 }
             }
-            if (qemuMonitorDeleteBitmap(priv->mon, node, disk->bitmap) < 0) {
-                success = false;
-                break;
-            }
+
+            if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
+                return -1;
         }
-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || !success)
+
+        qemuDomainObjEnterMonitor(driver, vm);
+        rc = qemuMonitorTransaction(priv->mon, &actions);
+        if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
             return -1;
     }

-- 
2.21.0




More information about the libvir-list mailing list