32a3ac0fa9
- kvm-blockdev-reduce-aio_context-locked-sections-in-bitma.patch [bz#1756413] - kvm-qapi-implement-block-dirty-bitmap-remove-transaction.patch [bz#1756413] - kvm-iotests-test-bitmap-moving-inside-254.patch [bz#1756413] - kvm-spapr-xive-skip-partially-initialized-vCPUs-in-prese.patch [bz#1754710] - kvm-nbd-Grab-aio-context-lock-in-more-places.patch [bz#1741094] - kvm-tests-Use-iothreads-during-iotest-223.patch [bz#1741094] - Resolves: bz#1741094 ([Upstream]Incremental backup: Qemu coredump when expose an active bitmap via pull mode(data plane enable)) - Resolves: bz#1754710 (qemu core dumped when hotpluging vcpus) - Resolves: bz#1756413 (backport support for transactionable block-dirty-bitmap-remove for incremental backup support)
275 lines
10 KiB
Diff
275 lines
10 KiB
Diff
From fd8ecebf0c0632e473bcb8bb08dc8311a5530dcf Mon Sep 17 00:00:00 2001
|
|
From: John Snow <jsnow@redhat.com>
|
|
Date: Fri, 27 Sep 2019 20:18:45 +0100
|
|
Subject: [PATCH 2/6] qapi: implement block-dirty-bitmap-remove transaction
|
|
action
|
|
|
|
RH-Author: John Snow <jsnow@redhat.com>
|
|
Message-id: <20190927201846.6823-3-jsnow@redhat.com>
|
|
Patchwork-id: 90911
|
|
O-Subject: [RHEL-AV-8.1.0 qemu-kvm PATCH 2/3] qapi: implement block-dirty-bitmap-remove transaction action
|
|
Bugzilla: 1756413
|
|
RH-Acked-by: Maxim Levitsky <mlevitsk@redhat.com>
|
|
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
RH-Acked-by: Stefano Garzarella <sgarzare@redhat.com>
|
|
|
|
It is used to do transactional movement of the bitmap (which is
|
|
possible in conjunction with merge command). Transactional bitmap
|
|
movement is needed in scenarios with external snapshot, when we don't
|
|
want to leave copy of the bitmap in the base image.
|
|
|
|
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
|
Message-id: 20190708220502.12977-3-jsnow@redhat.com
|
|
[Edited "since" version to 4.2 --js]
|
|
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
(cherry picked from commit c4e4b0fa598ddc9cee6ba7a06899ce0a8dae6c61)
|
|
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
|
|
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
---
|
|
block.c | 2 +-
|
|
block/dirty-bitmap.c | 15 ++++----
|
|
blockdev.c | 79 ++++++++++++++++++++++++++++++++++++++----
|
|
include/block/dirty-bitmap.h | 2 +-
|
|
migration/block-dirty-bitmap.c | 2 +-
|
|
qapi/transaction.json | 2 ++
|
|
6 files changed, 85 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/block.c b/block.c
|
|
index cbd8da5..92a3e9f 100644
|
|
--- a/block.c
|
|
+++ b/block.c
|
|
@@ -5334,7 +5334,7 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
|
|
for (bm = bdrv_dirty_bitmap_next(bs, NULL); bm;
|
|
bm = bdrv_dirty_bitmap_next(bs, bm))
|
|
{
|
|
- bdrv_dirty_bitmap_set_migration(bm, false);
|
|
+ bdrv_dirty_bitmap_skip_store(bm, false);
|
|
}
|
|
|
|
ret = refresh_total_sectors(bs, bs->total_sectors);
|
|
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
|
|
index 95a9c2a..a308e1f 100644
|
|
--- a/block/dirty-bitmap.c
|
|
+++ b/block/dirty-bitmap.c
|
|
@@ -48,10 +48,9 @@ struct BdrvDirtyBitmap {
|
|
bool inconsistent; /* bitmap is persistent, but inconsistent.
|
|
It cannot be used at all in any way, except
|
|
a QMP user can remove it. */
|
|
- bool migration; /* Bitmap is selected for migration, it should
|
|
- not be stored on the next inactivation
|
|
- (persistent flag doesn't matter until next
|
|
- invalidation).*/
|
|
+ bool skip_store; /* We are either migrating or deleting this
|
|
+ * bitmap; it should not be stored on the next
|
|
+ * inactivation. */
|
|
QLIST_ENTRY(BdrvDirtyBitmap) list;
|
|
};
|
|
|
|
@@ -757,16 +756,16 @@ void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap)
|
|
}
|
|
|
|
/* Called with BQL taken. */
|
|
-void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration)
|
|
+void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip)
|
|
{
|
|
qemu_mutex_lock(bitmap->mutex);
|
|
- bitmap->migration = migration;
|
|
+ bitmap->skip_store = skip;
|
|
qemu_mutex_unlock(bitmap->mutex);
|
|
}
|
|
|
|
bool bdrv_dirty_bitmap_get_persistence(BdrvDirtyBitmap *bitmap)
|
|
{
|
|
- return bitmap->persistent && !bitmap->migration;
|
|
+ return bitmap->persistent && !bitmap->skip_store;
|
|
}
|
|
|
|
bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap)
|
|
@@ -778,7 +777,7 @@ bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs)
|
|
{
|
|
BdrvDirtyBitmap *bm;
|
|
QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) {
|
|
- if (bm->persistent && !bm->readonly && !bm->migration) {
|
|
+ if (bm->persistent && !bm->readonly && !bm->skip_store) {
|
|
return true;
|
|
}
|
|
}
|
|
diff --git a/blockdev.c b/blockdev.c
|
|
index 0124825..800b3dc 100644
|
|
--- a/blockdev.c
|
|
+++ b/blockdev.c
|
|
@@ -2134,6 +2134,51 @@ static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
|
|
errp);
|
|
}
|
|
|
|
+static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
|
|
+ const char *node, const char *name, bool release,
|
|
+ BlockDriverState **bitmap_bs, Error **errp);
|
|
+
|
|
+static void block_dirty_bitmap_remove_prepare(BlkActionState *common,
|
|
+ Error **errp)
|
|
+{
|
|
+ BlockDirtyBitmap *action;
|
|
+ BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
|
|
+ common, common);
|
|
+
|
|
+ if (action_check_completion_mode(common, errp) < 0) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ action = common->action->u.block_dirty_bitmap_remove.data;
|
|
+
|
|
+ state->bitmap = do_block_dirty_bitmap_remove(action->node, action->name,
|
|
+ false, &state->bs, errp);
|
|
+ if (state->bitmap) {
|
|
+ bdrv_dirty_bitmap_skip_store(state->bitmap, true);
|
|
+ bdrv_dirty_bitmap_set_busy(state->bitmap, true);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void block_dirty_bitmap_remove_abort(BlkActionState *common)
|
|
+{
|
|
+ BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
|
|
+ common, common);
|
|
+
|
|
+ if (state->bitmap) {
|
|
+ bdrv_dirty_bitmap_skip_store(state->bitmap, false);
|
|
+ bdrv_dirty_bitmap_set_busy(state->bitmap, false);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void block_dirty_bitmap_remove_commit(BlkActionState *common)
|
|
+{
|
|
+ BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
|
|
+ common, common);
|
|
+
|
|
+ bdrv_dirty_bitmap_set_busy(state->bitmap, false);
|
|
+ bdrv_release_dirty_bitmap(state->bs, state->bitmap);
|
|
+}
|
|
+
|
|
static void abort_prepare(BlkActionState *common, Error **errp)
|
|
{
|
|
error_setg(errp, "Transaction aborted using Abort action");
|
|
@@ -2211,6 +2256,12 @@ static const BlkActionOps actions[] = {
|
|
.commit = block_dirty_bitmap_free_backup,
|
|
.abort = block_dirty_bitmap_restore,
|
|
},
|
|
+ [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_REMOVE] = {
|
|
+ .instance_size = sizeof(BlockDirtyBitmapState),
|
|
+ .prepare = block_dirty_bitmap_remove_prepare,
|
|
+ .commit = block_dirty_bitmap_remove_commit,
|
|
+ .abort = block_dirty_bitmap_remove_abort,
|
|
+ },
|
|
/* Where are transactions for MIRROR, COMMIT and STREAM?
|
|
* Although these blockjobs use transaction callbacks like the backup job,
|
|
* these jobs do not necessarily adhere to transaction semantics.
|
|
@@ -2869,20 +2920,21 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name,
|
|
bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
|
|
}
|
|
|
|
-void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
|
|
- Error **errp)
|
|
+static BdrvDirtyBitmap *do_block_dirty_bitmap_remove(
|
|
+ const char *node, const char *name, bool release,
|
|
+ BlockDriverState **bitmap_bs, Error **errp)
|
|
{
|
|
BlockDriverState *bs;
|
|
BdrvDirtyBitmap *bitmap;
|
|
|
|
bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
|
|
if (!bitmap || !bs) {
|
|
- return;
|
|
+ return NULL;
|
|
}
|
|
|
|
if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO,
|
|
errp)) {
|
|
- return;
|
|
+ return NULL;
|
|
}
|
|
|
|
if (bdrv_dirty_bitmap_get_persistence(bitmap)) {
|
|
@@ -2892,13 +2944,28 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
|
|
aio_context_acquire(aio_context);
|
|
bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err);
|
|
aio_context_release(aio_context);
|
|
+
|
|
if (local_err != NULL) {
|
|
error_propagate(errp, local_err);
|
|
- return;
|
|
+ return NULL;
|
|
}
|
|
}
|
|
|
|
- bdrv_release_dirty_bitmap(bs, bitmap);
|
|
+ if (release) {
|
|
+ bdrv_release_dirty_bitmap(bs, bitmap);
|
|
+ }
|
|
+
|
|
+ if (bitmap_bs) {
|
|
+ *bitmap_bs = bs;
|
|
+ }
|
|
+
|
|
+ return release ? NULL : bitmap;
|
|
+}
|
|
+
|
|
+void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
|
|
+ Error **errp)
|
|
+{
|
|
+ do_block_dirty_bitmap_remove(node, name, true, NULL, errp);
|
|
}
|
|
|
|
/**
|
|
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
|
|
index 62682eb..a21d54a 100644
|
|
--- a/include/block/dirty-bitmap.h
|
|
+++ b/include/block/dirty-bitmap.h
|
|
@@ -83,7 +83,7 @@ void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap);
|
|
void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy);
|
|
void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src,
|
|
HBitmap **backup, Error **errp);
|
|
-void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration);
|
|
+void bdrv_dirty_bitmap_skip_store(BdrvDirtyBitmap *bitmap, bool skip);
|
|
|
|
/* Functions that require manual locking. */
|
|
void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap);
|
|
diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c
|
|
index 4a896a0..d650ba4 100644
|
|
--- a/migration/block-dirty-bitmap.c
|
|
+++ b/migration/block-dirty-bitmap.c
|
|
@@ -326,7 +326,7 @@ static int init_dirty_bitmap_migration(void)
|
|
|
|
/* unset migration flags here, to not roll back it */
|
|
QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
|
|
- bdrv_dirty_bitmap_set_migration(dbms->bitmap, true);
|
|
+ bdrv_dirty_bitmap_skip_store(dbms->bitmap, true);
|
|
}
|
|
|
|
if (QSIMPLEQ_EMPTY(&dirty_bitmap_mig_state.dbms_list)) {
|
|
diff --git a/qapi/transaction.json b/qapi/transaction.json
|
|
index 95edb78..0590dbc 100644
|
|
--- a/qapi/transaction.json
|
|
+++ b/qapi/transaction.json
|
|
@@ -45,6 +45,7 @@
|
|
#
|
|
# - @abort: since 1.6
|
|
# - @block-dirty-bitmap-add: since 2.5
|
|
+# - @block-dirty-bitmap-remove: since 4.2
|
|
# - @block-dirty-bitmap-clear: since 2.5
|
|
# - @block-dirty-bitmap-enable: since 4.0
|
|
# - @block-dirty-bitmap-disable: since 4.0
|
|
@@ -61,6 +62,7 @@
|
|
'data': {
|
|
'abort': 'Abort',
|
|
'block-dirty-bitmap-add': 'BlockDirtyBitmapAdd',
|
|
+ 'block-dirty-bitmap-remove': 'BlockDirtyBitmap',
|
|
'block-dirty-bitmap-clear': 'BlockDirtyBitmap',
|
|
'block-dirty-bitmap-enable': 'BlockDirtyBitmap',
|
|
'block-dirty-bitmap-disable': 'BlockDirtyBitmap',
|
|
--
|
|
1.8.3.1
|
|
|