From 312fe09cc8af86c25a0c17162539589121e7d9a9 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Fri, 28 Oct 2016 10:08:19 +0300 Subject: block: Add 'base-node' parameter to the 'block-stream' command The way to specify the node from which to copy data in the block-stream operation is by using the 'base' parameter. This parameter however takes a file name, not a node name. Since we want to be able to perform this operation using only node names, this patch adds a new 'base-node' parameter. Signed-off-by: Alberto Garcia Reviewed-by: Kevin Wolf Signed-off-by: Kevin Wolf --- blockdev.c | 21 +++++++++++++++++++++ docs/qmp-commands.txt | 7 +++++-- hmp.c | 2 +- qapi/block-core.json | 8 ++++++-- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/blockdev.c b/blockdev.c index b5d4d6919f..ded13268f7 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2932,6 +2932,7 @@ static void block_job_cb(void *opaque, int ret) void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, bool has_base, const char *base, + bool has_base_node, const char *base_node, bool has_backing_file, const char *backing_file, bool has_speed, int64_t speed, bool has_on_error, BlockdevOnError on_error, @@ -2955,6 +2956,12 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); + if (has_base && has_base_node) { + error_setg(errp, "'base' and 'base-node' cannot be specified " + "at the same time"); + goto out; + } + if (has_base) { base_bs = bdrv_find_backing_image(bs, base); if (base_bs == NULL) { @@ -2965,6 +2972,20 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, base_name = base; } + if (has_base_node) { + base_bs = bdrv_lookup_bs(NULL, base_node, errp); + if (!base_bs) { + goto out; + } + if (bs == base_bs || !bdrv_chain_contains(bs, base_bs)) { + error_setg(errp, "Node '%s' is not a backing image of '%s'", + base_node, device); + goto out; + } + assert(bdrv_get_aio_context(base_bs) == aio_context); + base_name = base_bs->filename; + } + /* 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)) { diff --git a/docs/qmp-commands.txt b/docs/qmp-commands.txt index a4732a570c..6afa87298d 100644 --- a/docs/qmp-commands.txt +++ b/docs/qmp-commands.txt @@ -750,8 +750,11 @@ Arguments: - "job-id": Identifier for the newly-created block job. If omitted, the device name will be used. (json-string, optional) - "device": The device name or node-name of a root node (json-string) -- "base": The file name of the backing image above which copying starts - (json-string, optional) +- "base": The file name of the backing image above which copying starts. + It cannot be set if 'base-node' is also set (json-string, optional) +- "base-node": the node name of the backing image above which copying starts. + It cannot be set if 'base' is also set. + (json-string, optional) (Since 2.8) - "backing-file": The backing file string to write into the active layer. This filename is not validated. diff --git a/hmp.c b/hmp.c index 00af4230bf..b5e3f54534 100644 --- a/hmp.c +++ b/hmp.c @@ -1571,7 +1571,7 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict) int64_t speed = qdict_get_try_int(qdict, "speed", 0); qmp_block_stream(false, NULL, device, base != NULL, base, false, NULL, - qdict_haskey(qdict, "speed"), speed, + false, NULL, qdict_haskey(qdict, "speed"), speed, true, BLOCKDEV_ON_ERROR_REPORT, &error); hmp_handle_error(mon, &error); diff --git a/qapi/block-core.json b/qapi/block-core.json index d7a029cfd5..3592a9d7ad 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1484,7 +1484,11 @@ # # @device: the device or node name of the top image # -# @base: #optional the common backing file name +# @base: #optional the common backing file name. +# It cannot be set if @base-node is also set. +# +# @base-node: #optional the node name of the backing file. +# It cannot be set if @base is also set. (Since 2.8) # # @backing-file: #optional The backing file string to write into the top # image. This filename is not validated. @@ -1511,7 +1515,7 @@ ## { 'command': 'block-stream', 'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', - '*backing-file': 'str', '*speed': 'int', + '*base-node': 'str', '*backing-file': 'str', '*speed': 'int', '*on-error': 'BlockdevOnError' } } ## -- cgit v1.2.3