]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemuDomainBlockCommit: Handle bitmaps on start of commit
authorPeter Krempa <pkrempa@redhat.com>
Tue, 3 Mar 2020 12:59:48 +0000 (13:59 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Mon, 16 Mar 2020 16:33:09 +0000 (17:33 +0100)
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>
src/qemu/qemu_driver.c

index 2799094fe6a8a307573081b8bb0489a52b6ea730..3d5633f1e9ca9856d1e4c67029dac975881135df 100644 (file)
@@ -18399,6 +18399,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 |
@@ -18555,8 +18557,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;
@@ -18578,6 +18601,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;
     }