[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 03/20] blockdev: n-ary bitmap merge
From: |
Eric Blake |
Subject: |
[Qemu-devel] [PULL 03/20] blockdev: n-ary bitmap merge |
Date: |
Mon, 14 Jan 2019 10:25:48 -0600 |
From: John Snow <address@hidden>
Especially outside of transactions, it is helpful to provide
all-or-nothing semantics for bitmap merges. This facilitates
the coalescing of multiple bitmaps into a single target for
the "checkpoint" interpretation when assembling bitmaps that
represent arbitrary points in time from component bitmaps.
This is an incompatible change from the preliminary version
of the API.
Signed-off-by: John Snow <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
Reviewed-by: Vladimir Sementsov-Ogievskiy <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Eric Blake <address@hidden>
---
qapi/block-core.json | 22 ++++++-------
blockdev.c | 75 ++++++++++++++++++++++++++++++--------------
2 files changed, 62 insertions(+), 35 deletions(-)
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 762000f31f0..a153ea44203 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1821,14 +1821,14 @@
#
# @node: name of device/node which the bitmap is tracking
#
-# @dst_name: name of the destination dirty bitmap
+# @target: name of the destination dirty bitmap
#
-# @src_name: name of the source dirty bitmap
+# @bitmaps: name(s) of the source dirty bitmap(s)
#
# Since: 3.0
##
{ 'struct': 'BlockDirtyBitmapMerge',
- 'data': { 'node': 'str', 'dst_name': 'str', 'src_name': 'str' } }
+ 'data': { 'node': 'str', 'target': 'str', 'bitmaps': ['str'] } }
##
# @block-dirty-bitmap-add:
@@ -1943,23 +1943,23 @@
##
# @x-block-dirty-bitmap-merge:
#
-# FIXME: Rename @src_name and @dst_name to src-name and dst-name.
-#
-# Merge @src_name dirty bitmap to @dst_name dirty bitmap. @src_name dirty
-# bitmap is unchanged. On error, @dst_name is unchanged.
+# Merge dirty bitmaps listed in @bitmaps to the @target dirty bitmap.
+# The @bitmaps dirty bitmaps are unchanged.
+# On error, @target is unchanged.
#
# Returns: nothing on success
# If @node is not a valid block device, DeviceNotFound
-# If @dst_name or @src_name is not found, GenericError
-# If bitmaps has different sizes or granularities, GenericError
+# If any bitmap in @bitmaps or @target is not found, GenericError
+# If any of the bitmaps have different sizes or granularities,
+# GenericError
#
# Since: 3.0
#
# Example:
#
# -> { "execute": "x-block-dirty-bitmap-merge",
-# "arguments": { "node": "drive0", "dst_name": "bitmap0",
-# "src_name": "bitmap1" } }
+# "arguments": { "node": "drive0", "target": "bitmap0",
+# "bitmaps": ["bitmap1"] } }
# <- { "return": {} }
#
##
diff --git a/blockdev.c b/blockdev.c
index 3d46f8191f5..f7bf48dfe71 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2119,33 +2119,28 @@ static void
block_dirty_bitmap_disable_abort(BlkActionState *common)
}
}
+static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
+ const char *target,
+ strList *bitmaps,
+ HBitmap **backup,
+ Error **errp);
+
static void block_dirty_bitmap_merge_prepare(BlkActionState *common,
Error **errp)
{
BlockDirtyBitmapMerge *action;
BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState,
common, common);
- BdrvDirtyBitmap *merge_source;
if (action_check_completion_mode(common, errp) < 0) {
return;
}
action = common->action->u.x_block_dirty_bitmap_merge.data;
- state->bitmap = block_dirty_bitmap_lookup(action->node,
- action->dst_name,
- &state->bs,
- errp);
- if (!state->bitmap) {
- return;
- }
- merge_source = bdrv_find_dirty_bitmap(state->bs, action->src_name);
- if (!merge_source) {
- return;
- }
-
- bdrv_merge_dirty_bitmap(state->bitmap, merge_source, &state->backup, errp);
+ state->bitmap = do_block_dirty_bitmap_merge(action->node, action->target,
+ action->bitmaps,
&state->backup,
+ errp);
}
static void abort_prepare(BlkActionState *common, Error **errp)
@@ -2977,24 +2972,56 @@ void qmp_x_block_dirty_bitmap_disable(const char *node,
const char *name,
bdrv_disable_dirty_bitmap(bitmap);
}
-void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name,
- const char *src_name, Error **errp)
+static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node,
+ const char *target,
+ strList *bitmaps,
+ HBitmap **backup,
+ Error **errp)
{
BlockDriverState *bs;
- BdrvDirtyBitmap *dst, *src;
+ BdrvDirtyBitmap *dst, *src, *anon;
+ strList *lst;
+ Error *local_err = NULL;
- dst = block_dirty_bitmap_lookup(node, dst_name, &bs, errp);
+ dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
if (!dst) {
- return;
+ return NULL;
}
- src = bdrv_find_dirty_bitmap(bs, src_name);
- if (!src) {
- error_setg(errp, "Dirty bitmap '%s' not found", src_name);
- return;
+ anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst),
+ NULL, errp);
+ if (!anon) {
+ return NULL;
}
- bdrv_merge_dirty_bitmap(dst, src, NULL, errp);
+ for (lst = bitmaps; lst; lst = lst->next) {
+ src = bdrv_find_dirty_bitmap(bs, lst->value);
+ if (!src) {
+ error_setg(errp, "Dirty bitmap '%s' not found", lst->value);
+ dst = NULL;
+ goto out;
+ }
+
+ bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ dst = NULL;
+ goto out;
+ }
+ }
+
+ /* Merge into dst; dst is unchanged on failure. */
+ bdrv_merge_dirty_bitmap(dst, anon, backup, errp);
+
+ out:
+ bdrv_release_dirty_bitmap(bs, anon);
+ return dst;
+}
+
+void qmp_x_block_dirty_bitmap_merge(const char *node, const char *target,
+ strList *bitmaps, Error **errp)
+{
+ do_block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
}
BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
--
2.20.1
- [Qemu-devel] [PULL 00/20] NBD patches through 2019-01-14, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 01/20] blockdev: abort transactions in reverse order, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 02/20] block/dirty-bitmap: remove assertion from restore, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 06/20] iotests: add filter_generated_node_ids, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 05/20] iotests.py: don't abort if IMGKEYSECRET is undefined, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 04/20] block: remove 'x' prefix from experimental bitmap APIs, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 03/20] blockdev: n-ary bitmap merge,
Eric Blake <=
- [Qemu-devel] [PULL 10/20] iotests: implement pretty-print for log and qmp_log, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 09/20] iotests: change qmp_log filters to expect QMP objects only, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 08/20] iotests: remove default filters from qmp_log, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 07/20] iotests: add qmp recursive sorting function, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 12/20] qemu-nbd: Rename 'exp' variable clashing with math::exp() symbol, Eric Blake, 2019/01/14
- [Qemu-devel] [PULL 11/20] iotests: add iotest 236 for testing bitmap merge, Eric Blake, 2019/01/14