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

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