b971b8
From ae0be0a7cbfb291c640b25d31013f938745e8c08 Mon Sep 17 00:00:00 2001
b971b8
Message-Id: <ae0be0a7cbfb291c640b25d31013f938745e8c08@dist-git>
b971b8
From: Peter Krempa <pkrempa@redhat.com>
b971b8
Date: Tue, 23 Jun 2020 12:24:00 +0200
b971b8
Subject: [PATCH] qemu: Rewrite bitmap handling for block commit
b971b8
MIME-Version: 1.0
b971b8
Content-Type: text/plain; charset=UTF-8
b971b8
Content-Transfer-Encoding: 8bit
b971b8
b971b8
Reuse qemuBlockGetBitmapMergeActions which allows removing the ad-hoc
b971b8
implementation of bitmap merging for block commit. The new approach is
b971b8
way simpler and more robust and also allows us to get rid of the
b971b8
disabling of bitmaps done prior to the start as we actually do want to
b971b8
update the bitmaps in the base.
b971b8
b971b8
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
b971b8
Reviewed-by: Eric Blake <eblake@redhat.com>
b971b8
(cherry picked from commit 20a7abc2d2d8a378103abf105fa0c617218ec023)
b971b8
https://bugzilla.redhat.com/show_bug.cgi?id=1804593
b971b8
Message-Id: <2b1054dbe576d3984c960a42d175edbafa92565a.1592906423.git.pkrempa@redhat.com>
b971b8
Reviewed-by: Ján Tomko <jtomko@redhat.com>
b971b8
---
b971b8
 src/qemu/qemu_block.c                         | 203 +-----------------
b971b8
 src/qemu/qemu_block.h                         |  11 +-
b971b8
 src/qemu/qemu_blockjob.c                      |  25 ++-
b971b8
 src/qemu/qemu_driver.c                        |  56 +----
b971b8
 tests/qemublocktest.c                         |  18 +-
b971b8
 .../qemublocktestdata/bitmapblockcommit/empty |   1 -
b971b8
 6 files changed, 42 insertions(+), 272 deletions(-)
