|
|
7711c0 |
From 80ea6f080180cd5aea1603405948d164442dd8d1 Mon Sep 17 00:00:00 2001
|
|
|
7711c0 |
From: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Date: Wed, 20 Mar 2019 16:16:16 +0100
|
|
|
7711c0 |
Subject: [PATCH 018/163] blockdev: n-ary bitmap merge
|
|
|
7711c0 |
|
|
|
7711c0 |
RH-Author: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Message-id: <20190320161631.14841-5-jsnow@redhat.com>
|
|
|
7711c0 |
Patchwork-id: 84948
|
|
|
7711c0 |
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 04/19] blockdev: n-ary bitmap merge
|
|
|
7711c0 |
Bugzilla: 1668956
|
|
|
7711c0 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
7711c0 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
|
|
|
7711c0 |
Especially outside of transactions, it is helpful to provide
|
|
|
7711c0 |
all-or-nothing semantics for bitmap merges. This facilitates
|
|
|
7711c0 |
the coalescing of multiple bitmaps into a single target for
|
|
|
7711c0 |
the "checkpoint" interpretation when assembling bitmaps that
|
|
|
7711c0 |
represent arbitrary points in time from component bitmaps.
|
|
|
7711c0 |
|
|
|
7711c0 |
This is an incompatible change from the preliminary version
|
|
|
7711c0 |
of the API.
|
|
|
7711c0 |
|
|
|
7711c0 |
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
7711c0 |
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
|
|
7711c0 |
Message-Id: <20181221093529.23855-4-jsnow@redhat.com>
|
|
|
7711c0 |
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
7711c0 |
(cherry picked from commit 360d4e4e9a501d92fb8866ac307d33a25f70c6d1)
|
|
|
7711c0 |
Signed-off-by: John Snow <jsnow@redhat.com>
|
|
|
7711c0 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
7711c0 |
---
|
|
|
7711c0 |
blockdev.c | 75 +++++++++++++++++++++++++++++++++++-----------------
|
|
|
7711c0 |
qapi/block-core.json | 22 +++++++--------
|
|
|
7711c0 |
2 files changed, 62 insertions(+), 35 deletions(-)
|
|
|
7711c0 |
|
|
|
7711c0 |
diff --git a/blockdev.c b/blockdev.c
|
|
|
7711c0 |
index c9bda43..3755936 100644
|
|
|
7711c0 |
--- a/blockdev.c
|
|
|
7711c0 |
+++ b/blockdev.c
|
|
|
7711c0 |
@@ -2272,33 +2272,28 @@ static void block_dirty_bitmap_disable_abort(BlkActionState *common)
|
|
|
7711c0 |
}
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
+static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
|
|
|
7711c0 |
+ const char *target,
|
|
|
7711c0 |
+ strList *bitmaps,
|
|
|
7711c0 |
+ HBitmap **backup,
|
|
|
7711c0 |
+ Error **errp);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
|
|
|
7711c0 |
Error **errp)
|
|
|
7711c0 |
{
|
|
|
7711c0 |
BlockDirtyBitmapMerge *action;
|
|
|
7711c0 |
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
|
|
|
7711c0 |
common, common);
|
|
|
7711c0 |
- BdrvDirtyBitmap *merge_source;
|
|
|
7711c0 |
|
|
|
7711c0 |
if (action_check_completion_mode(common, errp) < 0) {
|
|
|
7711c0 |
return;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
action = common->action->u.x_block_dirty_bitmap_merge.data;
|
|
|
7711c0 |
- state->bitmap = block_dirty_bitmap_lookup(action->node,
|
|
|
7711c0 |
- action->dst_name,
|
|
|
7711c0 |
- &state->bs,
|
|
|
7711c0 |
- errp);
|
|
|
7711c0 |
- if (!state->bitmap) {
|
|
|
7711c0 |
- return;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
|
|
|
7711c0 |
- merge_source = bdrv_find_dirty_bitmap(state->bs, action->src_name);
|
|
|
7711c0 |
- if (!merge_source) {
|
|
|
7711c0 |
- return;
|
|
|
7711c0 |
- }
|
|
|
7711c0 |
-
|
|
|
7711c0 |
- bdrv_merge_dirty_bitmap(state->bitmap, merge_source, &state->backup, errp);
|
|
|
7711c0 |
+ state->bitmap = do_block_dirty_bitmap_merge(action->node, action->target,
|
|
|
7711c0 |
+ action->bitmaps, &state->backup,
|
|
|
7711c0 |
+ errp);
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
static void abort_prepare(BlkActionState *common, Error **errp)
|
|
|
7711c0 |
@@ -3130,24 +3125,56 @@ void qmp_x_block_dirty_bitmap_disable(const char *node, const char *name,
|
|
|
7711c0 |
bdrv_disable_dirty_bitmap(bitmap);
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
-void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name,
|
|
|
7711c0 |
- const char *src_name, Error **errp)
|
|
|
7711c0 |
+static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
|
|
|
7711c0 |
+ const char *target,
|
|
|
7711c0 |
+ strList *bitmaps,
|
|
|
7711c0 |
+ HBitmap **backup,
|
|
|
7711c0 |
+ Error **errp)
|
|
|
7711c0 |
{
|
|
|
7711c0 |
BlockDriverState *bs;
|
|
|
7711c0 |
- BdrvDirtyBitmap *dst, *src;
|
|
|
7711c0 |
+ BdrvDirtyBitmap *dst, *src, *anon;
|
|
|
7711c0 |
+ strList *lst;
|
|
|
7711c0 |
+ Error *local_err = NULL;
|
|
|
7711c0 |
|
|
|
7711c0 |
- dst = block_dirty_bitmap_lookup(node, dst_name, &bs, errp);
|
|
|
7711c0 |
+ dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
|
|
|
7711c0 |
if (!dst) {
|
|
|
7711c0 |
- return;
|
|
|
7711c0 |
+ return NULL;
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
- src = bdrv_find_dirty_bitmap(bs, src_name);
|
|
|
7711c0 |
- if (!src) {
|
|
|
7711c0 |
- error_setg(errp, "Dirty bitmap '%s' not found", src_name);
|
|
|
7711c0 |
- return;
|
|
|
7711c0 |
+ anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
|
|
|
7711c0 |
+ NULL, errp);
|
|
|
7711c0 |
+ if (!anon) {
|
|
|
7711c0 |
+ return NULL;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ for (lst = bitmaps; lst; lst = lst->next) {
|
|
|
7711c0 |
+ src = bdrv_find_dirty_bitmap(bs, lst->value);
|
|
|
7711c0 |
+ if (!src) {
|
|
|
7711c0 |
+ error_setg(errp, "Dirty bitmap '%s' not found", lst->value);
|
|
|
7711c0 |
+ dst = NULL;
|
|
|
7711c0 |
+ goto out;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err);
|
|
|
7711c0 |
+ if (local_err) {
|
|
|
7711c0 |
+ error_propagate(errp, local_err);
|
|
|
7711c0 |
+ dst = NULL;
|
|
|
7711c0 |
+ goto out;
|
|
|
7711c0 |
+ }
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
- bdrv_merge_dirty_bitmap(dst, src, NULL, errp);
|
|
|
7711c0 |
+ /* Merge into dst; dst is unchanged on failure. */
|
|
|
7711c0 |
+ bdrv_merge_dirty_bitmap(dst, anon, backup, errp);
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+ out:
|
|
|
7711c0 |
+ bdrv_release_dirty_bitmap(bs, anon);
|
|
|
7711c0 |
+ return dst;
|
|
|
7711c0 |
+}
|
|
|
7711c0 |
+
|
|
|
7711c0 |
+void qmp_x_block_dirty_bitmap_merge(const char *node, const char *target,
|
|
|
7711c0 |
+ strList *bitmaps, Error **errp)
|
|
|
7711c0 |
+{
|
|
|
7711c0 |
+ do_block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
|
|
|
7711c0 |
}
|
|
|
7711c0 |
|
|
|
7711c0 |
BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
|
|
|
7711c0 |
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
|
|
7711c0 |
index 0960449..7e11392 100644
|
|
|
7711c0 |
--- a/qapi/block-core.json
|
|
|
7711c0 |
+++ b/qapi/block-core.json
|
|
|
7711c0 |
@@ -1801,14 +1801,14 @@
|
|
|
7711c0 |
#
|
|
|
7711c0 |
# @node: name of device/node which the bitmap is tracking
|
|
|
7711c0 |
#
|
|
|
7711c0 |
-# @dst_name: name of the destination dirty bitmap
|
|
|
7711c0 |
+# @target: name of the destination dirty bitmap
|
|
|
7711c0 |
#
|
|
|
7711c0 |
-# @src_name: name of the source dirty bitmap
|
|
|
7711c0 |
+# @bitmaps: name(s) of the source dirty bitmap(s)
|
|
|
7711c0 |
#
|
|
|
7711c0 |
# Since: 3.0
|
|
|
7711c0 |
##
|
|
|
7711c0 |
{ 'struct': 'BlockDirtyBitmapMerge',
|
|
|
7711c0 |
- 'data': { 'node': 'str', 'dst_name': 'str', 'src_name': 'str' } }
|
|
|
7711c0 |
+ 'data': { 'node': 'str', 'target': 'str', 'bitmaps': ['str'] } }
|
|
|
7711c0 |
|
|
|
7711c0 |
##
|
|
|
7711c0 |
# @block-dirty-bitmap-add:
|
|
|
7711c0 |
@@ -1923,23 +1923,23 @@
|
|
|
7711c0 |
##
|
|
|
7711c0 |
# @x-block-dirty-bitmap-merge:
|
|
|
7711c0 |
#
|
|
|
7711c0 |
-# FIXME: Rename @src_name and @dst_name to src-name and dst-name.
|
|
|
7711c0 |
-#
|
|
|
7711c0 |
-# Merge @src_name dirty bitmap to @dst_name dirty bitmap. @src_name dirty
|
|
|
7711c0 |
-# bitmap is unchanged. On error, @dst_name is unchanged.
|
|
|
7711c0 |
+# Merge dirty bitmaps listed in @bitmaps to the @target dirty bitmap.
|
|
|
7711c0 |
+# The @bitmaps dirty bitmaps are unchanged.
|
|
|
7711c0 |
+# On error, @target is unchanged.
|
|
|
7711c0 |
#
|
|
|
7711c0 |
# Returns: nothing on success
|
|
|
7711c0 |
# If @node is not a valid block device, DeviceNotFound
|
|
|
7711c0 |
-# If @dst_name or @src_name is not found, GenericError
|
|
|
7711c0 |
-# If bitmaps has different sizes or granularities, GenericError
|
|
|
7711c0 |
+# If any bitmap in @bitmaps or @target is not found, GenericError
|
|
|
7711c0 |
+# If any of the bitmaps have different sizes or granularities,
|
|
|
7711c0 |
+# GenericError
|
|
|
7711c0 |
#
|
|
|
7711c0 |
# Since: 3.0
|
|
|
7711c0 |
#
|
|
|
7711c0 |
# Example:
|
|
|
7711c0 |
#
|
|
|
7711c0 |
# -> { "execute": "x-block-dirty-bitmap-merge",
|
|
|
7711c0 |
-# "arguments": { "node": "drive0", "dst_name": "bitmap0",
|
|
|
7711c0 |
-# "src_name": "bitmap1" } }
|
|
|
7711c0 |
+# "arguments": { "node": "drive0", "target": "bitmap0",
|
|
|
7711c0 |
+# "bitmaps": ["bitmap1"] } }
|
|
|
7711c0 |
# <- { "return": {} }
|
|
|
7711c0 |
#
|
|
|
7711c0 |
##
|
|
|
7711c0 |
--
|
|
|
7711c0 |
1.8.3.1
|
|
|
7711c0 |
|