[PATCH v6 19/25] parallels: report the stored dirty bitmaps in qemu-img info
"Denis V. Lunev" <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu.block,gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
From: Denis V. Lunev <[email protected]> Nothing tells which persistent bitmaps an image carries. qemu-img info says nothing about them, and the only other way to see one is to export the image over NBD and ask for a bitmap by name, which needs the name beforehand. Add ImageInfoSpecificParallels with the bitmaps and their granularity, as qcow2 reports the contents of its bitmap directory: Format specific information: bitmaps: [0]: name: b2c9e1a4-5d3f-4e8b-9a7c-6f0d1e2b3a45 granularity: 65536 The list is built from the bitmaps loaded at open time rather than from a second pass over the Format Extension, as every bitmap the extension carries is loaded and marked persistent there. On a node which is open that also covers a bitmap which was created but not stored yet, which is what the field says: qemu-img info opens the image on its own, so there the two are the same thing. An image with no bitmaps leaves the structure empty, and bdrv_image_info_specific_dump() prints nothing for an empty one, so the output for such an image does not change. Cc: Stefan Hajnoczi <[email protected]> Cc: Eric Blake <[email protected]> Cc: Markus Armbruster <[email protected]> Signed-off-by: Denis V. Lunev <[email protected]> --- block/parallels-ext.c | 22 ++++++++++ block/parallels.c | 20 ++++++++++ block/parallels.h | 3 ++ qapi/block-core.json | 40 ++++++++++++++++++- tests/qemu-iotests/tests/parallels-checks | 3 ++ tests/qemu-iotests/tests/parallels-checks.out | 9 +++++ 6 files changed, 95 insertions(+), 2 deletions(-) diff --git a/block/parallels-ext.c b/block/parallels-ext.c index f687f2da7c..ad87ecfbc1 100644 --- a/block/parallels-ext.c +++ b/block/parallels-ext.c @@ -736,3 +736,25 @@ parallels_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, return ret; } + +void parallels_get_bitmap_info_list(BlockDriverState *bs, + ParallelsBitmapInfoList **info_list) +{ + BdrvDirtyBitmap *bitmap; + ParallelsBitmapInfoList **tail = info_list; + + *info_list = NULL; + + FOR_EACH_DIRTY_BITMAP(bs, bitmap) { + ParallelsBitmapInfo *info; + + if (!bdrv_dirty_bitmap_get_persistence(bitmap)) { + continue; + } + + info = g_new0(ParallelsBitmapInfo, 1); + info->name = g_strdup(bdrv_dirty_bitmap_name(bitmap)); + info->granularity = bdrv_dirty_bitmap_granularity(bitmap); + QAPI_LIST_APPEND(tail, info); + } +} diff --git a/block/parallels.c b/block/parallels.c index 2a5ceb8978..e7d65d0458 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -1624,6 +1624,25 @@ static bool parallels_is_support_dirty_bitmaps(BlockDriverState *bs) return 1; } +static ImageInfoSpecific * GRAPH_RDLOCK +parallels_get_specific_info(BlockDriverState *bs, Error **errp) +{ + ImageInfoSpecificParallels *parallels_info; + ImageInfoSpecific *spec_info; + + parallels_info = g_new0(ImageInfoSpecificParallels, 1); + parallels_get_bitmap_info_list(bs, ¶llels_info->bitmaps); + parallels_info->has_bitmaps = !!parallels_info->bitmaps; + + spec_info = g_new(ImageInfoSpecific, 1); + *spec_info = (ImageInfoSpecific){ + .type = IMAGE_INFO_SPECIFIC_KIND_PARALLELS, + .u.parallels.data = parallels_info, + }; + + return spec_info; +} + static BlockDriver bdrv_parallels = { .format_name = "parallels", .instance_size = sizeof(BDRVParallelsState), @@ -1653,6 +1672,7 @@ static BlockDriver bdrv_parallels = { parallels_co_can_store_new_dirty_bitmap, .bdrv_co_remove_persistent_dirty_bitmap = parallels_co_remove_persistent_dirty_bitmap, + .bdrv_get_specific_info = parallels_get_specific_info, }; static void bdrv_parallels_init(void) diff --git a/block/parallels.h b/block/parallels.h index 27d8c3ac83..012f47320b 100644 --- a/block/parallels.h +++ b/block/parallels.h @@ -32,6 +32,7 @@ #ifndef BLOCK_PARALLELS_H #define BLOCK_PARALLELS_H #include "qemu/coroutine.h" +#include "qapi/qapi-types-block-core.h" #define HEADS_NUMBER 16 #define SEC_IN_CYL 32 @@ -111,5 +112,7 @@ parallels_co_can_store_new_dirty_bitmap(BlockDriverState *bs, const char *name, int coroutine_fn GRAPH_RDLOCK parallels_co_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, Error **errp); +void parallels_get_bitmap_info_list(BlockDriverState *bs, + ParallelsBitmapInfoList **info_list); #endif diff --git a/qapi/block-core.json b/qapi/block-core.json index 1f87b07850..4bc8b45efe 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -200,7 +200,7 @@ # Since: 1.7 ## { 'enum': 'ImageInfoSpecificKind', - 'data': [ 'qcow2', 'vmdk', 'luks', 'rbd', 'file' ] } + 'data': [ 'qcow2', 'vmdk', 'luks', 'rbd', 'file', 'parallels' ] } ## # @ImageInfoSpecificQCow2Wrapper: @@ -255,6 +255,41 @@ { 'struct': 'ImageInfoSpecificFileWrapper', 'data': { 'data': 'ImageInfoSpecificFile' } } +## +# @ParallelsBitmapInfo: +# +# Parallels dirty bitmap information. +# +# @name: the name of the bitmap +# +# @granularity: granularity of the bitmap in bytes +# +# Since: 11.2 +## +{ 'struct': 'ParallelsBitmapInfo', + 'data': { 'name': 'str', 'granularity': 'uint32' } } + +## +# @ImageInfoSpecificParallels: +# +# @bitmaps: A list of the persistent dirty bitmaps of the image, +# including the ones which are not written out yet +# +# Since: 11.2 +## +{ 'struct': 'ImageInfoSpecificParallels', + 'data': { '*bitmaps': ['ParallelsBitmapInfo'] } } + +## +# @ImageInfoSpecificParallelsWrapper: +# +# @data: image information specific to Parallels +# +# Since: 11.2 +## +{ 'struct': 'ImageInfoSpecificParallelsWrapper', + 'data': { 'data': 'ImageInfoSpecificParallels' } } + ## # @ImageInfoSpecific: # @@ -273,7 +308,8 @@ 'vmdk': 'ImageInfoSpecificVmdkWrapper', 'luks': 'ImageInfoSpecificLUKSWrapper', 'rbd': 'ImageInfoSpecificRbdWrapper', - 'file': 'ImageInfoSpecificFileWrapper' + 'file': 'ImageInfoSpecificFileWrapper', + 'parallels': 'ImageInfoSpecificParallelsWrapper' } } ## diff --git a/tests/qemu-iotests/tests/parallels-checks b/tests/qemu-iotests/tests/parallels-checks index 916d423a64..4c8fc17fa9 100755 --- a/tests/qemu-iotests/tests/parallels-checks +++ b/tests/qemu-iotests/tests/parallels-checks @@ -382,6 +382,9 @@ echo "== dirty a single granule of the bitmap ==" file_size=`stat --printf="%s" "$TEST_IMG"` echo "file size: $file_size" +echo "== the bitmap is reported by qemu-img info ==" +_img_info --format-specific + echo "== the extension and its bitmap data are not a leak ==" _check_test_img diff --git a/tests/qemu-iotests/tests/parallels-checks.out b/tests/qemu-iotests/tests/parallels-checks.out index 4dfadd68d6..7aaa4636d7 100644 --- a/tests/qemu-iotests/tests/parallels-checks.out +++ b/tests/qemu-iotests/tests/parallels-checks.out @@ -241,6 +241,15 @@ qemu-img: Operation add on bitmap bitmap0 failed: Bitmap name must be a UUID to wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) file size: 4194304 +== the bitmap is reported by qemu-img info == +image: TEST_DIR/t.IMGFMT +file format: IMGFMT +virtual size: 4 MiB (4194304 bytes) +Format specific information: + bitmaps: + [0]: + name: b2c9e1a4-5d3f-4e8b-9a7c-6f0d1e2b3a45 + granularity: 65536 == the extension and its bitmap data are not a leak == No errors were found on the image. == extend image by 1 cluster == -- 2.53.0