qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 5/5] block: extend block-commit to accept a stri


From: Benoît Canet
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
User-agent: Mutt/1.5.23 (2014-03-12)

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 <address@hidden>
> ---
>  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
> 
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]