d76c62
From e735d0f163806b34f9e65dacdf5e10b52c0478fd Mon Sep 17 00:00:00 2001
d76c62
Message-Id: <e735d0f163806b34f9e65dacdf5e10b52c0478fd@dist-git>
d76c62
From: Peter Krempa <pkrempa@redhat.com>
d76c62
Date: Mon, 16 Mar 2020 22:12:29 +0100
d76c62
Subject: [PATCH] qemuDomainBlockCommit: Handle bitmaps on start of commit
d76c62
MIME-Version: 1.0
d76c62
Content-Type: text/plain; charset=UTF-8
d76c62
Content-Transfer-Encoding: 8bit
d76c62
d76c62
On start of the commit job, we need to disable any active bitmap in the
d76c62
base. Use qemuBlockBitmapsHandleCommitStart to calculate which and call
d76c62
the appropriate QMP APIs. We use blockdev-reopen to make the 'base'
d76c62
writable to disable the bitmaps.
d76c62
d76c62
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
d76c62
Reviewed-by: Eric Blake <eblake@redhat.com>
d76c62
(cherry picked from commit 2b9091f089279a7bac523095a2ccd146fa20800b)
d76c62
https://bugzilla.redhat.com/show_bug.cgi?id=1799013
d76c62
Message-Id: <2aca5706f8412d27ff38da69582c522aca058054.1584391727.git.pkrempa@redhat.com>
d76c62
Reviewed-by: Ján Tomko <jtomko@redhat.com>
d76c62
---
d76c62
 src/qemu/qemu_driver.c | 43 +++++++++++++++++++++++++++++++++++++++++-
d76c62
 1 file changed, 42 insertions(+), 1 deletion(-)
d76c62
d76c62
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
d76c62
index 5c2b3cddf1..2f8fee2ef0 100644
d76c62
--- a/src/qemu/qemu_driver.c
d76c62
+++ b/src/qemu/qemu_driver.c
d76c62
@@ -18724,6 +18724,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
d76c62
     const char *nodebase = NULL;
d76c62
     bool persistjob = false;
d76c62
     bool blockdev = false;
d76c62
+    g_autoptr(virJSONValue) bitmapDisableActions = NULL;
d76c62
+    VIR_AUTOSTRINGLIST bitmapDisableList = NULL;
d76c62
 
d76c62
     virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW |
d76c62
                   VIR_DOMAIN_BLOCK_COMMIT_ACTIVE |
d76c62
@@ -18880,8 +18882,29 @@ qemuDomainBlockCommit(virDomainPtr dom,
d76c62
             goto endjob;
d76c62
     }
d76c62
 
d76c62
+    if (blockdev &&
d76c62
+        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
d76c62
+        g_autoptr(virHashTable) blockNamedNodeData = NULL;
d76c62
+        if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
d76c62
+            goto endjob;
d76c62
+
d76c62
+        if (qemuBlockBitmapsHandleCommitStart(topSource, baseSource,
d76c62
+                                              blockNamedNodeData,
d76c62
+                                              &bitmapDisableActions,
d76c62
+                                              &bitmapDisableList) < 0)
d76c62
+            goto endjob;
d76c62
+
d76c62
+        /* if we don't have terminator on 'base' we can't reopen it */
d76c62
+        if (bitmapDisableActions && !baseSource->backingStore) {
d76c62
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
d76c62
+                           _("can't handle bitmaps on unterminated backing image '%s'"),
d76c62
+                           base);
d76c62
+            goto endjob;
d76c62
+        }
d76c62
+    }
d76c62
+
d76c62
     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
d76c62
-                                          baseSource, NULL,
d76c62
+                                          baseSource, &bitmapDisableList,
d76c62
                                           flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
d76c62
                                           flags)))
d76c62
         goto endjob;
d76c62
@@ -18903,6 +18926,24 @@ qemuDomainBlockCommit(virDomainPtr dom,
d76c62
         if (!backingPath && top_parent &&
d76c62
             !(backingPath = qemuBlockGetBackingStoreString(baseSource)))
d76c62
             goto endjob;
d76c62
+
d76c62
+        if (bitmapDisableActions) {
d76c62
+            int rc;
d76c62
+
d76c62
+            if (qemuBlockReopenReadWrite(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
d76c62
+                goto endjob;
d76c62
+
d76c62
+            qemuDomainObjEnterMonitor(driver, vm);
d76c62
+            rc = qemuMonitorTransaction(priv->mon, &bitmapDisableActions);
d76c62
+            if (qemuDomainObjExitMonitor(driver, vm) < 0)
d76c62
+                goto endjob;
d76c62
+
d76c62
+            if (qemuBlockReopenReadOnly(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
d76c62
+                goto endjob;
d76c62
+
d76c62
+            if (rc < 0)
d76c62
+                goto endjob;
d76c62
+        }
d76c62
     } else {
d76c62
         device = job->name;
d76c62
     }
d76c62
-- 
d76c62
2.25.1
d76c62