From: Max Reitz <mreitz@redhat.com>
To: Alberto Garcia <berto@igalia.com>, qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org, Kevin Wolf <kwolf@redhat.com>,
Eric Blake <eblake@redhat.com>,
Stefan Hajnoczi <stefanha@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v9 06/11] block: Support streaming to an intermediate layer
Date: Wed, 27 Apr 2016 15:04:57 +0200 [thread overview]
Message-ID: <5720B8F9.8080504@redhat.com> (raw)
In-Reply-To: <3b38569c5caeb92ae2fd6b3c6c7272bcce2dcf85.1459776815.git.berto@igalia.com>
[-- Attachment #1.1: Type: text/plain, Size: 7140 bytes --]
On 04.04.2016 15:43, Alberto Garcia wrote:
> This makes sure that the image we are steaming into is open in
> read-write mode during the operation.
>
> The block job is created on the destination image, but operation
> blockers are also set on the active layer. We do this in order to
> prevent other block jobs from running in parallel in the same chain.
> See here for details on why that is currently not supported:
>
> [Qemu-block] RFC: Status of the intermediate block streaming work
> https://lists.gnu.org/archive/html/qemu-block/2015-12/msg00180.html
>
> Finally, this also unblocks the stream operation in backing files.
>
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> ---
> block.c | 4 +++-
> block/stream.c | 39 ++++++++++++++++++++++++++++++++++++++-
> blockdev.c | 2 +-
> include/block/block_int.h | 5 ++++-
> 4 files changed, 46 insertions(+), 4 deletions(-)
>
> diff --git a/block.c b/block.c
> index 48638c9..f7698a1 100644
> --- a/block.c
> +++ b/block.c
> @@ -1252,9 +1252,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);
> out:
> bdrv_refresh_limits(bs, NULL);
> }
> diff --git a/block/stream.c b/block/stream.c
> index 332b9a1..ac02ddf 100644
> --- a/block/stream.c
> +++ b/block/stream.c
> @@ -35,8 +35,10 @@ typedef struct StreamBlockJob {
> BlockJob common;
> RateLimit limit;
> BlockDriverState *base;
> + BlockDriverState *active;
> BlockdevOnError on_error;
> char *backing_file_str;
> + int bs_flags;
> } StreamBlockJob;
>
> static int coroutine_fn stream_populate(BlockDriverState *bs,
> @@ -66,6 +68,11 @@ static void stream_complete(BlockJob *job, void *opaque)
> StreamCompleteData *data = opaque;
> BlockDriverState *base = s->base;
>
> + if (s->active) {
> + bdrv_op_unblock_all(s->active, s->common.blocker);
> + bdrv_unref(s->active);
> + }
> +
> if (!block_job_is_cancelled(&s->common) && data->reached_end &&
> data->ret == 0) {
> const char *base_id = NULL, *base_fmt = NULL;
> @@ -79,6 +86,11 @@ static void stream_complete(BlockJob *job, void *opaque)
> bdrv_set_backing_hd(job->bs, base);
> }
>
> + /* Reopen the image back in read-only mode if necessary */
> + if (s->bs_flags != bdrv_get_flags(job->bs)) {
> + bdrv_reopen(job->bs, s->bs_flags, NULL);
> + }
> +
> g_free(s->backing_file_str);
> block_job_completed(&s->common, data->ret);
> g_free(data);
> @@ -216,13 +228,15 @@ static const BlockJobDriver stream_job_driver = {
> .set_speed = stream_set_speed,
> };
>
> -void stream_start(BlockDriverState *bs, BlockDriverState *base,
> +void stream_start(BlockDriverState *bs, BlockDriverState *active,
> + BlockDriverState *base,
> const char *backing_file_str, int64_t speed,
> BlockdevOnError on_error,
> BlockCompletionFunc *cb,
> void *opaque, Error **errp)
> {
> StreamBlockJob *s;
> + int orig_bs_flags;
>
> if ((on_error == BLOCKDEV_ON_ERROR_STOP ||
> on_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
> @@ -231,13 +245,36 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
> 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) {
> + return;
> + }
> + }
> +
> s = block_job_create(&stream_job_driver, bs, speed, cb, opaque, errp);
> if (!s) {
> return;
> }
>
> + /* If we are streaming to an intermediate image, we need to block
> + * the active layer. Due to a race condition, having several block
> + * jobs running in the same chain is broken and we currently don't
> + * support it. See here for details:
> + * https://lists.gnu.org/archive/html/qemu-block/2015-12/msg00180.html
> + */
> + if (active) {
> + bdrv_op_block_all(active, s->common.blocker);
block_job_create() unblocks BLOCK_OP_TYPE_DATAPLANE. Maybe this should
do the same?
No other objections from me.
Max
> + /* Hold a reference to the active layer, otherwise
> + * bdrv_close_all() will destroy it if we shut down the VM */
> + bdrv_ref(active);
> + }
> +
> s->base = base;
> + s->active = active;
> 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);
> diff --git a/blockdev.c b/blockdev.c
> index d1f5dfb..2e7712e 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -3038,7 +3038,7 @@ void qmp_block_stream(const char *device,
> /* backing_file string overrides base bs filename */
> base_name = has_backing_file ? backing_file : base_name;
>
> - stream_start(bs, base_bs, base_name, has_speed ? speed : 0,
> + stream_start(bs, NULL, 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/include/block/block_int.h b/include/block/block_int.h
> index 10d8759..0a53d5f 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -597,6 +597,8 @@ int is_windows_drive(const char *filename);
> /**
> * stream_start:
> * @bs: Block device to operate on.
> + * @active: The active layer of the chain where @bs belongs, or %NULL
> + * if @bs is already the topmost device.
> * @base: Block device that will become the new base, or %NULL to
> * flatten the whole backing file chain onto @bs.
> * @base_id: The file name that will be written to @bs as the new
> @@ -613,7 +615,8 @@ int is_windows_drive(const char *filename);
> * streaming job, the backing file of @bs will be changed to
> * @base_id in the written image and to @base in the live BlockDriverState.
> */
> -void stream_start(BlockDriverState *bs, BlockDriverState *base,
> +void stream_start(BlockDriverState *bs, BlockDriverState *active,
> + BlockDriverState *base,
> const char *base_id, int64_t speed, BlockdevOnError on_error,
> BlockCompletionFunc *cb,
> void *opaque, Error **errp);
>
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
next prev parent reply other threads:[~2016-04-27 13:05 UTC|newest]
Thread overview: 56+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-04 13:43 [Qemu-devel] [PATCH for-2.7 v9 00/11] Support streaming to an intermediate layer Alberto Garcia
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 01/11] block: keep a list of block jobs Alberto Garcia
2016-04-27 11:59 ` Max Reitz
2016-04-29 14:22 ` Kevin Wolf
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 02/11] block: use the block job list in bdrv_drain_all() Alberto Garcia
2016-04-27 12:04 ` Max Reitz
2016-04-27 12:08 ` Alberto Garcia
2016-04-29 14:25 ` Kevin Wolf
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 03/11] block: use the block job list in qmp_query_block_jobs() Alberto Garcia
2016-04-27 12:09 ` Max Reitz
2016-04-29 14:32 ` Kevin Wolf
2016-05-02 13:06 ` Alberto Garcia
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 04/11] block: use the block job list in bdrv_close() Alberto Garcia
2016-04-27 12:14 ` Max Reitz
2016-04-29 14:38 ` Kevin Wolf
2016-05-02 13:42 ` Alberto Garcia
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 05/11] block: allow block jobs in any arbitrary node Alberto Garcia
2016-04-27 12:30 ` Max Reitz
2016-04-27 14:59 ` Alberto Garcia
2016-04-29 15:00 ` Kevin Wolf
2016-05-06 10:00 ` Alberto Garcia
2016-05-06 17:54 ` John Snow
2016-05-09 7:06 ` Kevin Wolf
2016-05-09 11:59 ` Alberto Garcia
2016-04-29 15:25 ` Eric Blake
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 06/11] block: Support streaming to an intermediate layer Alberto Garcia
2016-04-27 13:04 ` Max Reitz [this message]
2016-04-28 9:23 ` Alberto Garcia
2016-04-29 15:07 ` Kevin Wolf
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 07/11] block: Add QMP support for " Alberto Garcia
2016-04-27 13:34 ` Max Reitz
2016-04-28 12:20 ` Alberto Garcia
2016-04-29 15:18 ` Kevin Wolf
2016-05-03 12:50 ` Alberto Garcia
2016-05-03 13:23 ` Kevin Wolf
2016-05-03 13:33 ` Alberto Garcia
2016-05-03 13:48 ` Kevin Wolf
2016-05-03 15:09 ` Alberto Garcia
[not found] ` <w517fezo0al.fsf@maestria.local.igalia.com>
2016-05-12 15:04 ` Kevin Wolf
[not found] ` <w514ma3nwbl.fsf@maestria.local.igalia.com>
2016-05-12 15:28 ` Kevin Wolf
2016-05-17 14:26 ` Alberto Garcia
2016-05-17 14:47 ` Kevin Wolf
2016-05-17 14:54 ` Alberto Garcia
2016-04-29 15:11 ` Kevin Wolf
2016-05-03 12:53 ` Alberto Garcia
2016-05-03 13:18 ` Kevin Wolf
2016-05-03 13:29 ` Alberto Garcia
2016-04-29 15:29 ` Eric Blake
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 08/11] docs: Document how to stream " Alberto Garcia
2016-04-04 13:43 ` [Qemu-devel] [PATCH v9 09/11] qemu-iotests: test streaming " Alberto Garcia
2016-04-04 13:44 ` [Qemu-devel] [PATCH v9 10/11] qemu-iotests: test overlapping block-stream operations Alberto Garcia
2016-04-27 13:48 ` Max Reitz
2016-04-27 15:02 ` Alberto Garcia
2016-04-04 13:44 ` [Qemu-devel] [PATCH v9 11/11] qemu-iotests: test non-overlapping " Alberto Garcia
2016-04-27 13:50 ` Max Reitz
2016-04-08 10:00 ` [Qemu-devel] [PATCH for-2.7 v9 00/11] Support streaming to an intermediate layer Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5720B8F9.8080504@redhat.com \
--to=mreitz@redhat.com \
--cc=berto@igalia.com \
--cc=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.