b971b8
b971b8
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
b971b8
index b2296c2b4c..ff9e000461 100644
b971b8
--- a/src/qemu/qemu_block.c
b971b8
+++ b/src/qemu/qemu_block.c
b971b8
@@ -3194,117 +3194,7 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
b971b8
 /**
b971b8
  * @topsrc: virStorageSource representing 'top' of the job
b971b8
  * @basesrc: virStorageSource representing 'base' of the job
b971b8
- * @blockNamedNodeData: hash table containing data about bitmaps
b971b8
- * @actions: filled with arguments for a 'transaction' command
b971b8
- * @disabledBitmapsBase: filled with a list of bitmap names which must be disabled
b971b8
- *
b971b8
- * Prepares data for correctly handling bitmaps during the start of a commit
b971b8
- * job. The bitmaps in the 'base' image must be disabled, so that the writes
b971b8
- * done by the blockjob don't dirty the enabled bitmaps.
b971b8
- *
b971b8
- * @actions and @disabledBitmapsBase are untouched if no bitmaps need
b971b8
- * to be disabled.
b971b8
- */
b971b8
-int
b971b8
-qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc,
b971b8
-                                  virStorageSourcePtr basesrc,
b971b8
-                                  virHashTablePtr blockNamedNodeData,
b971b8
-                                  virJSONValuePtr *actions,
b971b8
-                                  char ***disabledBitmapsBase)
b971b8
-{
b971b8
-    g_autoptr(virJSONValue) act = virJSONValueNewArray();
b971b8
-    VIR_AUTOSTRINGLIST bitmaplist = NULL;
b971b8
-    size_t curbitmapstr = 0;
b971b8
-    qemuBlockNamedNodeDataPtr entry;
b971b8
-    bool disable_bitmaps = false;
b971b8
-    size_t i;
b971b8
-
b971b8
-    if (!(entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat)))
b971b8
-        return 0;
b971b8
-
b971b8
-    bitmaplist = g_new0(char *, entry->nbitmaps + 1);
b971b8
-
b971b8
-    for (i = 0; i < entry->nbitmaps; i++) {
b971b8
-        qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
b971b8
-
b971b8
-        if (!bitmap->recording || bitmap->inconsistent ||
b971b8
-            !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData))
b971b8
-            continue;
b971b8
-
b971b8
-        disable_bitmaps = true;
b971b8
-
b971b8
-        if (qemuMonitorTransactionBitmapDisable(act, basesrc->nodeformat,
b971b8
-                                                bitmap->name) < 0)
b971b8
-            return -1;
b971b8
-
b971b8
-        bitmaplist[curbitmapstr++] = g_strdup(bitmap->name);
b971b8
-    }
b971b8
-
b971b8
-    if (disable_bitmaps) {
b971b8
-        *actions = g_steal_pointer(&act;;
b971b8
-        *disabledBitmapsBase = g_steal_pointer(&bitmaplist);
b971b8
-    }
b971b8
-
b971b8
-    return 0;
b971b8
-}
b971b8
-
b971b8
-
b971b8
-struct qemuBlockBitmapsHandleCommitData {
b971b8
-    bool skip;
b971b8
-    bool create;
b971b8
-    bool enable;
b971b8
-    const char *basenode;
b971b8
-    virJSONValuePtr merge;
b971b8
-    unsigned long long granularity;
b971b8
-    bool persistent;
b971b8
-};
b971b8
-
b971b8
-
b971b8
-static void
b971b8
-qemuBlockBitmapsHandleCommitDataFree(void *opaque)
b971b8
-{
b971b8
-    struct qemuBlockBitmapsHandleCommitData *data = opaque;
b971b8
-
b971b8
-    virJSONValueFree(data->merge);
b971b8
-    g_free(data);
b971b8
-}
b971b8
-
b971b8
-
b971b8
-static int
b971b8
-qemuBlockBitmapsHandleCommitFinishIterate(void *payload,
b971b8
-                                          const void *entryname,
b971b8
-                                          void *opaque)
b971b8
-{
b971b8
-    struct qemuBlockBitmapsHandleCommitData *data = payload;
b971b8
-    const char *bitmapname = entryname;
b971b8
-    virJSONValuePtr actions = opaque;
b971b8
-
b971b8
-    if (data->skip)
b971b8
-        return 0;
b971b8
-
b971b8
-    if (data->create) {
b971b8
-        if (qemuMonitorTransactionBitmapAdd(actions, data->basenode, bitmapname,
b971b8
-                                            data->persistent, !data->enable,
b971b8
-                                            data->granularity) < 0)
b971b8
-            return -1;
b971b8
-    } else {
b971b8
-        if (data->enable &&
b971b8
-            qemuMonitorTransactionBitmapEnable(actions, data->basenode, bitmapname) < 0)
b971b8
-            return -1;
b971b8
-    }
b971b8
-
b971b8
-    if (data->merge &&
b971b8
-        qemuMonitorTransactionBitmapMerge(actions, data->basenode, bitmapname,
b971b8
-                                          &data->merge) < 0)
b971b8
-        return -1;
b971b8
-
b971b8
-    return 0;
b971b8
-}
b971b8
-
b971b8
-
b971b8
-/**
b971b8
- * @topsrc: virStorageSource representing 'top' of the job
b971b8
- * @basesrc: virStorageSource representing 'base' of the job
b971b8
+ * @active: commit job is an active layer block-commit
b971b8
  * @blockNamedNodeData: hash table containing data about bitmaps
b971b8
  * @actions: filled with arguments for a 'transaction' command
b971b8
  * @disabledBitmapsBase: bitmap names which were disabled
b971b8
@@ -3317,95 +3207,20 @@ qemuBlockBitmapsHandleCommitFinishIterate(void *payload,
b971b8
 int
b971b8
 qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc,
b971b8
                                    virStorageSourcePtr basesrc,
b971b8
+                                   bool active,
b971b8
                                    virHashTablePtr blockNamedNodeData,
b971b8
-                                   virJSONValuePtr *actions,
b971b8
-                                   char **disabledBitmapsBase)
b971b8
+                                   virJSONValuePtr *actions)
b971b8
 {
b971b8
-    g_autoptr(virJSONValue) act = virJSONValueNewArray();
b971b8
-    virStorageSourcePtr n;
b971b8
-    qemuBlockNamedNodeDataPtr entry;
b971b8
-    g_autoptr(virHashTable) commitdata = NULL;
b971b8
-    struct qemuBlockBitmapsHandleCommitData *bitmapdata;
b971b8
-    size_t i;
b971b8
-
b971b8
-    commitdata = virHashNew(qemuBlockBitmapsHandleCommitDataFree);
b971b8
-
b971b8
-    for (n = topsrc; n != basesrc; n = n->backingStore) {
b971b8
-        if (!(entry = virHashLookup(blockNamedNodeData, n->nodeformat)))
b971b8
-            continue;
b971b8
-
b971b8
-        for (i = 0; i < entry->nbitmaps; i++) {
b971b8
-            qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
b971b8
-
b971b8
-            if (!(bitmapdata = virHashLookup(commitdata, bitmap->name))) {
b971b8
-                bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1);
b971b8
+    virStorageSourcePtr writebitmapsrc = NULL;
b971b8
 
b971b8
-                /* we must mirror the state of the topmost bitmap and merge
b971b8
-                 * everything else */
b971b8
-                bitmapdata->create = true;
b971b8
-                bitmapdata->enable = bitmap->recording;
b971b8
-                bitmapdata->basenode = basesrc->nodeformat;
b971b8
-                bitmapdata->merge = virJSONValueNewArray();
b971b8
-                bitmapdata->granularity = bitmap->granularity;
b971b8
-                bitmapdata->persistent = bitmap->persistent;
b971b8
+    if (active)
b971b8
+        writebitmapsrc = basesrc;
b971b8
 
