Blame SOURCES/libvirt-qemu-backup-Split-up-code-traversing-checkpoint-list-looking-for-bitmaps.patch

a41c76
From d0dc4217142fda8ce8850a30b7d89a344bb55d5e Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <d0dc4217142fda8ce8850a30b7d89a344bb55d5e@dist-git>
a41c76
From: Peter Krempa <pkrempa@redhat.com>
a41c76
Date: Tue, 23 Jun 2020 12:23:35 +0200
a41c76
Subject: [PATCH] qemu: backup: Split up code traversing checkpoint list
a41c76
 looking for bitmaps
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
The algorithm is getting quite complex. Split out the lookup of range of
a41c76
backing chain storage sources and bitmaps contained in them which
a41c76
correspond to one checkpoint.
a41c76
a41c76
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
a41c76
Reviewed-by: Eric Blake <eblake@redhat.com>
a41c76
(cherry picked from commit 562511afa6cef5948e6339596ba5954cb5ed0565)
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1804593
a41c76
Message-Id: <b3a1485033a5bb425f261caeb299973b2f39bbff.1592906423.git.pkrempa@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_backup.c | 111 ++++++++++++++++++++++-------------------
a41c76
 1 file changed, 61 insertions(+), 50 deletions(-)
a41c76
a41c76
diff --git a/src/qemu/qemu_backup.c b/src/qemu/qemu_backup.c
a41c76
index 5d18720f53..400b711f79 100644
a41c76
--- a/src/qemu/qemu_backup.c
a41c76
+++ b/src/qemu/qemu_backup.c
a41c76
@@ -173,72 +173,83 @@ qemuBackupDiskDataCleanup(virDomainObjPtr vm,
a41c76
 }
a41c76
 
a41c76
 
a41c76
+static int
a41c76
+qemuBackupGetBitmapMergeRange(virStorageSourcePtr from,
a41c76
+                              const char *bitmapname,
a41c76
+                              virJSONValuePtr *actions,
a41c76
+                              virStorageSourcePtr *to,
a41c76
+                              const char *diskdst,
a41c76
+                              virHashTablePtr blockNamedNodeData)
a41c76
+{
a41c76
+    g_autoptr(virJSONValue) act = virJSONValueNewArray();
a41c76
+    virStorageSourcePtr tmpsrc = NULL;
a41c76
+    virStorageSourcePtr n;
a41c76
+    bool foundbitmap = false;
a41c76
+
a41c76
+    for (n = from; virStorageSourceIsBacking(n); n = n->backingStore) {
a41c76
+        qemuBlockNamedNodeDataBitmapPtr bitmap = NULL;
a41c76
+
a41c76
+        if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
a41c76
+                                                             n,
a41c76
+                                                             bitmapname)))
a41c76
+            break;
a41c76
+
a41c76
+        foundbitmap = true;
a41c76
+
a41c76
+        if (bitmap->inconsistent) {
a41c76
+            virReportError(VIR_ERR_INVALID_ARG,
a41c76
+                           _("bitmap '%s' for image '%s%u' is inconsistent"),
a41c76
+                           bitmap->name, diskdst, n->id);
a41c76
+            return -1;
a41c76
+        }
a41c76
+
a41c76
+        if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(act,
a41c76
+                                                             n->nodeformat,
a41c76
+                                                             bitmapname) < 0)
a41c76
+            return -1;
a41c76
+
a41c76
+        tmpsrc = n;
a41c76
+    }
a41c76
+
a41c76
+    if (!foundbitmap) {
a41c76
+        virReportError(VIR_ERR_INVALID_ARG,
a41c76
+                       _("failed to find bitmap '%s' in image '%s%u'"),
a41c76
+                       bitmapname, diskdst, from->id);
a41c76
+        return -1;
a41c76
+    }
a41c76
+
a41c76
+    *actions = g_steal_pointer(&act;;
a41c76
+    *to = tmpsrc;
a41c76
+
a41c76
+    return 0;
a41c76
+}
a41c76
+
a41c76
+
a41c76
 virJSONValuePtr
