a41c76
From 628b1f392c5fb2e3a492640a9069edd244a7b150 Mon Sep 17 00:00:00 2001
a41c76
Message-Id: <628b1f392c5fb2e3a492640a9069edd244a7b150@dist-git>
a41c76
From: Peter Krempa <pkrempa@redhat.com>
a41c76
Date: Tue, 4 Feb 2020 15:07:50 +0100
a41c76
Subject: [PATCH] qemu: checkpoint: split out checkpoint deletion bitmaps
a41c76
MIME-Version: 1.0
a41c76
Content-Type: text/plain; charset=UTF-8
a41c76
Content-Transfer-Encoding: 8bit
a41c76
a41c76
qemuCheckpointDiscard is a massive function that can be separated into
a41c76
smaller bits. Extract the part that actually modifies the disk from the
a41c76
metadata handling.
a41c76
a41c76
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
a41c76
Reviewed-by: Eric Blake <eblake@redhat.com>
a41c76
(cherry picked from commit 44e1b85717b9a4e6df24f9cbf846627e4f29b859)
a41c76
a41c76
https://bugzilla.redhat.com/show_bug.cgi?id=1207659
a41c76
Message-Id: <b6cdc7883d1f3b16e8a496dac6e9ec046ec2c4ea.1580824112.git.pkrempa@redhat.com>
a41c76
Reviewed-by: Ján Tomko <jtomko@redhat.com>
a41c76
---
a41c76
 src/qemu/qemu_checkpoint.c | 137 ++++++++++++++++++++-----------------
a41c76
 1 file changed, 76 insertions(+), 61 deletions(-)
a41c76
a41c76
diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
a41c76
index d13d4c2a37..9ff3129570 100644
a41c76
--- a/src/qemu/qemu_checkpoint.c
a41c76
+++ b/src/qemu/qemu_checkpoint.c
a41c76
@@ -104,6 +104,81 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm,
a41c76
 }
a41c76
 
a41c76
 
a41c76
+static int
a41c76
+qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
a41c76
+                             virDomainCheckpointDefPtr chkdef,
a41c76
+                             bool chkcurrent,
a41c76
+                             virDomainMomentObjPtr parent)
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
+
a41c76
+    for (i = 0; i < chkdef->ndisks; i++) {
a41c76
+        virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
a41c76
+        const char *node;
a41c76
+
a41c76
+        if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
+            continue;
a41c76
+
a41c76
+        node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
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
+
a41c76
+                disk2 = &parentdef->disks[j];
a41c76
+                if (STRNEQ(disk->name, disk2->name) ||
a41c76
+                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
+                    continue;
a41c76
+                search_parents = false;
a41c76
+
a41c76
+                if (!(arr = virJSONValueNewArray()))
a41c76
+                    return -1;
a41c76
+
a41c76
+                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
a41c76
+                    return -1;
a41c76
+
a41c76
+                if (chkcurrent) {
a41c76
+                    if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
a41c76
+                        return -1;
a41c76
+                }
a41c76
+
a41c76
+                if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
a41c76
+                    return -1;
a41c76
+            }
a41c76
+        }
a41c76
+
a41c76
+        if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
a41c76
+            return -1;
a41c76
+    }
a41c76
+
a41c76
+    qemuDomainObjEnterMonitor(driver, vm);
a41c76
+    rc = qemuMonitorTransaction(priv->mon, &actions);
a41c76
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
a41c76
+        return -1;
a41c76
+
a41c76
+    return 0;
a41c76
+}
a41c76
+
a41c76
+
a41c76
 static int
a41c76
 qemuCheckpointDiscard(virQEMUDriverPtr driver,
a41c76
                       virDomainObjPtr vm,
a41c76
@@ -112,9 +187,6 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
a41c76
                       bool metadata_only)
a41c76
 {
a41c76
     virDomainMomentObjPtr parent = NULL;
a41c76
-    virDomainMomentObjPtr moment;
a41c76
-    virDomainCheckpointDefPtr parentdef = NULL;
a41c76
-    size_t i, j;
a41c76
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
a41c76
     g_autofree char *chkFile = NULL;
a41c76
     bool chkcurrent = chk == virDomainCheckpointGetCurrent(vm->checkpoints);
a41c76
@@ -129,67 +201,10 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
a41c76
                               chk->def->name);
a41c76
 
a41c76
     if (!metadata_only) {
a41c76
-        qemuDomainObjPrivatePtr priv = vm->privateData;
a41c76
-        bool search_parents;
a41c76
         virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
a41c76
-        int rc;
a41c76
-        g_autoptr(virJSONValue) actions = NULL;
a41c76
-
a41c76
-        if (!(actions = virJSONValueNewArray()))
a41c76
-            return -1;
a41c76
-
a41c76
         parent = virDomainCheckpointFindByName(vm->checkpoints,
a41c76
                                                chk->def->parent_name);
a41c76
-        for (i = 0; i < chkdef->ndisks; i++) {
a41c76
-            virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
a41c76
-            const char *node;
a41c76
-
a41c76
-            if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
-                continue;
a41c76
-
a41c76
-            node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
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
-
a41c76
-                    disk2 = &parentdef->disks[j];
a41c76
-                    if (STRNEQ(disk->name, disk2->name) ||
a41c76
-                        disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
a41c76
-                        continue;
a41c76
-                    search_parents = false;
a41c76
-
a41c76
-                    if (!(arr = virJSONValueNewArray()))
a41c76
-                        return -1;
a41c76
-
a41c76
-                    if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
a41c76
-                        return -1;
a41c76
-
a41c76
-                    if (chkcurrent) {
a41c76
-                        if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
a41c76
-                            return -1;
a41c76
-                    }
a41c76
-
a41c76
-                    if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
a41c76
-                        return -1;
a41c76
-                }
a41c76
-            }
a41c76
-
a41c76
-            if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
a41c76
-                return -1;
a41c76
-        }
a41c76
-
a41c76
-        qemuDomainObjEnterMonitor(driver, vm);
a41c76
-        rc = qemuMonitorTransaction(priv->mon, &actions);
a41c76
-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
a41c76
+        if (qemuCheckpointDiscardBitmaps(vm, chkdef, chkcurrent, parent) < 0)
a41c76
             return -1;
a41c76
     }
a41c76
 
a41c76
-- 
a41c76
2.25.0
a41c76