b971b8
-                if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) < 0) {
b971b8
-                    qemuBlockBitmapsHandleCommitDataFree(bitmapdata);
b971b8
-                    return -1;
b971b8
-                }
b971b8
-            }
b971b8
-
b971b8
-            if (bitmap->inconsistent ||
b971b8
-                !qemuBlockBitmapChainIsValid(topsrc, bitmap->name, blockNamedNodeData))
b971b8
-                bitmapdata->skip = true;
b971b8
-
b971b8
-            if (qemuMonitorTransactionBitmapMergeSourceAddBitmap(bitmapdata->merge,
b971b8
-                                                                 n->nodeformat,
b971b8
-                                                                 bitmap->name) < 0)
b971b8
-                return -1;
b971b8
-        }
b971b8
-    }
b971b8
-
b971b8
-    if ((entry = virHashLookup(blockNamedNodeData, basesrc->nodeformat))) {
b971b8
-        /* note that all bitmaps in 'base' were disabled when commit was started */
b971b8
-        for (i = 0; i < entry->nbitmaps; i++) {
b971b8
-            qemuBlockNamedNodeDataBitmapPtr bitmap = entry->bitmaps[i];
b971b8
-
b971b8
-            if ((bitmapdata = virHashLookup(commitdata, bitmap->name))) {
b971b8
-                bitmapdata->create = false;
b971b8
-            } else {
b971b8
-                if (disabledBitmapsBase) {
b971b8
-                    char **disabledbitmaps;
b971b8
-
b971b8
-                    for (disabledbitmaps = disabledBitmapsBase; *disabledbitmaps; disabledbitmaps++) {
b971b8
-                        if (STREQ(*disabledbitmaps, bitmap->name)) {
b971b8
-                            bitmapdata = g_new0(struct qemuBlockBitmapsHandleCommitData, 1);
b971b8
-
b971b8
-                            bitmapdata->create = false;
b971b8
-                            bitmapdata->enable = true;
b971b8
-                            bitmapdata->basenode = basesrc->nodeformat;
b971b8
-                            bitmapdata->granularity = bitmap->granularity;
b971b8
-                            bitmapdata->persistent = bitmap->persistent;
b971b8
-
b971b8
-                            if (virHashAddEntry(commitdata, bitmap->name, bitmapdata) < 0) {
b971b8
-                                qemuBlockBitmapsHandleCommitDataFree(bitmapdata);
b971b8
-                                return -1;
b971b8
-                            }
b971b8
-
b971b8
-                            break;
b971b8
-                        }
b971b8
-                    }
b971b8
-                }
b971b8
-            }
b971b8
-        }
b971b8
-    }
b971b8
-
b971b8
-    if (virHashForEach(commitdata, qemuBlockBitmapsHandleCommitFinishIterate, act) < 0)
b971b8
+    if (qemuBlockGetBitmapMergeActions(topsrc, basesrc, basesrc, NULL, NULL,
b971b8
+                                       writebitmapsrc, actions,
b971b8
+                                       blockNamedNodeData) < 0)
b971b8
         return -1;
