When a block driver supports obtaining format-specific information, but that object only contains optional fields, it is possible that none of them are present, so that dump_qobject() (called by bdrv_image_info_specific_dump()) will not print anything.
The callers of bdrv_image_info_specific_dump() put a header above this information ("Format specific information:\n"), which will look strange when there is nothing below. Modify bdrv_image_info_specific_dump() to print this header instead of its callers, and only if there is indeed something to be printed. Signed-off-by: Hanna Reitz <hre...@redhat.com> --- include/block/qapi.h | 3 ++- block/qapi.c | 41 +++++++++++++++++++++++++++++++++++++---- qemu-io-cmds.c | 4 ++-- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/include/block/qapi.h b/include/block/qapi.h index 22c7807c89..c09859ea78 100644 --- a/include/block/qapi.h +++ b/include/block/qapi.h @@ -40,6 +40,7 @@ void bdrv_query_image_info(BlockDriverState *bs, Error **errp); void bdrv_snapshot_dump(QEMUSnapshotInfo *sn); -void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec); +void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec, + const char *prefix); void bdrv_image_info_dump(ImageInfo *info); #endif diff --git a/block/qapi.c b/block/qapi.c index cf557e3aea..51202b470a 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -777,7 +777,35 @@ static void dump_qdict(int indentation, QDict *dict) } } -void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec) +/* + * Return whether dumping the given QObject with dump_qobject() would + * yield an empty dump, i.e. not print anything. + */ +static bool qobject_is_empty_dump(const QObject *obj) +{ + switch (qobject_type(obj)) { + case QTYPE_QNUM: + case QTYPE_QSTRING: + case QTYPE_QBOOL: + return false; + + case QTYPE_QDICT: + return qdict_size(qobject_to(QDict, obj)) == 0; + + case QTYPE_QLIST: + return qlist_empty(qobject_to(QList, obj)); + + default: + abort(); + } +} + +/** + * Dumps the given ImageInfoSpecific object in a human-readable form, + * prepending an optional prefix if the dump is not empty. + */ +void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec, + const char *prefix) { QObject *obj, *data; Visitor *v = qobject_output_visitor_new(&obj); @@ -785,7 +813,12 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec) visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort); visit_complete(v, &obj); data = qdict_get(qobject_to(QDict, obj), "data"); - dump_qobject(1, data); + if (!qobject_is_empty_dump(data)) { + if (prefix) { + qemu_printf("%s", prefix); + } + dump_qobject(1, data); + } qobject_unref(obj); visit_free(v); } @@ -866,7 +899,7 @@ void bdrv_image_info_dump(ImageInfo *info) } if (info->has_format_specific) { - qemu_printf("Format specific information:\n"); - bdrv_image_info_specific_dump(info->format_specific); + bdrv_image_info_specific_dump(info->format_specific, + "Format specific information:\n"); } } diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 2f0d8ac25a..084ec44d3b 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -1819,8 +1819,8 @@ static int info_f(BlockBackend *blk, int argc, char **argv) return -EIO; } if (spec_info) { - printf("Format specific information:\n"); - bdrv_image_info_specific_dump(spec_info); + bdrv_image_info_specific_dump(spec_info, + "Format specific information:\n"); qapi_free_ImageInfoSpecific(spec_info); } -- 2.35.3