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

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