b971b8
 
b971b8
-    if (virJSONValueArraySize(act) > 0)
b971b8
-        *actions = g_steal_pointer(&act;;
b971b8
-
b971b8
     return 0;
b971b8
 }
b971b8
 
b971b8
diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h
b971b8
index 2500390734..19d2fc32e0 100644
b971b8
--- a/src/qemu/qemu_block.h
b971b8
+++ b/src/qemu/qemu_block.h
b971b8
@@ -243,19 +243,12 @@ qemuBlockBitmapsHandleBlockcopy(virStorageSourcePtr src,
b971b8
                                 bool shallow,
b971b8
                                 virJSONValuePtr *actions);
b971b8
 
b971b8
-int
b971b8
-qemuBlockBitmapsHandleCommitStart(virStorageSourcePtr topsrc,
b971b8
-                                  virStorageSourcePtr basesrc,
b971b8
-                                  virHashTablePtr blockNamedNodeData,
b971b8
-                                  virJSONValuePtr *actions,
b971b8
-                                  char ***disabledBitmapsBase);
b971b8
-
b971b8
 int
b971b8
 qemuBlockBitmapsHandleCommitFinish(virStorageSourcePtr topsrc,
b971b8
                                    virStorageSourcePtr basesrc,
b971b8
+                                   bool active,
b971b8
                                    virHashTablePtr blockNamedNodeData,
b971b8
-                                   virJSONValuePtr *actions,
b971b8
-                                   char **disabledBitmapsBase);
b971b8
+                                   virJSONValuePtr *actions);
b971b8
 
b971b8
 int
b971b8
 qemuBlockReopenReadWrite(virDomainObjPtr vm,
b971b8
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
b971b8
index c80c71295b..c63a691a0e 100644
b971b8
--- a/src/qemu/qemu_blockjob.c
b971b8
+++ b/src/qemu/qemu_blockjob.c
b971b8
@@ -1063,6 +1063,7 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm,
b971b8
     qemuDomainObjPrivatePtr priv = vm->privateData;
b971b8
     g_autoptr(virHashTable) blockNamedNodeData = NULL;
b971b8
     g_autoptr(virJSONValue) actions = NULL;
b971b8
+    bool active = job->type == QEMU_BLOCKJOB_TYPE_ACTIVE_COMMIT;
b971b8
 
b971b8
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN))
b971b8
         return 0;
b971b8
@@ -1072,16 +1073,18 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm,
b971b8
 
