qemu-img: Use BlockNodeInfo

qemu-img info never uses ImageInfo's backing-image field, because it
opens the backing chain one by one with BDRV_O_NO_BACKING, and prints
all backing chain nodes' information consecutively.  Use BlockNodeInfo
to make it clear that we only print information about a single node, and
that we are not using the backing-image field.

Notably, bdrv_image_info_dump() does not evaluate the backing-image
field, so we can easily make it take a BlockNodeInfo pointer (and
consequentially rename it to bdrv_node_info_dump()).  It makes more
sense this way, because again, the interface now makes it syntactically
clear that backing-image is ignored by this function.

Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220620162704.80987-6-hreitz@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Hanna Reitz 2022-06-20 18:26:57 +02:00 committed by Kevin Wolf
parent a2085f8909
commit b1f4cd1589
5 changed files with 29 additions and 29 deletions

View file

@ -725,7 +725,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
monitor_printf(mon, "\nImages:\n"); monitor_printf(mon, "\nImages:\n");
image_info = inserted->image; image_info = inserted->image;
while (1) { while (1) {
bdrv_image_info_dump(image_info); bdrv_node_info_dump(qapi_ImageInfo_base(image_info));
if (image_info->backing_image) { if (image_info->backing_image) {
image_info = image_info->backing_image; image_info = image_info->backing_image;
} else { } else {

View file

@ -848,7 +848,7 @@ void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
visit_free(v); visit_free(v);
} }
void bdrv_image_info_dump(ImageInfo *info) void bdrv_node_info_dump(BlockNodeInfo *info)
{ {
char *size_buf, *dsize_buf; char *size_buf, *dsize_buf;
if (!info->has_actual_size) { if (!info->has_actual_size) {

View file

@ -45,5 +45,5 @@ void bdrv_query_image_info(BlockDriverState *bs,
void bdrv_snapshot_dump(QEMUSnapshotInfo *sn); 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); const char *prefix);
void bdrv_image_info_dump(ImageInfo *info); void bdrv_node_info_dump(BlockNodeInfo *info);
#endif #endif

View file

@ -5796,9 +5796,9 @@
## ##
# @DummyBlockCoreForceArrays: # @DummyBlockCoreForceArrays:
# #
# Not used by QMP; hack to let us use ImageInfoList internally # Not used by QMP; hack to let us use BlockNodeInfoList internally
# #
# Since: 8.0 # Since: 8.0
## ##
{ 'struct': 'DummyBlockCoreForceArrays', { 'struct': 'DummyBlockCoreForceArrays',
'data': { 'unused-image-info': ['ImageInfo'] } } 'data': { 'unused-block-node-info': ['BlockNodeInfo'] } }

View file

@ -2817,13 +2817,13 @@ static void dump_snapshots(BlockDriverState *bs)
g_free(sn_tab); g_free(sn_tab);
} }
static void dump_json_image_info_list(ImageInfoList *list) static void dump_json_block_node_info_list(BlockNodeInfoList *list)
{ {
GString *str; GString *str;
QObject *obj; QObject *obj;
Visitor *v = qobject_output_visitor_new(&obj); Visitor *v = qobject_output_visitor_new(&obj);
visit_type_ImageInfoList(v, NULL, &list, &error_abort); visit_type_BlockNodeInfoList(v, NULL, &list, &error_abort);
visit_complete(v, &obj); visit_complete(v, &obj);
str = qobject_to_json_pretty(obj, true); str = qobject_to_json_pretty(obj, true);
assert(str != NULL); assert(str != NULL);
@ -2833,13 +2833,13 @@ static void dump_json_image_info_list(ImageInfoList *list)
g_string_free(str, true); g_string_free(str, true);
} }
static void dump_json_image_info(ImageInfo *info) static void dump_json_block_node_info(BlockNodeInfo *info)
{ {
GString *str; GString *str;
QObject *obj; QObject *obj;
Visitor *v = qobject_output_visitor_new(&obj); Visitor *v = qobject_output_visitor_new(&obj);
visit_type_ImageInfo(v, NULL, &info, &error_abort); visit_type_BlockNodeInfo(v, NULL, &info, &error_abort);
visit_complete(v, &obj); visit_complete(v, &obj);
str = qobject_to_json_pretty(obj, true); str = qobject_to_json_pretty(obj, true);
assert(str != NULL); assert(str != NULL);
@ -2849,9 +2849,9 @@ static void dump_json_image_info(ImageInfo *info)
g_string_free(str, true); g_string_free(str, true);
} }
static void dump_human_image_info_list(ImageInfoList *list) static void dump_human_image_info_list(BlockNodeInfoList *list)
{ {
ImageInfoList *elem; BlockNodeInfoList *elem;
bool delim = false; bool delim = false;
for (elem = list; elem; elem = elem->next) { for (elem = list; elem; elem = elem->next) {
@ -2860,7 +2860,7 @@ static void dump_human_image_info_list(ImageInfoList *list)
} }
delim = true; delim = true;
bdrv_image_info_dump(elem->value); bdrv_node_info_dump(elem->value);
} }
} }
@ -2870,24 +2870,24 @@ static gboolean str_equal_func(gconstpointer a, gconstpointer b)
} }
/** /**
* Open an image file chain and return an ImageInfoList * Open an image file chain and return an BlockNodeInfoList
* *
* @filename: topmost image filename * @filename: topmost image filename
* @fmt: topmost image format (may be NULL to autodetect) * @fmt: topmost image format (may be NULL to autodetect)
* @chain: true - enumerate entire backing file chain * @chain: true - enumerate entire backing file chain
* false - only topmost image file * false - only topmost image file
* *
* Returns a list of ImageInfo objects or NULL if there was an error opening an * Returns a list of BlockNodeInfo objects or NULL if there was an error
* image file. If there was an error a message will have been printed to * opening an image file. If there was an error a message will have been
* stderr. * printed to stderr.
*/ */
static ImageInfoList *collect_image_info_list(bool image_opts, static BlockNodeInfoList *collect_image_info_list(bool image_opts,
const char *filename, const char *filename,
const char *fmt, const char *fmt,
bool chain, bool force_share) bool chain, bool force_share)
{ {
ImageInfoList *head = NULL; BlockNodeInfoList *head = NULL;
ImageInfoList **tail = &head; BlockNodeInfoList **tail = &head;
GHashTable *filenames; GHashTable *filenames;
Error *err = NULL; Error *err = NULL;
@ -2896,7 +2896,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
while (filename) { while (filename) {
BlockBackend *blk; BlockBackend *blk;
BlockDriverState *bs; BlockDriverState *bs;
ImageInfo *info; BlockNodeInfo *info;
if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) { if (g_hash_table_lookup_extended(filenames, filename, NULL, NULL)) {
error_report("Backing file '%s' creates an infinite loop.", error_report("Backing file '%s' creates an infinite loop.",
@ -2913,7 +2913,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
} }
bs = blk_bs(blk); bs = blk_bs(blk);
bdrv_query_image_info(bs, &info, &err); bdrv_query_block_node_info(bs, &info, &err);
if (err) { if (err) {
error_report_err(err); error_report_err(err);
blk_unref(blk); blk_unref(blk);
@ -2946,7 +2946,7 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
return head; return head;
err: err:
qapi_free_ImageInfoList(head); qapi_free_BlockNodeInfoList(head);
g_hash_table_destroy(filenames); g_hash_table_destroy(filenames);
return NULL; return NULL;
} }
@ -2957,7 +2957,7 @@ static int img_info(int argc, char **argv)
OutputFormat output_format = OFORMAT_HUMAN; OutputFormat output_format = OFORMAT_HUMAN;
bool chain = false; bool chain = false;
const char *filename, *fmt, *output; const char *filename, *fmt, *output;
ImageInfoList *list; BlockNodeInfoList *list;
bool image_opts = false; bool image_opts = false;
bool force_share = false; bool force_share = false;
@ -3036,14 +3036,14 @@ static int img_info(int argc, char **argv)
break; break;
case OFORMAT_JSON: case OFORMAT_JSON:
if (chain) { if (chain) {
dump_json_image_info_list(list); dump_json_block_node_info_list(list);
} else { } else {
dump_json_image_info(list->value); dump_json_block_node_info(list->value);
} }
break; break;
} }
qapi_free_ImageInfoList(list); qapi_free_BlockNodeInfoList(list);
return 0; return 0;
} }