a41c76
 qemuBackupDiskPrepareOneBitmapsChain(virDomainMomentDefPtr *incremental,
a41c76
                                      virStorageSourcePtr backingChain,
a41c76
                                      virHashTablePtr blockNamedNodeData,
a41c76
                                      const char *diskdst)
a41c76
 {
a41c76
-    qemuBlockNamedNodeDataBitmapPtr bitmap;
a41c76
     g_autoptr(virJSONValue) ret = NULL;
a41c76
     size_t incridx = 0;
a41c76
+    virStorageSourcePtr n = backingChain;
a41c76
 
a41c76
     ret = virJSONValueNewArray();
a41c76
 
a41c76
-    if (!(bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
a41c76
-                                                         backingChain,
a41c76
-                                                         incremental[0]->name))) {
a41c76
-        virReportError(VIR_ERR_INVALID_ARG,
a41c76
-                       _("failed to find bitmap '%s' in image '%s%u'"),
a41c76
-                       incremental[0]->name, diskdst, backingChain->id);
a41c76
-        return NULL;
a41c76
-    }
a41c76
+    for (incridx = 0; incremental[incridx]; incridx++) {
a41c76
+        g_autoptr(virJSONValue) tmp = virJSONValueNewArray();
a41c76
+        virStorageSourcePtr tmpsrc = NULL;
a41c76
 
a41c76
-    while (bitmap) {
a41c76
-        if (bitmap->inconsistent) {
a41c76
-            virReportError(VIR_ERR_INVALID_ARG,
a41c76
-                           _("bitmap '%s' for image '%s%u' is inconsistent"),
a41c76
-                           bitmap->name, diskdst, backingChain->id);
a41c76
+        if (qemuBackupGetBitmapMergeRange(n, incremental[incridx]->name,
a41c76
+                                          &tmp, &tmpsrc, diskdst,
a41c76
+                                          blockNamedNodeData) < 0)
a41c76
             return NULL;
a41c76
-        }
a41c76
 
a41c76
-        if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(ret,
a41c76
-                                                             backingChain->nodeformat,
a41c76
-                                                             bitmap->name) < 0)
a41c76
+        if (virJSONValueArrayConcat(ret, tmp) < 0)
a41c76
             return NULL;
a41c76
 
a41c76
-        if (backingChain->backingStore &&
a41c76
-            (bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
a41c76
-                                                            backingChain->backingStore,
a41c76
-                                                            incremental[incridx]->name))) {
a41c76
-            backingChain = backingChain->backingStore;
a41c76
-            continue;
a41c76
-        }
a41c76
-
a41c76
-        if (incremental[incridx + 1]) {
a41c76
-            if ((bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
a41c76
-                                                                backingChain,
a41c76
-                                                                incremental[incridx + 1]->name))) {
a41c76
-                incridx++;
a41c76
-                continue;
a41c76
-            }
a41c76
-
a41c76
-            if (backingChain->backingStore &&
a41c76
-                (bitmap = qemuBlockNamedNodeDataGetBitmapByName(blockNamedNodeData,
a41c76
-                                                                backingChain->backingStore,
a41c76
-                                                                incremental[incridx + 1]->name))) {
a41c76
-                incridx++;
a41c76
-                backingChain = backingChain->backingStore;
a41c76
-                continue;
a41c76
-            }
a41c76
-
a41c76
-            virReportError(VIR_ERR_INVALID_ARG,
a41c76
-                           _("failed to find bitmap '%s' in image '%s%u'"),
a41c76
-                           incremental[incridx]->name, diskdst, backingChain->id);
a41c76
-            return NULL;
a41c76
-        } else {
a41c76
-            break;
a41c76
-        }
a41c76
+        n = tmpsrc;
a41c76
     }
a41c76
 
a41c76
     return g_steal_pointer(&ret;;
a41c76
-- 
a41c76
2.27.0
a41c76