From nobody Fri Nov 7 03:35:49 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1545273316891438.97043819350415; Wed, 19 Dec 2018 18:35:16 -0800 (PST) Received: from localhost ([::1]:35009 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gZoB9-0007cP-Ea for importer@patchew.org; Wed, 19 Dec 2018 21:35:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44968) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gZo6M-0004AT-Pq for qemu-devel@nongnu.org; Wed, 19 Dec 2018 21:30:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gZo6G-0007YR-Mi for qemu-devel@nongnu.org; Wed, 19 Dec 2018 21:30:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:59932) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gZo64-0007CW-Df; Wed, 19 Dec 2018 21:30:00 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9CE7D81DED; Thu, 20 Dec 2018 02:29:59 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-232.bos.redhat.com [10.18.17.232]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9FE1B2D35F; Thu, 20 Dec 2018 02:29:58 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Wed, 19 Dec 2018 21:29:44 -0500 Message-Id: <20181220022952.20493-4-jsnow@redhat.com> In-Reply-To: <20181220022952.20493-1-jsnow@redhat.com> References: <20181220022952.20493-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Thu, 20 Dec 2018 02:29:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v5 03/11] blockdev: n-ary bitmap merge X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , vsementsov@virtuozzo.com, Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 75 ++++++++++++++++++++++++++++++-------------- qapi/block-core.json | 22 ++++++------- 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/blockdev.c b/blockdev.c index 43e4c22da5..6031c94121 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2119,33 +2119,28 @@ static void block_dirty_bitmap_disable_abort(BlkAct= ionState *common) } } =20 +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 =3D DO_UPCAST(BlockDirtyBitmapState, common, common); - BdrvDirtyBitmap *merge_source; =20 if (action_check_completion_mode(common, errp) < 0) { return; } =20 action =3D common->action->u.x_block_dirty_bitmap_merge.data; - state->bitmap =3D block_dirty_bitmap_lookup(action->node, - action->dst_name, - &state->bs, - errp); - if (!state->bitmap) { - return; - } =20 - merge_source =3D bdrv_find_dirty_bitmap(state->bs, action->src_name); - if (!merge_source) { - return; - } - - bdrv_merge_dirty_bitmap(state->bitmap, merge_source, &state->backup, e= rrp); + state->bitmap =3D do_block_dirty_bitmap_merge(action->node, action->ta= rget, + action->bitmaps, &state->b= ackup, + errp); } =20 static void abort_prepare(BlkActionState *common, Error **errp) @@ -2977,24 +2972,56 @@ void qmp_x_block_dirty_bitmap_disable(const char *n= ode, const char *name, bdrv_disable_dirty_bitmap(bitmap); } =20 -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 =3D NULL; =20 - dst =3D block_dirty_bitmap_lookup(node, dst_name, &bs, errp); + dst =3D block_dirty_bitmap_lookup(node, target, &bs, errp); if (!dst) { - return; + return NULL; } =20 - src =3D bdrv_find_dirty_bitmap(bs, src_name); - if (!src) { - error_setg(errp, "Dirty bitmap '%s' not found", src_name); - return; + anon =3D bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(ds= t), + NULL, errp); + if (!anon) { + return NULL; } =20 - bdrv_merge_dirty_bitmap(dst, src, NULL, errp); + for (lst =3D bitmaps; lst; lst =3D lst->next) { + src =3D bdrv_find_dirty_bitmap(bs, lst->value); + if (!src) { + error_setg(errp, "Dirty bitmap '%s' not found", lst->value); + dst =3D NULL; + goto out; + } + + bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err); + if (local_err) { + error_propagate(errp, local_err); + dst =3D 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); } =20 BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *= node, diff --git a/qapi/block-core.json b/qapi/block-core.json index 762000f31f..a153ea4420 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'] } } =20 ## # @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": {} } # ## --=20 2.17.2