[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 09/11] block: add ability for block-stream to use
From: |
Jeff Cody |
Subject: |
[Qemu-devel] [PATCH v2 09/11] block: add ability for block-stream to use node-name |
Date: |
Tue, 27 May 2014 10:28:39 -0400 |
This adds the ability for block-stream to use node-name arguments
for base, to specify the backing image to stream from.
Both 'base' and 'base-node-name' are optional, but mutually exclusive.
Either can be specified, but not both together.
The argument for "device" is now optional as well, so long as
base-node-name is specified. From the node-name, we can determine
the full device chain.
Signed-off-by: Jeff Cody <address@hidden>
---
blockdev.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++----------
hmp-commands.hx | 2 +-
hmp.c | 10 +++++----
qapi-schema.json | 15 ++++++++++----
qmp-commands.hx | 2 +-
5 files changed, 70 insertions(+), 21 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 983c7da..a4468b4 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1870,22 +1870,52 @@ static void block_job_cb(void *opaque, int ret)
bdrv_put_ref_bh_schedule(bs);
}
-void qmp_block_stream(const char *device, bool has_base,
- const char *base, bool has_speed, int64_t speed,
+void qmp_block_stream(bool has_device, const char *device,
+ bool has_base, const char *base,
+ bool has_base_node_name, const char *base_node_name,
+ bool has_speed, int64_t speed,
bool has_on_error, BlockdevOnError on_error,
Error **errp)
{
- BlockDriverState *bs;
+ BlockDriverState *bs = NULL;
BlockDriverState *base_bs = NULL;
Error *local_err = NULL;
+ const char *base_name;
if (!has_on_error) {
on_error = BLOCKDEV_ON_ERROR_REPORT;
}
- bs = bdrv_find(device);
+ if (has_base && has_base_node_name) {
+ error_setg(errp, "'base' and 'base-node-name' are mutually exclusive");
+ return;
+ }
+
+ if (!has_base_node_name && !has_device) {
+ error_setg(errp, "'device' required if 'base-node-name' not
specified");
+ return;
+ }
+
+
+ if (has_device) {
+ bs = bdrv_find(device);
+ if (!bs) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
+ }
+ }
+
+ if (has_base_node_name) {
+ base_bs = bdrv_lookup_bs(NULL, base_node_name, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+ bs = bs ?: bdrv_find_active(base_bs);
+ }
+
if (!bs) {
- error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ error_setg(errp, "Could not find active layer");
return;
}
@@ -1893,15 +1923,25 @@ void qmp_block_stream(const char *device, bool has_base,
return;
}
- if (base) {
+ if (has_base) {
base_bs = bdrv_find_backing_image(bs, base);
- if (base_bs == NULL) {
- error_set(errp, QERR_BASE_NOT_FOUND, base);
- return;
- }
}
- stream_start(bs, base_bs, base, has_speed ? speed : 0,
+ if (base_bs == NULL && (has_base || has_base_node_name)) {
+ error_set(errp, QERR_BASE_NOT_FOUND, base);
+ return;
+ }
+
+ base_name = base_bs ? base_bs->filename : NULL;
+
+ /* Verify that 'base' is in the same chain as 'top', if 'base' was
+ * specified */
+ if (base_bs && !bdrv_chain_contains(bs, base_bs)) {
+ error_setg(errp, "'%s' and 'top' are not in the same chain", device);
+ return;
+ }
+
+ stream_start(bs, base_bs, base_name, has_speed ? speed : 0,
on_error, block_job_cb, bs, &local_err);
if (local_err) {
error_propagate(errp, local_err);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 2e462c0..17eda87 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -76,7 +76,7 @@ ETEXI
{
.name = "block_stream",
- .args_type = "device:B,speed:o?,base:s?",
+ .args_type = "device:B?,speed:o?,base:s?,base-node-name:s?",
.params = "device [speed [base]]",
.help = "copy data from a backing file into a block device",
.mhandler.cmd = hmp_block_stream,
diff --git a/hmp.c b/hmp.c
index ccc35d4..122aa29 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1168,11 +1168,13 @@ void hmp_block_set_io_throttle(Monitor *mon, const
QDict *qdict)
void hmp_block_stream(Monitor *mon, const QDict *qdict)
{
Error *error = NULL;
- const char *device = qdict_get_str(qdict, "device");
- const char *base = qdict_get_try_str(qdict, "base");
- int64_t speed = qdict_get_try_int(qdict, "speed", 0);
+ const char *device = qdict_get_str(qdict, "device");
+ const char *base = qdict_get_try_str(qdict, "base");
+ const char *base_node_name = qdict_get_try_str(qdict, "base_node_name");
+ int64_t speed = qdict_get_try_int(qdict, "speed", 0);
- qmp_block_stream(device, base != NULL, base,
+ qmp_block_stream(device != NULL, device, base != NULL, base,
+ base_node_name != NULL, base_node_name,
qdict_haskey(qdict, "speed"), speed,
true, BLOCKDEV_ON_ERROR_REPORT, &error);
diff --git a/qapi-schema.json b/qapi-schema.json
index f790e9a..63e74c5 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2600,9 +2600,16 @@
# On successful completion the image file is updated to drop the backing file
# and the BLOCK_JOB_COMPLETED event is emitted.
#
-# @device: the device name
+# @device: #optional The device name. Optional only if @base-node-name
+# is used.
+#
+# For 'base', either @base or @base-node-name may be set but not both. If
+# neither is specified, this is the deepest backing image
+#
+# @base: #optional the common backing file name
#
-# @base: #optional the common backing file name
+# @base-node-name: #optional the block driver state node name of the
+# common backing file. (Since 2.1)
#
# @speed: #optional the maximum speed, in bytes per second
#
@@ -2616,8 +2623,8 @@
# Since: 1.1
##
{ 'command': 'block-stream',
- 'data': { 'device': 'str', '*base': 'str', '*speed': 'int',
- '*on-error': 'BlockdevOnError' } }
+ 'data': { '*device': 'str', '*base': 'str', '*base-node-name': 'str',
+ '*speed': 'int', '*on-error': 'BlockdevOnError' } }
##
# @block-job-set-speed:
diff --git a/qmp-commands.hx b/qmp-commands.hx
index f4fafda..903c63a 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -979,7 +979,7 @@ EQMP
{
.name = "block-stream",
- .args_type = "device:B,base:s?,speed:o?,on-error:s?",
+ .args_type =
"device:B?,base:s?,base-node-name:s?,speed:o?,on-error:s?",
.mhandler.cmd_new = qmp_marshal_input_block_stream,
},
--
1.8.3.1
- Re: [Qemu-devel] [PATCH v2 04/11] block: add helper function to find the active layer of any BDS, (continued)
- [Qemu-devel] [PATCH v2 05/11] block: simplify bdrv_find_base(), Jeff Cody, 2014/05/27
- [Qemu-devel] [PATCH v2 06/11] block: make 'top' argument to block-commit optional, Jeff Cody, 2014/05/27
- [Qemu-devel] [PATCH v2 08/11] block: extend block-commit to accept a string for the backing file, Jeff Cody, 2014/05/27
- [Qemu-devel] [PATCH v2 07/11] block: Accept node-name arguments for block-commit, Jeff Cody, 2014/05/27
- [Qemu-devel] [PATCH v2 09/11] block: add ability for block-stream to use node-name,
Jeff Cody <=
- [Qemu-devel] [PATCH v2 10/11] block: add backing-file option to block-stream, Jeff Cody, 2014/05/27
- [Qemu-devel] [PATCH v2 11/11] block: add QAPI command to allow live backing file change, Jeff Cody, 2014/05/27