Blob Blame History Raw
From e735d0f163806b34f9e65dacdf5e10b52c0478fd Mon Sep 17 00:00:00 2001
Message-Id: <e735d0f163806b34f9e65dacdf5e10b52c0478fd@dist-git>
From: Peter Krempa <pkrempa@redhat.com>
Date: Mon, 16 Mar 2020 22:12:29 +0100
Subject: [PATCH] qemuDomainBlockCommit: Handle bitmaps on start of commit
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

On start of the commit job, we need to disable any active bitmap in the
base. Use qemuBlockBitmapsHandleCommitStart to calculate which and call
the appropriate QMP APIs. We use blockdev-reopen to make the 'base'
writable to disable the bitmaps.

Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
(cherry picked from commit 2b9091f089279a7bac523095a2ccd146fa20800b)
https://bugzilla.redhat.com/show_bug.cgi?id=1799013
Message-Id: <2aca5706f8412d27ff38da69582c522aca058054.1584391727.git.pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
---
 src/qemu/qemu_driver.c | 43 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5c2b3cddf1..2f8fee2ef0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18724,6 +18724,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
     const char *nodebase = NULL;
     bool persistjob = false;
     bool blockdev = false;
+    g_autoptr(virJSONValue) bitmapDisableActions = NULL;
+    VIR_AUTOSTRINGLIST bitmapDisableList = NULL;
 
     virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW |
                   VIR_DOMAIN_BLOCK_COMMIT_ACTIVE |
@@ -18880,8 +18882,29 @@ qemuDomainBlockCommit(virDomainPtr dom,
             goto endjob;
     }
 
+    if (blockdev &&
+        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
+        g_autoptr(virHashTable) blockNamedNodeData = NULL;
+        if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
+            goto endjob;
+
+        if (qemuBlockBitmapsHandleCommitStart(topSource, baseSource,
+                                              blockNamedNodeData,
+                                              &bitmapDisableActions,
+                                              &bitmapDisableList) < 0)
+            goto endjob;
+
+        /* if we don't have terminator on 'base' we can't reopen it */
+        if (bitmapDisableActions && !baseSource->backingStore) {
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                           _("can't handle bitmaps on unterminated backing image '%s'"),
+                           base);
+            goto endjob;
+        }
+    }
+
     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
-                                          baseSource, NULL,
+                                          baseSource, &bitmapDisableList,
                                           flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
                                           flags)))
         goto endjob;
@@ -18903,6 +18926,24 @@ qemuDomainBlockCommit(virDomainPtr dom,
         if (!backingPath && top_parent &&
             !(backingPath = qemuBlockGetBackingStoreString(baseSource)))
             goto endjob;
+
+        if (bitmapDisableActions) {
+            int rc;
+
+            if (qemuBlockReopenReadWrite(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
+                goto endjob;
+
+            qemuDomainObjEnterMonitor(driver, vm);
+            rc = qemuMonitorTransaction(priv->mon, &bitmapDisableActions);
+            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+                goto endjob;
+
+            if (qemuBlockReopenReadOnly(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
+                goto endjob;
+
+            if (rc < 0)
+                goto endjob;
+        }
     } else {
         device = job->name;
     }
-- 
2.25.1