b971b8
     if (qemuBlockBitmapsHandleCommitFinish(job->data.commit.top,
b971b8
                                            job->data.commit.base,
b971b8
+                                           active,
b971b8
                                            blockNamedNodeData,
b971b8
-                                           &actions,
b971b8
-                                           job->data.commit.disabledBitmapsBase) < 0)
b971b8
+                                           &actions) < 0)
b971b8
         return 0;
b971b8
 
b971b8
     if (!actions)
b971b8
         return 0;
b971b8
 
b971b8
-    if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0)
b971b8
-        return -1;
b971b8
+    if (!active) {
b971b8
+        if (qemuBlockReopenReadWrite(vm, job->data.commit.base, asyncJob) < 0)
b971b8
+            return -1;
b971b8
+    }
b971b8
 
b971b8
     if (qemuDomainObjEnterMonitorAsync(priv->driver, vm, asyncJob) < 0)
b971b8
         return -1;
b971b8
@@ -1091,8 +1094,10 @@ qemuBlockJobProcessEventCompletedCommitBitmaps(virDomainObjPtr vm,
b971b8
     if (qemuDomainObjExitMonitor(priv->driver, vm) < 0)
b971b8
         return -1;
b971b8
 
b971b8
-    if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0)
b971b8
-        return -1;
b971b8
+    if (!active) {
b971b8
+        if (qemuBlockReopenReadOnly(vm, job->data.commit.base, asyncJob) < 0)
b971b8
+            return -1;
b971b8
+    }
b971b8
 
b971b8
     return 0;
b971b8
 }
b971b8
@@ -1262,6 +1267,9 @@ qemuBlockJobProcessEventCompletedActiveCommit(virQEMUDriverPtr driver,
b971b8
     job->disk->src = job->data.commit.base;
b971b8
     job->disk->src->readonly = job->data.commit.top->readonly;
b971b8
 
b971b8
+    if (qemuBlockJobProcessEventCompletedCommitBitmaps(vm, job, asyncJob) < 0)
b971b8
+        return;
b971b8
+
b971b8
     qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job->data.commit.top);
b971b8
 
b971b8
     if (job->data.commit.deleteCommittedImages)
b971b8
@@ -1333,6 +1341,7 @@ qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver,
b971b8
                                            virDomainObjPtr vm,
b971b8
                                            qemuBlockJobDataPtr job)
