[openSUSE] block: Convert qmp_query_block() to coroutine_fn (bsc#1211000)
This is another caller of bdrv_get_allocated_file_size() that needs to be converted to a coroutine because that function will be made asynchronous when called (indirectly) from the QMP dispatcher. This QMP command is a candidate because it calls bdrv_do_query_node_info(), which in turn calls bdrv_get_allocated_file_size(). We've determined bdrv_do_query_node_info() to be coroutine-safe (see previous commits), so we can just put this QMP command in a coroutine. Since qmp_query_block() now expects to run in a coroutine, its callers need to be converted as well. Convert hmp_info_block(), which calls only coroutine-safe code, including qmp_query_named_block_nodes() which has been converted to coroutine in the previous patches. Now that all callers of bdrv_[co_]block_device_info() are using the coroutine version, a few things happen: - we can return to using bdrv_block_device_info() without a wrapper; - bdrv_get_allocated_file_size() can stop being mixed; - bdrv_co_get_allocated_file_size() needs to be put under the graph lock because it is being called wthout the wrapper; - bdrv_do_query_node_info() doesn't need to acquire the AioContext because it doesn't call aio_poll anymore; Signed-off-by: Fabiano Rosas <farosas@suse.de> References: bsc#1211000 [relax main loop requirement at qmp_query_block] Signed-off-by: Fabiano Rosas <farosas@suse.de>
This commit is contained in:
2
block.c
2
block.c
@@ -6348,7 +6348,7 @@ BlockDeviceInfoList *bdrv_named_nodes_list(bool flat,
|
|||||||
|
|
||||||
list = NULL;
|
list = NULL;
|
||||||
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
|
QTAILQ_FOREACH(bs, &graph_bdrv_states, node_list) {
|
||||||
BlockDeviceInfo *info = bdrv_co_block_device_info(NULL, bs, flat, errp);
|
BlockDeviceInfo *info = bdrv_block_device_info(NULL, bs, flat, errp);
|
||||||
if (!info) {
|
if (!info) {
|
||||||
qapi_free_BlockDeviceInfoList(list);
|
qapi_free_BlockDeviceInfoList(list);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -748,7 +748,7 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_info_block(Monitor *mon, const QDict *qdict)
|
void coroutine_fn hmp_info_block(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
BlockInfoList *block_list, *info;
|
BlockInfoList *block_list, *info;
|
||||||
BlockDeviceInfoList *blockdev_list, *blockdev;
|
BlockDeviceInfoList *blockdev_list, *blockdev;
|
||||||
|
|||||||
20
block/qapi.c
20
block/qapi.c
@@ -41,10 +41,10 @@
|
|||||||
#include "qemu/qemu-print.h"
|
#include "qemu/qemu-print.h"
|
||||||
#include "sysemu/block-backend.h"
|
#include "sysemu/block-backend.h"
|
||||||
|
|
||||||
BlockDeviceInfo *coroutine_fn bdrv_co_block_device_info(BlockBackend *blk,
|
BlockDeviceInfo *coroutine_fn bdrv_block_device_info(BlockBackend *blk,
|
||||||
BlockDriverState *bs,
|
BlockDriverState *bs,
|
||||||
bool flat,
|
bool flat,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
ImageInfo **p_image_info;
|
ImageInfo **p_image_info;
|
||||||
ImageInfo *backing_info;
|
ImageInfo *backing_info;
|
||||||
@@ -234,8 +234,6 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
|||||||
int ret;
|
int ret;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
aio_context_acquire(bdrv_get_aio_context(bs));
|
|
||||||
|
|
||||||
size = bdrv_getlength(bs);
|
size = bdrv_getlength(bs);
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
error_setg_errno(errp, -size, "Can't get image size '%s'",
|
error_setg_errno(errp, -size, "Can't get image size '%s'",
|
||||||
@@ -248,7 +246,9 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
|||||||
info->filename = g_strdup(bs->filename);
|
info->filename = g_strdup(bs->filename);
|
||||||
info->format = g_strdup(bdrv_get_format_name(bs));
|
info->format = g_strdup(bdrv_get_format_name(bs));
|
||||||
info->virtual_size = size;
|
info->virtual_size = size;
|
||||||
info->actual_size = bdrv_get_allocated_file_size(bs);
|
bdrv_graph_co_rdlock();
|
||||||
|
info->actual_size = bdrv_co_get_allocated_file_size(bs);
|
||||||
|
bdrv_graph_co_rdunlock();
|
||||||
info->has_actual_size = info->actual_size >= 0;
|
info->has_actual_size = info->actual_size >= 0;
|
||||||
if (bs->encrypted) {
|
if (bs->encrypted) {
|
||||||
info->encrypted = true;
|
info->encrypted = true;
|
||||||
@@ -304,7 +304,7 @@ bdrv_do_query_node_info(BlockDriverState *bs, BlockNodeInfo *info, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
aio_context_release(bdrv_get_aio_context(bs));
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -667,13 +667,13 @@ bdrv_query_bds_stats(BlockDriverState *bs, bool blk_level)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockInfoList *qmp_query_block(Error **errp)
|
BlockInfoList *coroutine_fn qmp_query_block(Error **errp)
|
||||||
{
|
{
|
||||||
BlockInfoList *head = NULL, **p_next = &head;
|
BlockInfoList *head = NULL, **p_next = &head;
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
GRAPH_RDLOCK_GUARD_MAINLOOP();
|
GRAPH_RDLOCK_GUARD();
|
||||||
|
|
||||||
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
|
for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
|
||||||
BlockInfoList *info;
|
BlockInfoList *info;
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ ERST
|
|||||||
.help = "show info of one block device or all block devices "
|
.help = "show info of one block device or all block devices "
|
||||||
"(-n: show named nodes; -v: show details)",
|
"(-n: show named nodes; -v: show details)",
|
||||||
.cmd = hmp_info_block,
|
.cmd = hmp_info_block,
|
||||||
|
.coroutine = true,
|
||||||
},
|
},
|
||||||
|
|
||||||
SRST
|
SRST
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ void hmp_eject(Monitor *mon, const QDict *qdict);
|
|||||||
|
|
||||||
void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
||||||
|
|
||||||
void hmp_info_block(Monitor *mon, const QDict *qdict);
|
void coroutine_fn hmp_info_block(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
|
void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
|
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
|
||||||
void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
|
void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs);
|
|||||||
int64_t coroutine_fn GRAPH_RDLOCK
|
int64_t coroutine_fn GRAPH_RDLOCK
|
||||||
bdrv_co_get_allocated_file_size(BlockDriverState *bs);
|
bdrv_co_get_allocated_file_size(BlockDriverState *bs);
|
||||||
|
|
||||||
int64_t co_wrapper_mixed_bdrv_rdlock
|
int64_t co_wrapper_bdrv_rdlock
|
||||||
bdrv_get_allocated_file_size(BlockDriverState *bs);
|
bdrv_get_allocated_file_size(BlockDriverState *bs);
|
||||||
|
|
||||||
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
|
BlockMeasureInfo *bdrv_measure(BlockDriver *drv, QemuOpts *opts,
|
||||||
|
|||||||
@@ -30,10 +30,7 @@
|
|||||||
#include "block/snapshot.h"
|
#include "block/snapshot.h"
|
||||||
#include "qapi/qapi-types-block-core.h"
|
#include "qapi/qapi-types-block-core.h"
|
||||||
|
|
||||||
BlockDeviceInfo * coroutine_fn GRAPH_RDLOCK
|
BlockDeviceInfo *coroutine_fn GRAPH_RDLOCK
|
||||||
bdrv_co_block_device_info(BlockBackend *blk, BlockDriverState *bs,
|
|
||||||
bool flat, Error **errp);
|
|
||||||
BlockDeviceInfo *co_wrapper_bdrv_rdlock
|
|
||||||
bdrv_block_device_info(BlockBackend *blk, BlockDriverState *bs, bool flat,
|
bdrv_block_device_info(BlockBackend *blk, BlockDriverState *bs, bool flat,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
int GRAPH_RDLOCK
|
int GRAPH_RDLOCK
|
||||||
|
|||||||
@@ -839,7 +839,7 @@
|
|||||||
# }
|
# }
|
||||||
##
|
##
|
||||||
{ 'command': 'query-block', 'returns': ['BlockInfo'],
|
{ 'command': 'query-block', 'returns': ['BlockInfo'],
|
||||||
'allow-preconfig': true }
|
'allow-preconfig': true, 'coroutine': true }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @BlockDeviceTimedStats:
|
# @BlockDeviceTimedStats:
|
||||||
|
|||||||
Reference in New Issue
Block a user