[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 14/29] block: Support streaming to an intermediate la
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 14/29] block: Support streaming to an intermediate layer |
Date: |
Mon, 31 Oct 2016 18:25:43 +0100 |
From: Alberto Garcia <address@hidden>
This makes sure that the image we are streaming into is open in
read-write mode during the operation.
Operation blockers are also set in all intermediate nodes, since they
will be removed from the chain afterwards.
Finally, this also unblocks the stream operation in backing files.
Signed-off-by: Alberto Garcia <address@hidden>
Reviewed-by: Kevin Wolf <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block.c | 4 +++-
block/stream.c | 24 ++++++++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/block.c b/block.c
index 2c87186..c19c6c6 100644
--- a/block.c
+++ b/block.c
@@ -1428,9 +1428,11 @@ void bdrv_set_backing_hd(BlockDriverState *bs,
BlockDriverState *backing_hd)
backing_hd->drv ? backing_hd->drv->format_name : "");
bdrv_op_block_all(backing_hd, bs->backing_blocker);
- /* Otherwise we won't be able to commit due to check in bdrv_commit */
+ /* Otherwise we won't be able to commit or stream */
bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET,
bs->backing_blocker);
+ bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_STREAM,
+ bs->backing_blocker);
/*
* We do backup in 3 ways:
* 1. drive backup
diff --git a/block/stream.c b/block/stream.c
index 3187481..b8ab89a 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -37,6 +37,7 @@ typedef struct StreamBlockJob {
BlockDriverState *base;
BlockdevOnError on_error;
char *backing_file_str;
+ int bs_flags;
} StreamBlockJob;
static int coroutine_fn stream_populate(BlockBackend *blk,
@@ -81,6 +82,11 @@ static void stream_complete(BlockJob *job, void *opaque)
bdrv_set_backing_hd(bs, base);
}
+ /* Reopen the image back in read-only mode if necessary */
+ if (s->bs_flags != bdrv_get_flags(bs)) {
+ bdrv_reopen(bs, s->bs_flags, NULL);
+ }
+
g_free(s->backing_file_str);
block_job_completed(&s->common, data->ret);
g_free(data);
@@ -220,6 +226,8 @@ void stream_start(const char *job_id, BlockDriverState *bs,
BlockCompletionFunc *cb, void *opaque, Error **errp)
{
StreamBlockJob *s;
+ BlockDriverState *iter;
+ int orig_bs_flags;
s = block_job_create(job_id, &stream_job_driver, bs, speed,
cb, opaque, errp);
@@ -227,8 +235,24 @@ void stream_start(const char *job_id, BlockDriverState *bs,
return;
}
+ /* Make sure that the image is opened in read-write mode */
+ orig_bs_flags = bdrv_get_flags(bs);
+ if (!(orig_bs_flags & BDRV_O_RDWR)) {
+ if (bdrv_reopen(bs, orig_bs_flags | BDRV_O_RDWR, errp) != 0) {
+ block_job_unref(&s->common);
+ return;
+ }
+ }
+
+ /* Block all intermediate nodes between bs and base, because they
+ * will disappear from the chain after this operation */
+ for (iter = backing_bs(bs); iter && iter != base; iter = backing_bs(iter))
{
+ block_job_add_bdrv(&s->common, iter);
+ }
+
s->base = base;
s->backing_file_str = g_strdup(backing_file_str);
+ s->bs_flags = orig_bs_flags;
s->on_error = on_error;
s->common.co = qemu_coroutine_create(stream_run, s);
--
1.8.3.1
- [Qemu-block] [PULL 06/29] block: Add bdrv_drain_all_{begin,end}(), (continued)
- [Qemu-block] [PULL 06/29] block: Add bdrv_drain_all_{begin,end}(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 03/29] block/ssh: Add InetSocketAddress and accept it, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 02/29] util/qemu-sockets: Make inet_connect_saddr() public, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 08/29] block: Add block_job_add_bdrv(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 07/29] block: Pause all jobs during bdrv_reopen_multiple(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 09/29] block: Use block_job_add_bdrv() in mirror_start_job(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 12/29] block: Block all nodes involved in the block-commit operation, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 10/29] block: Use block_job_add_bdrv() in backup_start(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 11/29] block: Check blockers in all nodes involved in a block-commit job, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 13/29] block: Block all intermediate nodes in commit_active_start(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 14/29] block: Support streaming to an intermediate layer,
Kevin Wolf <=
- [Qemu-block] [PULL 15/29] block: Add QMP support for streaming to an intermediate layer, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 16/29] docs: Document how to stream to an intermediate layer, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 17/29] qemu-iotests: Test streaming to an intermediate layer, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 18/29] qemu-iotests: Test block-stream operations in parallel, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 20/29] qemu-iotests: Test block-stream and block-commit in parallel, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 19/29] qemu-iotests: Test overlapping stream and commit operations, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 22/29] qemu-iotests: Test streaming to a Quorum child, Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 21/29] qemu-iotests: Add iotests.supports_quorum(), Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 24/29] qemu-iotests: Test the 'base-node' parameter of 'block-stream', Kevin Wolf, 2016/10/31
- [Qemu-block] [PULL 23/29] block: Add 'base-node' parameter to the 'block-stream' command, Kevin Wolf, 2016/10/31