b971b8
 {
b971b8
+    g_autoptr(virJSONValue) actions = virJSONValueNewArray();
b971b8
     virDomainDiskDefPtr disk = job->disk;
b971b8
 
b971b8
     VIR_DEBUG("active commit job '%s' on VM '%s' failed", job->name, vm->def->name);
b971b8
@@ -1340,6 +1349,10 @@ qemuBlockJobProcessEventFailedActiveCommit(virQEMUDriverPtr driver,
b971b8
     if (!disk)
b971b8
         return;
b971b8
 
b971b8
+    ignore_value(qemuMonitorTransactionBitmapRemove(actions, disk->mirror->nodeformat,
b971b8
+                                                    "libvirt-tmp-activewrite"));
b971b8
+
b971b8
+
b971b8
     /* Ideally, we would make the backing chain read only again (yes, SELinux
b971b8
      * can do that using different labels). But that is not implemented yet and
b971b8
      * not leaking security driver metadata is more important. */
b971b8
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
b971b8
index 9f7d96c0b6..983d4a04a8 100644
b971b8
--- a/src/qemu/qemu_driver.c
b971b8
+++ b/src/qemu/qemu_driver.c
b971b8
@@ -17594,9 +17594,9 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
b971b8
 
b971b8
     case QEMU_BLOCKJOB_TYPE_COPY:
b971b8
         if (blockdev && !job->jobflagsmissing) {
b971b8
-            g_autoptr(virHashTable) blockNamedNodeData = NULL;
b971b8
             bool shallow = job->jobflags & VIR_DOMAIN_BLOCK_COPY_SHALLOW;
b971b8
             bool reuse = job->jobflags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT;
b971b8
+            g_autoptr(virHashTable) blockNamedNodeData = NULL;
b971b8
 
b971b8
             if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
b971b8
                 return -1;
b971b8
@@ -17634,16 +17634,15 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
b971b8
          * the bitmaps if it wasn't present thus must skip this */
b971b8
         if (blockdev &&
b971b8
             virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
b971b8
-            g_autoptr(virHashTable) blockNamedNodeData = NULL;
b971b8
 
b971b8
-            if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
b971b8
-                return -1;
b971b8
+            actions = virJSONValueNewArray();
b971b8
 
b971b8
-            if (qemuBlockBitmapsHandleCommitFinish(job->data.commit.top,
b971b8
-                                                   job->data.commit.base,
b971b8
-                                                   blockNamedNodeData,
b971b8
-                                                   &actions,
b971b8
-                                                   job->data.commit.disabledBitmapsBase) < 0)
b971b8
+            if (qemuMonitorTransactionBitmapAdd(actions,
b971b8
+                                                job->data.commit.base->nodeformat,
b971b8
+                                                "libvirt-tmp-activewrite",
b971b8
+                                                false,
b971b8
+                                                false,
b971b8
+                                                0) < 0)
b971b8
                 return -1;
b971b8
         }
b971b8
 
b971b8
@@ -18758,7 +18757,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
b971b8
     const char *nodebase = NULL;
b971b8
     bool persistjob = false;
b971b8
     bool blockdev = false;
b971b8
-    g_autoptr(virJSONValue) bitmapDisableActions = NULL;
b971b8
     VIR_AUTOSTRINGLIST bitmapDisableList = NULL;
b971b8
 
b971b8
     virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW |
b971b8
@@ -18920,27 +18918,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
b971b8
             goto endjob;
b971b8
     }
b971b8
 
b971b8
-    if (blockdev &&
b971b8
-        virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV_REOPEN)) {
b971b8
-        g_autoptr(virHashTable) blockNamedNodeData = NULL;
b971b8
-        if (!(blockNamedNodeData = qemuBlockGetNamedNodeData(vm, QEMU_ASYNC_JOB_NONE)))
b971b8
-            goto endjob;
b971b8
-
b971b8
-        if (qemuBlockBitmapsHandleCommitStart(topSource, baseSource,
b971b8
-                                              blockNamedNodeData,
b971b8
-                                              &bitmapDisableActions,
b971b8
-                                              &bitmapDisableList) < 0)
b971b8
-            goto endjob;
b971b8
-
b971b8
-        /* if we don't have terminator on 'base' we can't reopen it */
b971b8
-        if (bitmapDisableActions && !baseSource->backingStore) {
b971b8
-            virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
b971b8
-                           _("can't handle bitmaps on unterminated backing image '%s'"),
b971b8
-                           base);
b971b8
-            goto endjob;
b971b8
-        }
b971b8
-    }
b971b8
-
b971b8
     if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
b971b8
                                           baseSource, &bitmapDisableList,
b971b8
                                           flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
b971b8
@@ -18965,23 +18942,6 @@ qemuDomainBlockCommit(virDomainPtr dom,
b971b8
             !(backingPath = qemuBlockGetBackingStoreString(baseSource, false)))
b971b8
             goto endjob;
b971b8
 
