From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38839) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMfBm-0001xf-EF for qemu-devel@nongnu.org; Fri, 22 Jan 2016 12:07:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aMfBj-0000AW-BY for qemu-devel@nongnu.org; Fri, 22 Jan 2016 12:07:58 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:37977 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aMfBi-0000AK-Oe for qemu-devel@nongnu.org; Fri, 22 Jan 2016 12:07:55 -0500 From: Vladimir Sementsov-Ogievskiy Date: Fri, 22 Jan 2016 20:07:39 +0300 Message-Id: <1453482459-80179-2-git-send-email-vsementsov@virtuozzo.com> In-Reply-To: <1453482459-80179-1-git-send-email-vsementsov@virtuozzo.com> References: <1453482459-80179-1-git-send-email-vsementsov@virtuozzo.com> Subject: [Qemu-devel] [PATCH] qmp: add query-block-dirty-bitmap List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: famz@redhat.com, Vladimir Sementsov-Ogievskiy , jsnow@redhat.com, den@virtuozzo.com 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) { + ; + } + + 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' } ## # @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, -- 1.8.3.1