Blame SOURCES/libvirt-qemu-checkpoint-Introduce-helper-to-find-checkpoint-disk-definition-in-parents.patch

a41c76
From a7a774b357e4f56ef4860dbc04065197e3dd9640 Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <a7a774b357e4f56ef4860dbc04065197e3dd9640@dist-git>
a41c76
From: Peter Krempa <pkrempa@redhat.com>
a41c76
Date: Tue, 4 Feb 2020 15:07:56 +0100
a41c76
Subject: [PATCH] qemu: checkpoint: Introduce helper to find checkpoint disk
a41c76
 definition in parents
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
The algorithm is used in two places to find the parent checkpoint object
a41c76
which contains given disk and then uses data from the disk. Additionally
a41c76
the code is written in a very non-obvious way. Factor out the lookup of
a41c76
the disk into a function which also simplifies the callers.
a41c76
a41c76
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
a41c76
Reviewed-by: Eric Blake <eblake@redhat.com>
a41c76
(cherry picked from commit 6796194a28bd42bcbb237ffae6faea262fcce660)
a41c76
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1207659
a41c76
Message-Id: <4b9ca38d8272158c6d254cb1d3dad21cc736ad9f.1580824112.git.pkrempa@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_checkpoint.c | 127 ++++++++++++++++++++-----------------
a41c76
 1 file changed, 70 insertions(+), 57 deletions(-)
a41c76
a41c76
diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
a41c76
index 326707e098..1100f6e744 100644
a41c76
--- a/src/qemu/qemu_checkpoint.c
a41c76
+++ b/src/qemu/qemu_checkpoint.c
a41c76
@@ -104,6 +104,50 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm,
a41c76
 }
a41c76
 
a41c76
 
a41c76
+/**
a41c76
+ * qemuCheckpointFindActiveDiskInParent:
a41c76
+ * @vm: domain object
a41c76
+ * @from: starting moment object
a41c76
+ * @diskname: name (target) of the disk to find
a41c76
+ *
a41c76
+ * Find the first checkpoint starting from @from continuing through parents
a41c76
+ * of the checkpoint which describes disk @diskname. Return the pointer to the
a41c76
+ * definition of the disk.
a41c76
+ */
a41c76
+static virDomainCheckpointDiskDef *
a41c76
+qemuCheckpointFindActiveDiskInParent(virDomainObjPtr vm,
a41c76
+                                     virDomainMomentObjPtr from,
a41c76
+                                     const char *diskname)
a41c76
+{
a41c76
+    virDomainMomentObjPtr parent = from;
a41c76
+    virDomainCheckpointDefPtr parentdef = NULL;
a41c76
+    size_t i;
a41c76
+
a41c76
+    while (parent) {
a41c76
+        parentdef = virDomainCheckpointObjGetDef(parent);
a41c76
+
a41c76
+        for (i = 0; i < parentdef->ndisks; i++) {
a41c76
+            virDomainCheckpointDiskDef *chkdisk = &parentdef->disks[i];
a41c76
+
a41c76
+            if (STRNEQ(chkdisk->name, diskname))
a41c76
+                continue;
a41c76
+
a41c76
+            /* currently inspected checkpoint doesn't describe the disk,
a41c76
+             * continue into parent checkpoint */
a41c76
+            if (chkdisk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
+                break;
a41c76
+
a41c76
+            return chkdisk;
a41c76
+        }
a41c76
+
a41c76
+        parent = virDomainCheckpointFindByName(vm->checkpoints,
a41c76
+                                               parentdef->parent.parent_name);
a41c76
+    }
a41c76
+
a41c76
+    return NULL;
a41c76
+}
a41c76
+
a41c76
+
a41c76
 static int
a41c76
 qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
a41c76
                              virDomainCheckpointDefPtr chkdef,
a41c76
@@ -112,13 +156,9 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
a41c76
 {
a41c76
     qemuDomainObjPrivatePtr priv = vm->privateData;
a41c76
     virQEMUDriverPtr driver = priv->driver;
a41c76
-    virDomainMomentObjPtr moment;
a41c76
-    virDomainCheckpointDefPtr parentdef = NULL;
a41c76
-    bool search_parents;
a41c76
     int rc;
a41c76
     g_autoptr(virJSONValue) actions = NULL;
a41c76
     size_t i;
a41c76
-    size_t j;
a41c76
 
a41c76
     if (!(actions = virJSONValueNewArray()))
a41c76
         return -1;
a41c76
@@ -126,6 +166,7 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
a41c76
     for (i = 0; i < chkdef->ndisks; i++) {
a41c76
         virDomainCheckpointDiskDef *chkdisk = &chkdef->disks[i];
a41c76
         virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
a41c76
+        virDomainCheckpointDiskDef *parentchkdisk = NULL;
a41c76
 
a41c76
         /* domdisk can be missing e.g. when it was unplugged */
a41c76
         if (!domdisk)
a41c76
@@ -137,42 +178,28 @@ qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
a41c76
         /* If any ancestor checkpoint has a bitmap for the same
a41c76
          * disk, then this bitmap must be merged to the
a41c76
          * ancestor. */
a41c76
-        search_parents = true;
a41c76
-        for (moment = parent;
a41c76
-             search_parents && moment;
a41c76
-             moment = virDomainCheckpointFindByName(vm->checkpoints,
a41c76
-                                                    parentdef->parent.parent_name)) {
a41c76
-            parentdef = virDomainCheckpointObjGetDef(moment);
a41c76
-            for (j = 0; j < parentdef->ndisks; j++) {
a41c76
-                virDomainCheckpointDiskDef *disk2;
a41c76
-                g_autoptr(virJSONValue) arr = NULL;
a41c76
+        if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, parent, chkdisk->name))) {
a41c76
+            g_autoptr(virJSONValue) arr = NULL;
a41c76
 
a41c76
-                disk2 = &parentdef->disks[j];
a41c76
-                if (STRNEQ(chkdisk->name, disk2->name) ||
a41c76
-                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
-                    continue;
a41c76
-                search_parents = false;
a41c76
+            if (!(arr = virJSONValueNewArray()))
a41c76
+                return -1;
a41c76
 
a41c76
-                if (!(arr = virJSONValueNewArray()))
a41c76
-                    return -1;
a41c76
+            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
a41c76
+                                                                 domdisk->src->nodeformat,
a41c76
+                                                                 chkdisk->bitmap) < 0)
a41c76
+                return -1;
a41c76
 
a41c76
-                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr,
a41c76
-                                                                     domdisk->src->nodeformat,
a41c76
-                                                                     chkdisk->bitmap) < 0)
a41c76
-                    return -1;
a41c76
-
a41c76
-                if (chkcurrent) {
a41c76
-                    if (qemuMonitorTransactionBitmapEnable(actions,
a41c76
-                                                           domdisk->src->nodeformat,
a41c76
-                                                           disk2->bitmap) < 0)
a41c76
-                        return -1;
a41c76
-                }
a41c76
-
a41c76
-                if (qemuMonitorTransactionBitmapMerge(actions,
a41c76
-                                                      domdisk->src->nodeformat,
a41c76
-                                                      disk2->bitmap, &arr) < 0)
a41c76
+            if (chkcurrent) {
a41c76
+                if (qemuMonitorTransactionBitmapEnable(actions,
a41c76
+                                                       domdisk->src->nodeformat,
a41c76
+                                                       parentchkdisk->bitmap) < 0)
a41c76
                     return -1;
a41c76
             }
