Skip to content

Commit

Permalink
block: Add QMP support for streaming to an intermediate layer
Browse files Browse the repository at this point in the history
This patch makes the 'device' parameter of the 'block-stream' command
accept a node name that is not a root node. The presence of this
feature can't be directly tested with introspection; soon we'll
introduce a 'base-node' parameter whose presence can be checked for
this purpose.

In addition to that, operation blockers will be checked in all
intermediate nodes between the top and the base node.

Signed-off-by: Alberto Garcia <[email protected]>
Signed-off-by: Kevin Wolf <[email protected]>
  • Loading branch information
bertogg authored and kevmw committed Oct 31, 2016
1 parent 61b49e4 commit 554b614
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
15 changes: 9 additions & 6 deletions blockdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -2937,7 +2937,7 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
bool has_on_error, BlockdevOnError on_error,
Error **errp)
{
BlockDriverState *bs;
BlockDriverState *bs, *iter;
BlockDriverState *base_bs = NULL;
AioContext *aio_context;
Error *local_err = NULL;
Expand All @@ -2947,18 +2947,14 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
on_error = BLOCKDEV_ON_ERROR_REPORT;
}

bs = qmp_get_root_bs(device, errp);
bs = bdrv_lookup_bs(device, device, errp);
if (!bs) {
return;
}

aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);

if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_STREAM, errp)) {
goto out;
}

if (has_base) {
base_bs = bdrv_find_backing_image(bs, base);
if (base_bs == NULL) {
Expand All @@ -2969,6 +2965,13 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device,
base_name = base;
}

/* Check for op blockers in the whole chain between bs and base */
for (iter = bs; iter && iter != base_bs; iter = backing_bs(iter)) {
if (bdrv_op_is_blocked(iter, BLOCK_OP_TYPE_STREAM, errp)) {
goto out;
}
}

/* if we are streaming the entire chain, the result will have no backing
* file, and specifying one is therefore an error */
if (base_bs == NULL && has_backing_file) {
Expand Down
13 changes: 10 additions & 3 deletions qapi/block-core.json
Original file line number Diff line number Diff line change
Expand Up @@ -1464,6 +1464,13 @@
# with query-block-jobs. The operation can be stopped before it has completed
# using the block-job-cancel command.
#
# The node that receives the data is called the top image, can be located in
# any part of the chain (but always above the base image; see below) and can be
# specified using its device or node name. Earlier qemu versions only allowed
# 'device' to name the top level node; presence of the 'base-node' parameter
# during introspection can be used as a witness of the enhanced semantics
# of 'device'.
#
# If a base file is specified then sectors are not copied from that base file and
# its backing chain. When streaming completes the image file will have the base
# file as its backing file. This can be used to stream a subset of the backing
Expand All @@ -1475,12 +1482,12 @@
# @job-id: #optional identifier for the newly-created block job. If
# omitted, the device name will be used. (Since 2.7)
#
# @device: the device name or node-name of a root node
# @device: the device or node name of the top image
#
# @base: #optional the common backing file name
#
# @backing-file: #optional The backing file string to write into the active
# layer. This filename is not validated.
# @backing-file: #optional The backing file string to write into the top
# image. This filename is not validated.
#
# If a pathname string is such that it cannot be
# resolved by QEMU, that means that subsequent QMP or
Expand Down

0 comments on commit 554b614

Please sign in to comment.