From: "Benoît Canet" <benoit.canet@irqsave.net>
To: Jeff Cody <jcody@redhat.com>
Cc: kwolf@redhat.com, benoit.canet@irqsave.net, pkrempa@redhat.com,
famz@redhat.com, qemu-devel@nongnu.org, stefanha@redhat.com
Subject: Re: [Qemu-devel] [PATCH 5/5] block: extend block-commit to accept a string for the backing file
Date: Thu, 15 May 2014 14:26:57 +0200 [thread overview]
Message-ID: <20140515122657.GH2812@irqsave.net> (raw)
In-Reply-To: <50765faa0041d43d22dd14a0128d3b55850571ac.1400123059.git.jcody@redhat.com>
The Wednesday 14 May 2014 à 23:20:19 (-0400), Jeff Cody wrote :
> On some image chains, QEMU may not always be able to resolve the
> filenames properly, when updating the backing file of an image
> after a block commit.
>
> For instance, certain relative pathnames may fail, or drives may
> have been specified originally by file descriptor (e.g. /dev/fd/???),
> or a relative protocol pathname may have been used.
>
> In these instances, QEMU may lack the information to be able to make
> the correct choice, but the user or management layer most likely does
> have that knowledge.
>
> With this extension to the block-commit api, the user is able to change
> the backing file of the overlay image as part of the block-commit
> operation.
>
> This allows the change to be 'safe', in the sense that if the attempt
> to write the overlay image metadata fails, then the block-commit
> operation returns failure, without disrupting the guest.
>
> If the commit top is the active layer, then specifying the backing
> file string will be treated as an error (there is no overlay image
> to modify in that case).
>
> If a backing file string is not specified in the command, the backing
> file string to use is determined in the same manner as it was
> previously.
>
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
> block.c | 8 ++++++--
> block/commit.c | 9 ++++++---
> blockdev.c | 8 +++++++-
> include/block/block.h | 3 ++-
> include/block/block_int.h | 3 ++-
> qapi-schema.json | 18 ++++++++++++++++--
> qmp-commands.hx | 14 +++++++++++++-
> 7 files changed, 52 insertions(+), 11 deletions(-)
>
> diff --git a/block.c b/block.c
> index c4f77c2..7e63a1f 100644
> --- a/block.c
> +++ b/block.c
> @@ -2547,12 +2547,15 @@ typedef struct BlkIntermediateStates {
> *
> * base <- active
> *
> + * If backing_file_str is non-NULL, it will be used when modifying top's
> + * overlay image metadata.
> + *
> * Error conditions:
> * if active == top, that is considered an error
> *
> */
> int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
> - BlockDriverState *base)
> + BlockDriverState *base, const char *backing_file_str)
> {
> BlockDriverState *intermediate;
> BlockDriverState *base_bs = NULL;
> @@ -2604,7 +2607,8 @@ int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
> }
>
> /* success - we can delete the intermediate states, and link top->base */
> - ret = bdrv_change_backing_file(new_top_bs, base_bs->filename,
> + backing_file_str = backing_file_str ? backing_file_str : base_bs->filename;
> + ret = bdrv_change_backing_file(new_top_bs, backing_file_str,
> base_bs->drv ? base_bs->drv->format_name : "");
> if (ret) {
> goto exit;
> diff --git a/block/commit.c b/block/commit.c
> index 5c09f44..91517d3 100644
> --- a/block/commit.c
> +++ b/block/commit.c
> @@ -37,6 +37,7 @@ typedef struct CommitBlockJob {
> BlockdevOnError on_error;
> int base_flags;
> int orig_overlay_flags;
> + char *backing_file_str;
> } CommitBlockJob;
>
> static int coroutine_fn commit_populate(BlockDriverState *bs,
> @@ -141,7 +142,7 @@ wait:
>
> if (!block_job_is_cancelled(&s->common) && sector_num == end) {
> /* success */
> - ret = bdrv_drop_intermediate(active, top, base);
> + ret = bdrv_drop_intermediate(active, top, base, s->backing_file_str);
> }
>
> exit_free_buf:
> @@ -158,7 +159,7 @@ exit_restore_reopen:
> if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) {
> bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL);
> }
> -
> + g_free(s->backing_file_str);
> block_job_completed(&s->common, ret);
> }
>
> @@ -182,7 +183,7 @@ static const BlockJobDriver commit_job_driver = {
> void commit_start(BlockDriverState *bs, BlockDriverState *base,
> BlockDriverState *top, int64_t speed,
> BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
> - void *opaque, Error **errp)
> + void *opaque, const char *backing_file_str, Error **errp)
> {
> CommitBlockJob *s;
> BlockReopenQueue *reopen_queue = NULL;
> @@ -244,6 +245,8 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
> s->base_flags = orig_base_flags;
> s->orig_overlay_flags = orig_overlay_flags;
>
> + s->backing_file_str = g_strdup(backing_file_str);
> +
> s->on_error = on_error;
> s->common.co = qemu_coroutine_create(commit_run);
>
> diff --git a/blockdev.c b/blockdev.c
> index d8cb396..c0c7867 100644
> --- a/blockdev.c
> +++ b/blockdev.c
> @@ -1872,6 +1872,7 @@ void qmp_block_commit(const char *device,
> bool has_base_node_name, const char *base_node_name,
> bool has_top, const char *top,
> bool has_top_node_name, const char *top_node_name,
> + bool has_backing_file, const char *backing_file,
> bool has_speed, int64_t speed,
> Error **errp)
> {
> @@ -1951,11 +1952,16 @@ void qmp_block_commit(const char *device,
> }
>
> if (top_bs == bs) {
> + if (has_backing_file) {
> + error_setg(errp, "'backing-file' specified,"
> + " but 'top' is the active layer");
> + return;
> + }
> commit_active_start(bs, base_bs, speed, on_error, block_job_cb,
> bs, &local_err);
> } else {
> commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,
> - &local_err);
> + backing_file, &local_err);
I don't know QAPI well enough to be sure but are we certain that if
has_backing_file == false then backing_file == NULL and not some
random pointer ?
If am thinking to add has_backing_file ? backing_file : NULL here.
> }
> if (local_err != NULL) {
> error_propagate(errp, local_err);
> diff --git a/include/block/block.h b/include/block/block.h
> index 283a6f3..e7aeca6 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -266,7 +266,8 @@ int bdrv_change_backing_file(BlockDriverState *bs,
> const char *backing_file, const char *backing_fmt);
> void bdrv_register(BlockDriver *bdrv);
> int bdrv_drop_intermediate(BlockDriverState *active, BlockDriverState *top,
> - BlockDriverState *base);
> + BlockDriverState *base,
> + const char *backing_file_str);
> BlockDriverState *bdrv_find_overlay(BlockDriverState *active,
> BlockDriverState *bs);
> BlockDriverState *bdrv_find_base(BlockDriverState *bs);
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 9ffcb69..8e7dce7 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -428,13 +428,14 @@ void stream_start(BlockDriverState *bs, BlockDriverState *base,
> * @on_error: The action to take upon error.
> * @cb: Completion function for the job.
> * @opaque: Opaque pointer value passed to @cb.
> + * @backing_file_str: String to use as the backing file in @top's overlay
Miss a final dot to be like the other lines.
> * @errp: Error object.
> *
> */
> void commit_start(BlockDriverState *bs, BlockDriverState *base,
> BlockDriverState *top, int64_t speed,
> BlockdevOnError on_error, BlockDriverCompletionFunc *cb,
> - void *opaque, Error **errp);
> + void *opaque, const char *backing_file_str, Error **errp);
> /**
> * commit_active_start:
> * @bs: Active block device to be committed.
> diff --git a/qapi-schema.json b/qapi-schema.json
> index eddb2b8..ef775fe 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -2118,6 +2118,18 @@
> # topmost data to be committed down.
> # (Since 2.1)
> #
> +# @backing-file: #optional The backing file string to write into the overlay
> +# image of 'top'. If 'top' is the active layer,
> +# specifying a backing file string is an error. This
> +# backing file string is only written into the the
> +# image file metadata - internal structures inside
> +# QEMU are not updated, and the string is not validated.
> +# If not specified, QEMU will automatically determine
> +# the backing file string to use. Care should be taken
> +# when specifying the string, to specify a valid filename
> +# or protocol.
> +# (Since 2.1)
> +#
> # If top == base, that is an error.
> # If top == active, the job will not be completed by itself,
> # user needs to complete the job with the block-job-complete
> @@ -2130,7 +2142,6 @@
> # size of the smaller top, you can safely truncate it
> # yourself once the commit operation successfully completes.
> #
> -#
Spurious line removal.
> # @speed: #optional the maximum speed, in bytes per second
> #
> # Returns: Nothing on success
> @@ -2141,13 +2152,16 @@
> # If @speed is invalid, InvalidParameter
> # If both @base and @base-node-name are specified, GenericError
> # If both @top and @top-node-name are specified, GenericError
> +# If @top or @top-node-name is the active layer, and @backing-file is
> +# specified, GenericError
> #
> # Since: 1.3
> #
> ##
> { 'command': 'block-commit',
> 'data': { 'device': 'str', '*base': 'str', '*base-node-name': 'str',
> - '*top': 'str', '*top-node-name': 'str', '*speed': 'int' } }
> + '*top': 'str', '*top-node-name': 'str', '*backing-file': 'str',
> + '*speed': 'int' } }
>
> ##
> # @drive-backup
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 2b9b1dc..e2c446f 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -985,7 +985,7 @@ EQMP
>
> {
> .name = "block-commit",
> - .args_type = "device:B,base:s?,base-node-name:s?,top:s?,top-node-name:s?,speed:o?",
> + .args_type = "device:B,base:s?,base-node-name:s?,top:s?,top-node-name:s?,backing-file:s?,speed:o?",
> .mhandler.cmd_new = qmp_marshal_input_block_commit,
> },
>
> @@ -1021,6 +1021,18 @@ For 'top', either top or top-node-name must be set but not both.
> topmost data to be committed down.
> (json-string, optional) (Since 2.1)
>
> +- "backing-file": The backing file string to write into the overlay
> + image of 'top'. If 'top' is the active layer,
> + specifying a backing file string is an error. This
> + backing file string is only written into the the
> + image file metadata - internal structures inside
> + QEMU are not updated, and the string is not validated.
> + If not specified, QEMU will automatically determine
> + the backing file string to use. Care should be taken
> + when specifying the string, to specify a valid filename
> + or protocol.
> + (json-string, optional) (Since 2.1)
> +
> If top == base, that is an error.
> If top == active, the job will not be completed by itself,
> user needs to complete the job with the block-job-complete
> --
> 1.8.3.1
>
>
next prev parent reply other threads:[~2014-05-15 12:26 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-15 3:20 [Qemu-devel] [PATCH 0/5] block: Modify block-commit to use node-names Jeff Cody
2014-05-15 3:20 ` [Qemu-devel] [PATCH 1/5] block: Auto-generate node_names for each BDS entry Jeff Cody
2014-05-15 11:58 ` Benoît Canet
2014-05-15 12:06 ` Jeff Cody
2014-05-15 12:32 ` Benoît Canet
2014-05-15 12:37 ` Jeff Cody
2014-05-15 14:11 ` Eric Blake
2014-05-15 15:59 ` Eric Blake
2014-05-15 18:41 ` Jeff Cody
2014-05-15 19:12 ` Eric Blake
2014-05-16 9:39 ` Kevin Wolf
2014-05-16 11:35 ` Jeff Cody
2014-05-16 12:47 ` Eric Blake
2014-05-16 17:16 ` Kevin Wolf
2014-05-15 3:20 ` [Qemu-devel] [PATCH 2/5] block: add helper function to determine if a BDS is in a chain Jeff Cody
2014-05-15 11:48 ` Benoît Canet
2014-05-15 14:16 ` Eric Blake
2014-05-15 14:24 ` Kevin Wolf
2014-05-15 14:31 ` Jeff Cody
2014-05-15 3:20 ` [Qemu-devel] [PATCH 3/5] block: make 'top' argument to block-commit optional Jeff Cody
2014-05-15 11:47 ` Benoît Canet
2014-05-15 11:49 ` Jeff Cody
2014-05-15 15:07 ` Eric Blake
2014-05-15 3:20 ` [Qemu-devel] [PATCH 4/5] block: Accept node-name arguments for block-commit Jeff Cody
2014-05-15 12:09 ` Benoît Canet
2014-05-15 15:42 ` Eric Blake
2014-05-15 18:04 ` Jeff Cody
2014-05-15 3:20 ` [Qemu-devel] [PATCH 5/5] block: extend block-commit to accept a string for the backing file Jeff Cody
2014-05-15 12:26 ` Benoît Canet [this message]
2014-05-15 12:57 ` Eric Blake
2014-05-15 13:10 ` Jeff Cody
2014-05-15 13:14 ` Eric Blake
2014-05-15 16:06 ` Eric Blake
2014-05-15 18:22 ` Jeff Cody
2014-05-15 18:52 ` Eric Blake
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=20140515122657.GH2812@irqsave.net \
--to=benoit.canet@irqsave.net \
--cc=famz@redhat.com \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=pkrempa@redhat.com \
--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.