a41c76
+
a41c76
+            if (qemuMonitorTransactionBitmapMerge(actions,
a41c76
+                                                  domdisk->src->nodeformat,
a41c76
+                                                  parentchkdisk->bitmap, &arr) < 0)
a41c76
+                return -1;
a41c76
         }
a41c76
 
a41c76
         if (qemuMonitorTransactionBitmapRemove(actions,
a41c76
@@ -324,14 +351,12 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
a41c76
                          virDomainMomentObjPtr old_current,
a41c76
                          virDomainCheckpointDefPtr def)
a41c76
 {
a41c76
-    size_t i, j;
a41c76
-    virDomainCheckpointDefPtr olddef;
a41c76
-    virDomainMomentObjPtr parent;
a41c76
-    bool search_parents;
a41c76
+    size_t i;
a41c76
 
a41c76
     for (i = 0; i < def->ndisks; i++) {
a41c76
         virDomainCheckpointDiskDef *chkdisk = &def->disks[i];
a41c76
         virDomainDiskDefPtr domdisk = virDomainDiskByTarget(vm->def, chkdisk->name);
a41c76
+        virDomainCheckpointDiskDef *parentchkdisk = NULL;
a41c76
 
a41c76
         /* checkpoint definition validator mandates that the corresponding
a41c76
          * domdisk should exist */
a41c76
@@ -351,25 +376,13 @@ qemuCheckpointAddActions(virDomainObjPtr vm,
a41c76
          * iteration; but it is also possible to have to search
a41c76
          * further than the immediate parent to find another
a41c76
          * checkpoint with a bitmap on the same disk.  */
a41c76
-        search_parents = true;
a41c76
-        for (parent = old_current; search_parents && parent;
a41c76
-             parent = virDomainCheckpointFindByName(vm->checkpoints,
a41c76
-                                                    olddef->parent.parent_name)) {
a41c76
-            olddef = virDomainCheckpointObjGetDef(parent);
a41c76
-            for (j = 0; j < olddef->ndisks; j++) {
a41c76
-                virDomainCheckpointDiskDef *disk2;
a41c76
+        if ((parentchkdisk = qemuCheckpointFindActiveDiskInParent(vm, old_current,
a41c76
+                                                                  chkdisk->name))) {
a41c76
 
a41c76
-                disk2 = &olddef->disks[j];
a41c76
-                if (STRNEQ(chkdisk->name, disk2->name) ||
a41c76
-                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
-                    continue;
a41c76
-                if (qemuMonitorTransactionBitmapDisable(actions,
a41c76
-                                                        domdisk->src->nodeformat,
a41c76
-                                                        disk2->bitmap) < 0)
a41c76
-                    return -1;
a41c76
-                search_parents = false;
a41c76
-                break;
a41c76
-            }
a41c76
+            if (qemuMonitorTransactionBitmapDisable(actions,
a41c76
+                                                    domdisk->src->nodeformat,
a41c76
+                                                    parentchkdisk->bitmap) < 0)
a41c76
+                return -1;
a41c76
         }
a41c76
     }
a41c76
     return 0;
a41c76
-- 
a41c76
2.25.0
a41c76