b971b8
-        if (bitmapDisableActions) {
b971b8
-            int rc;
b971b8
-
b971b8
-            if (qemuBlockReopenReadWrite(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
b971b8
-                goto endjob;
b971b8
-
b971b8
-            qemuDomainObjEnterMonitor(driver, vm);
b971b8
-            rc = qemuMonitorTransaction(priv->mon, &bitmapDisableActions);
b971b8
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
b971b8
-                goto endjob;
b971b8
-
b971b8
-            if (qemuBlockReopenReadOnly(vm, baseSource, QEMU_ASYNC_JOB_NONE) < 0)
b971b8
-                goto endjob;
b971b8
-
b971b8
-            if (rc < 0)
b971b8
-                goto endjob;
b971b8
-        }
b971b8
     } else {
b971b8
         device = job->name;
b971b8
     }
b971b8
diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c
b971b8
index 8ce878f15b..f0e80a0738 100644
b971b8
--- a/tests/qemublocktest.c
b971b8
+++ b/tests/qemublocktest.c
b971b8
@@ -928,12 +928,11 @@ testQemuBlockBitmapBlockcommit(const void *opaque)
b971b8
 
b971b8
     g_autofree char *actual = NULL;
b971b8
     g_autofree char *expectpath = NULL;
b971b8
-    g_autoptr(virJSONValue) actionsDisable = NULL;
b971b8
     g_autoptr(virJSONValue) actionsMerge = NULL;
b971b8
     g_autoptr(virJSONValue) nodedatajson = NULL;
b971b8
     g_autoptr(virHashTable) nodedata = NULL;
b971b8
     g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
b971b8
-    VIR_AUTOSTRINGLIST bitmapsDisable = NULL;
b971b8
+    bool active = data->top == data->chain;
b971b8
 
b971b8
     expectpath = g_strdup_printf("%s/%s%s", abs_srcdir,
b971b8
                                  blockcommitPrefix, data->name);
b971b8
@@ -947,20 +946,10 @@ testQemuBlockBitmapBlockcommit(const void *opaque)
b971b8
         return -1;
b971b8
     }
b971b8
 
b971b8
-    if (qemuBlockBitmapsHandleCommitStart(data->top, data->base, nodedata,
b971b8
-                                          &actionsDisable, &bitmapsDisable) < 0)
b971b8
-        return -1;
b971b8
-
b971b8
-    virBufferAddLit(&buf, "pre job bitmap disable:\n");
b971b8
-
b971b8
-    if (actionsDisable &&
b971b8
-        virJSONValueToBuffer(actionsDisable, &buf, true) < 0)
b971b8
-        return -1;
b971b8
-
b971b8
     virBufferAddLit(&buf, "merge bitmpas:\n");
b971b8
 
b971b8
-    if (qemuBlockBitmapsHandleCommitFinish(data->top, data->base, nodedata,
b971b8
-                                           &actionsMerge, bitmapsDisable) < 0)
b971b8
+    if (qemuBlockBitmapsHandleCommitFinish(data->top, data->base, active, nodedata,
b971b8
+                                           &actionsMerge) < 0)
b971b8
         return -1;
b971b8
 
b971b8
     if (actionsMerge &&
b971b8
@@ -1356,6 +1345,7 @@ mymain(void)
b971b8
 #define TEST_BITMAP_BLOCKCOMMIT(testname, topimg, baseimg, ndf) \
b971b8
     do {\
b971b8
         blockbitmapblockcommitdata.name = testname; \
b971b8
+        blockbitmapblockcommitdata.chain = bitmapSourceChain; \
b971b8
         blockbitmapblockcommitdata.top = testQemuBitmapGetFakeChainEntry(bitmapSourceChain, topimg); \
b971b8
         blockbitmapblockcommitdata.base = testQemuBitmapGetFakeChainEntry(bitmapSourceChain, baseimg); \
b971b8
         blockbitmapblockcommitdata.nodedatafile = ndf; \
b971b8
diff --git a/tests/qemublocktestdata/bitmapblockcommit/empty b/tests/qemublocktestdata/bitmapblockcommit/empty
b971b8
index bfc58f994e..9260011852 100644
b971b8
--- a/tests/qemublocktestdata/bitmapblockcommit/empty
b971b8
+++ b/tests/qemublocktestdata/bitmapblockcommit/empty
b971b8
@@ -1,2 +1 @@
b971b8
-pre job bitmap disable:
b971b8
 merge bitmpas:
b971b8
-- 
b971b8
2.27.0
b971b8