render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
Blob Blame History Raw
From 628b1f392c5fb2e3a492640a9069edd244a7b150 Mon Sep 17 00:00:00 2001
Message-Id: <628b1f392c5fb2e3a492640a9069edd244a7b150@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Tue, 4 Feb 2020 15:07:50 +0100
Subject: [PATCH] qemu: checkpoint: split out checkpoint deletion bitmaps
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

qemuCheckpointDiscard is a massive function that can be separated into
smaller bits. Extract the part that actually modifies the disk from the
metadata handling.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 44e1b85717b9a4e6df24f9cbf846627e4f29b859)

https://bugzilla.redhat.com/show_bug.cgi?id=1207659
Message-Id: <b6cdc7883d1f3b16e8a496dac6e9ec046ec2c4ea.1580824112.git.pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
---
 src/qemu/qemu_checkpoint.c | 137 ++++++++++++++++++++-----------------
 1 file changed, 76 insertions(+), 61 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index d13d4c2a37..9ff3129570 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -104,6 +104,81 @@ qemuCheckpointWriteMetadata(virDomainObjPtr vm,
 }
 
 
+static int
+qemuCheckpointDiscardBitmaps(virDomainObjPtr vm,
+                             virDomainCheckpointDefPtr chkdef,
+                             bool chkcurrent,
+                             virDomainMomentObjPtr parent)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverPtr driver = priv->driver;
+    virDomainMomentObjPtr moment;
+    virDomainCheckpointDefPtr parentdef = NULL;
+    bool search_parents;
+    int rc;
+    g_autoptr(virJSONValue) actions = NULL;
+    size_t i;
+    size_t j;
+
+    if (!(actions = virJSONValueNewArray()))
+        return -1;
+
+    for (i = 0; i < chkdef->ndisks; i++) {
+        virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
+        const char *node;
+
+        if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+            continue;
+
+        node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
+        /* If any ancestor checkpoint has a bitmap for the same
+         * disk, then this bitmap must be merged to the
+         * ancestor. */
+        search_parents = true;
+        for (moment = parent;
+             search_parents && moment;
+             moment = virDomainCheckpointFindByName(vm->checkpoints,
+                                                    parentdef->parent.parent_name)) {
+            parentdef = virDomainCheckpointObjGetDef(moment);
+            for (j = 0; j < parentdef->ndisks; j++) {
+                virDomainCheckpointDiskDef *disk2;
+                g_autoptr(virJSONValue) arr = NULL;
+
+                disk2 = &parentdef->disks[j];
+                if (STRNEQ(disk->name, disk2->name) ||
+                    disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
+                    continue;
+                search_parents = false;
+
+                if (!(arr = virJSONValueNewArray()))
+                    return -1;
+
+                if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
+                    return -1;
+
+                if (chkcurrent) {
+                    if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
+                        return -1;
+                }
+
+                if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
+                    return -1;
+            }
+        }
+
+        if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
+            return -1;
+    }
+
+    qemuDomainObjEnterMonitor(driver, vm);
+    rc = qemuMonitorTransaction(priv->mon, &actions);
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+        return -1;
+
+    return 0;
+}
+
+
 static int
 qemuCheckpointDiscard(virQEMUDriverPtr driver,
                       virDomainObjPtr vm,
@@ -112,9 +187,6 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
                       bool metadata_only)
 {
     virDomainMomentObjPtr parent = NULL;
-    virDomainMomentObjPtr moment;
-    virDomainCheckpointDefPtr parentdef = NULL;
-    size_t i, j;
     g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(driver);
     g_autofree char *chkFile = NULL;
     bool chkcurrent = chk == virDomainCheckpointGetCurrent(vm->checkpoints);
@@ -129,67 +201,10 @@ qemuCheckpointDiscard(virQEMUDriverPtr driver,
                               chk->def->name);
 
     if (!metadata_only) {
-        qemuDomainObjPrivatePtr priv = vm->privateData;
-        bool search_parents;
         virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
-        int rc;
-        g_autoptr(virJSONValue) actions = NULL;
-
-        if (!(actions = virJSONValueNewArray()))
-            return -1;
-
         parent = virDomainCheckpointFindByName(vm->checkpoints,
                                                chk->def->parent_name);
-        for (i = 0; i < chkdef->ndisks; i++) {
-            virDomainCheckpointDiskDef *disk = &chkdef->disks[i];
-            const char *node;
-
-            if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
-                continue;
-
-            node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
-            /* If any ancestor checkpoint has a bitmap for the same
-             * disk, then this bitmap must be merged to the
-             * ancestor. */
-            search_parents = true;
-            for (moment = parent;
-                 search_parents && moment;
-                 moment = virDomainCheckpointFindByName(vm->checkpoints,
-                                                        parentdef->parent.parent_name)) {
-                parentdef = virDomainCheckpointObjGetDef(moment);
-                for (j = 0; j < parentdef->ndisks; j++) {
-                    virDomainCheckpointDiskDef *disk2;
-                    g_autoptr(virJSONValue) arr = NULL;
-
-                    disk2 = &parentdef->disks[j];
-                    if (STRNEQ(disk->name, disk2->name) ||
-                        disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
-                        continue;
-                    search_parents = false;
-
-                    if (!(arr = virJSONValueNewArray()))
-                        return -1;
-
-                    if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(arr, node, disk->bitmap) < 0)
-                        return -1;
-
-                    if (chkcurrent) {
-                        if (qemuMonitorTransactionBitmapEnable(actions, node, disk2->bitmap) < 0)
-                            return -1;
-                    }
-
-                    if (qemuMonitorTransactionBitmapMerge(actions, node, disk2->bitmap, &arr) < 0)
-                        return -1;
-                }
-            }
-
-            if (qemuMonitorTransactionBitmapRemove(actions, node, disk->bitmap) < 0)
-                return -1;
-        }
-
-        qemuDomainObjEnterMonitor(driver, vm);
-        rc = qemuMonitorTransaction(priv->mon, &actions);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+        if (qemuCheckpointDiscardBitmaps(vm, chkdef, chkcurrent, parent) < 0)
             return -1;
     }
 
-- 
2.25.0