From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44731) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMfWB-0000fh-WB for qemu-devel@nongnu.org; Fri, 22 Jan 2016 12:29:05 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aMfW8-0005YU-P9 for qemu-devel@nongnu.org; Fri, 22 Jan 2016 12:29:03 -0500 Received: from mx2.parallels.com ([199.115.105.18]:39838) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMfW8-0005YP-HS for qemu-devel@nongnu.org; Fri, 22 Jan 2016 12:29:00 -0500 Message-ID: <56A266D3.1030605@virtuozzo.com> Date: Fri, 22 Jan 2016 20:28:51 +0300 From: Vladimir Sementsov-Ogievskiy MIME-Version: 1.0 References: <1453482459-80179-1-git-send-email-vsementsov@virtuozzo.com> <1453482459-80179-2-git-send-email-vsementsov@virtuozzo.com> <56A26565.9080601@virtuozzo.com> In-Reply-To: <56A26565.9080601@virtuozzo.com> Content-Type: text/plain; charset="windows-1252"; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH] qmp: add query-block-dirty-bitmap List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Denis V. Lunev" , qemu-devel@nongnu.org Cc: famz@redhat.com, jsnow@redhat.com On 22.01.2016 20:22, Denis V. Lunev wrote: > On 01/22/2016 08:07 PM, Vladimir Sementsov-Ogievskiy wrote: >> Add qmp command to query dirty bitmap. This is needed for external >> backup. >> >> Signed-off-by: Vladimir Sementsov-Ogievskiy >> --- >> block.c | 41 ++++++++++++++++++++++++++++++++++++++++ >> blockdev.c | 21 +++++++++++++++++++++ >> include/block/block.h | 2 ++ >> qapi/block-core.json | 52 >> +++++++++++++++++++++++++++++++++++++++++++++++++++ >> qmp-commands.hx | 22 ++++++++++++++++++++++ >> 5 files changed, 138 insertions(+) >> >> diff --git a/block.c b/block.c >> index 5709d3d..9a28589 100644 >> --- a/block.c >> +++ b/block.c >> @@ -3717,6 +3717,47 @@ void bdrv_set_dirty(BlockDriverState *bs, >> int64_t cur_sector, >> } >> } >> +BlockDirtyBitmapInfo *bdrv_query_dirty_bitmap(BlockDriverState *bs, >> + BdrvDirtyBitmap *bitmap) >> +{ >> + BlockDirtyBitmapInfo *info = g_new0(BlockDirtyBitmapInfo, 1); >> + BlockDirtyRegionList **plist = &info->dirty_regions; >> + uint64_t begin = 0, end = 0, size = bitmap->size; >> + HBitmap *hb = bitmap->bitmap; >> + >> + info->dirty_count = bdrv_get_dirty_count(bitmap); >> + info->granularity = bdrv_dirty_bitmap_granularity(bitmap); >> + info->size = bitmap->size; >> + info->name = g_strdup(bitmap->name); >> + info->disabled = bitmap->disabled; >> + info->dirty_regions = NULL; >> + >> + for (; begin < size; ++begin) { >> + BlockDirtyRegion *region; >> + BlockDirtyRegionList *entry; >> + >> + if (!hbitmap_get(hb, begin)) { >> + continue; >> + } >> + >> + for (end = begin + 1; end < size && hbitmap_get(hb, end); >> ++end) { >> + ; >> + } > let us implemented faster finder. This would be useful in other > places. It could be > 100 times faster! I'll use iterators here, if the whole way is ok (querying regions, not blob) > >> + >> + region = g_new0(BlockDirtyRegion, 1); >> + entry = g_new0(BlockDirtyRegionList, 1); >> + region->start = begin; >> + region->count = end - begin; >> + entry->value = region; >> + *plist = entry; >> + plist = &entry->next; >> + >> + begin = end; >> + } >> + >> + return info; >> +} >> + >> /** >> * Advance an HBitmapIter to an arbitrary offset. >> */ >> diff --git a/blockdev.c b/blockdev.c >> index 07cfe25..d2bc453 100644 >> --- a/blockdev.c >> +++ b/blockdev.c >> @@ -2734,6 +2734,27 @@ void qmp_block_dirty_bitmap_clear(const char >> *node, const char *name, >> aio_context_release(aio_context); >> } >> +BlockDirtyBitmapInfo *qmp_query_block_dirty_bitmap(const char *node, >> + const char *name, >> + Error **errp) >> +{ >> + AioContext *aio_context; >> + BdrvDirtyBitmap *bitmap; >> + BlockDriverState *bs; >> + BlockDirtyBitmapInfo *ret = NULL; >> + >> + bitmap = block_dirty_bitmap_lookup(node, name, &bs, >> &aio_context, errp); >> + if (!bitmap) { >> + return NULL; >> + } >> + >> + ret = bdrv_query_dirty_bitmap(bs, bitmap); >> + >> + aio_context_release(aio_context); >> + >> + return ret; >> +} >> + >> void hmp_drive_del(Monitor *mon, const QDict *qdict) >> { >> const char *id = qdict_get_str(qdict, "id"); >> diff --git a/include/block/block.h b/include/block/block.h >> index 25f36dc..9d6bd33 100644 >> --- a/include/block/block.h >> +++ b/include/block/block.h >> @@ -505,6 +505,8 @@ void bdrv_set_dirty_bitmap(BdrvDirtyBitmap *bitmap, >> int64_t cur_sector, int nr_sectors); >> void bdrv_reset_dirty_bitmap(BdrvDirtyBitmap *bitmap, >> int64_t cur_sector, int nr_sectors); >> +BlockDirtyBitmapInfo *bdrv_query_dirty_bitmap(BlockDriverState *bs, >> + BdrvDirtyBitmap *bitmap); >> void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct >> HBitmapIter *hbi); >> void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset); >> int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap); >> diff --git a/qapi/block-core.json b/qapi/block-core.json >> index 0a915ed..12ed759 100644 >> --- a/qapi/block-core.json >> +++ b/qapi/block-core.json >> @@ -414,6 +414,58 @@ >> ## >> { 'command': 'query-block', 'returns': ['BlockInfo'] } >> +## >> +# @BlockDirtyRegion: >> +# >> +# Region in bytes. >> +# >> +# @start: first byte >> +# >> +# @count: number of bytes in the region >> +# >> +# Since: 2.3 >> +## >> +{ 'struct': 'BlockDirtyRegion', >> + 'data': { 'start': 'int', 'count': 'int' } } >> + >> +## >> +# @BlockDirtyBitmapInfo >> +# >> +# @name: the name of the dirty bitmap >> +# >> +# @size: size of the dirty bitmap in sectors >> +# >> +# @granularity: granularity of the dirty bitmap in bytes >> +# >> +# @disabled: whether the dirty bitmap is disabled >> +# >> +# @dirty-count: number of dirty bytes according to the dirty bitmap >> +# >> +# @dirty-regions: dirty regions of the bitmap >> +# >> +# Since 2.3 >> +## >> +{ 'struct': 'BlockDirtyBitmapInfo', >> + 'data': { 'name': 'str', >> + 'size': 'int', >> + 'granularity': 'int', >> + 'disabled': 'bool', >> + 'dirty-count': 'int', >> + 'dirty-regions': ['BlockDirtyRegion'] } } >> + >> +## >> +# @query-block-dirty-bitmap >> +# >> +# Get a description for specified dirty bitmap including it's dirty >> regions. >> +# This command is in general for testing purposes. >> +# >> +# Returns: @BlockDirtyBitmapInfo >> +# >> +# Since: 2.3 >> +## >> +{ 'command': 'query-block-dirty-bitmap', >> + 'data': 'BlockDirtyBitmap', >> + 'returns': 'BlockDirtyBitmapInfo' } > 1) should we consider part-by-part retrieval? This could be useful for > large discs. > 2) Change to since 2.6 > 3) Do you think that content should be retrieved separately than data? 3 - what do you mean? > > >> ## >> # @BlockDeviceTimedStats: >> diff --git a/qmp-commands.hx b/qmp-commands.hx >> index db072a6..75d9345 100644 >> --- a/qmp-commands.hx >> +++ b/qmp-commands.hx >> @@ -1457,6 +1457,28 @@ Example: >> EQMP >> { >> + .name = "query-block-dirty-bitmap", >> + .args_type = "node:B,name:s", >> + .mhandler.cmd_new = qmp_marshal_query_block_dirty_bitmap, >> + }, >> + >> +SQMP >> + >> +query-block-dirty-bitmap >> +------------------------ >> +Since 2.6 >> + >> +Get dirty bitmap info, including contents. Bitmap data are returned >> as array of >> +dirty regions >> + >> +Arguments: >> + >> +- "node": device/node on which to remove dirty bitmap (json-string) >> +- "name": name of the dirty bitmap to remove (json-string) >> + >> +EQMP >> + >> + { >> .name = "blockdev-snapshot-sync", >> .args_type = >> "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?", >> .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_sync, > can you pls use den@openvz.org addr sending patches to me? ok, sorry. -- Best regards, Vladimir * now, @virtuozzo.com instead of @parallels.com. Sorry for this inconvenience.