diff options
author | Alberto Garcia <berto@igalia.com> | 2016-10-28 10:08:19 +0300 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2016-10-31 16:52:39 +0100 |
commit | 312fe09cc8af86c25a0c17162539589121e7d9a9 (patch) | |
tree | 02816e1079b4d5f0a64cfc102378449a13502baf /blockdev.c | |
parent | 48361afba902ab90a9f667a94f863bafd1417d2e (diff) |
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 <berto@igalia.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'blockdev.c')
-rw-r--r-- | blockdev.c | 21 |
1 files changed, 21 insertions, 0 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)) { |