Skip to content

Commit

Permalink
qmp: fill in the image field in BlockDeviceInfo
Browse files Browse the repository at this point in the history
The image field in BlockDeviceInfo is supposed to contain an ImageInfo
object. However that is being filled in by bdrv_query_info(), not by
bdrv_block_device_info(), which is where BlockDeviceInfo is actually
created.

Anyone calling bdrv_block_device_info() directly will get a null image
field. As a consequence of this, the HMP command 'info block -n -v'
crashes QEMU.

This patch moves the code that fills in that field from
bdrv_query_info() to bdrv_block_device_info().

Signed-off-by: Alberto Garcia <[email protected]>
Message-id: [email protected]
Signed-off-by: Stefan Hajnoczi <[email protected]>
Signed-off-by: Kevin Wolf <[email protected]>
  • Loading branch information
bertogg authored and kevmw committed Apr 28, 2015
1 parent 9419874 commit d5a8ee6
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 26 deletions.
9 changes: 7 additions & 2 deletions block.c
Original file line number Diff line number Diff line change
Expand Up @@ -3897,15 +3897,20 @@ BlockDriverState *bdrv_find_node(const char *node_name)
}

/* Put this QMP function here so it can access the static graph_bdrv_states. */
BlockDeviceInfoList *bdrv_named_nodes_list(void)
BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp)
{
BlockDeviceInfoList *list, *entry;
BlockDriverState *bs;

list = NULL;
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
BlockDeviceInfo *info = bdrv_block_device_info(bs, errp);
if (!info) {
qapi_free_BlockDeviceInfoList(list);
return NULL;
}
entry = g_malloc0(sizeof(*entry));
entry->value = bdrv_block_device_info(bs);
entry->value = info;
entry->next = list;
list = entry;
}
Expand Down
46 changes: 25 additions & 21 deletions block/qapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
#include "qapi/qmp/types.h"
#include "sysemu/block-backend.h"

BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp)
{
ImageInfo **p_image_info;
BlockDriverState *bs0;
BlockDeviceInfo *info = g_malloc0(sizeof(*info));

info->file = g_strdup(bs->filename);
Expand Down Expand Up @@ -92,6 +94,25 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)

info->write_threshold = bdrv_write_threshold_get(bs);

bs0 = bs;
p_image_info = &info->image;
while (1) {
Error *local_err = NULL;
bdrv_query_image_info(bs0, p_image_info, &local_err);
if (local_err) {
error_propagate(errp, local_err);
qapi_free_BlockDeviceInfo(info);
return NULL;
}
if (bs0->drv && bs0->backing_hd) {
bs0 = bs0->backing_hd;
(*p_image_info)->has_backing_image = true;
p_image_info = &((*p_image_info)->backing_image);
} else {
break;
}
}

return info;
}

Expand Down Expand Up @@ -264,9 +285,6 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
{
BlockInfo *info = g_malloc0(sizeof(*info));
BlockDriverState *bs = blk_bs(blk);
BlockDriverState *bs0;
ImageInfo **p_image_info;
Error *local_err = NULL;
info->device = g_strdup(blk_name(blk));
info->type = g_strdup("unknown");
info->locked = blk_dev_is_medium_locked(blk);
Expand All @@ -289,23 +307,9 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,

if (bs->drv) {
info->has_inserted = true;
info->inserted = bdrv_block_device_info(bs);

bs0 = bs;
p_image_info = &info->inserted->image;
while (1) {
bdrv_query_image_info(bs0, p_image_info, &local_err);
if (local_err) {
error_propagate(errp, local_err);
goto err;
}
if (bs0->drv && bs0->backing_hd) {
bs0 = bs0->backing_hd;
(*p_image_info)->has_backing_image = true;
p_image_info = &((*p_image_info)->backing_image);
} else {
break;
}
info->inserted = bdrv_block_device_info(bs, errp);
if (info->inserted == NULL) {
goto err;
}
}

Expand Down
2 changes: 1 addition & 1 deletion blockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2392,7 +2392,7 @@ void qmp_drive_backup(const char *device, const char *target,

BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp)
{
return bdrv_named_nodes_list();
return bdrv_named_nodes_list(errp);
}

void qmp_blockdev_backup(const char *device, const char *target,
Expand Down
2 changes: 1 addition & 1 deletion include/block/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ void bdrv_lock_medium(BlockDriverState *bs, bool locked);
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
const char *bdrv_get_format_name(BlockDriverState *bs);
BlockDriverState *bdrv_find_node(const char *node_name);
BlockDeviceInfoList *bdrv_named_nodes_list(void);
BlockDeviceInfoList *bdrv_named_nodes_list(Error **errp);
BlockDriverState *bdrv_lookup_bs(const char *device,
const char *node_name,
Error **errp);
Expand Down
2 changes: 1 addition & 1 deletion include/block/qapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "block/block.h"
#include "block/snapshot.h"

BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs);
BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs, Error **errp);
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
SnapshotInfoList **p_list,
Error **errp);
Expand Down

0 comments on commit d5a8ee6

Please sign in to comment.