All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Alberto Garcia <berto@igalia.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org,
	Max Reitz <mreitz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH 01/13] block: Allow freezing BdrvChild links
Date: Tue, 12 Feb 2019 15:47:47 +0100	[thread overview]
Message-ID: <20190212144747.GC5283@localhost.localdomain> (raw)
In-Reply-To: <ae441a8c27cae1a80e57fb6d291fe95667da0c76.1547739122.git.berto@igalia.com>

Am 17.01.2019 um 16:33 hat Alberto Garcia geschrieben:
> Our permission system is useful to define what operations are allowed
> on a certain block node and includes things like BLK_PERM_WRITE or
> BLK_PERM_RESIZE among others.
> 
> One of the permissions is BLK_PERM_GRAPH_MOD which allows "changing
> the node that this BdrvChild points to". The exact meaning of this has
> never been very clear, but it can be understood as "change any of the
> links connected to the node". This can be used to prevent changing a
> backing link, but it's too coarse.
> 
> This patch adds a new 'frozen' attribute to BdrvChild, which forbids
> detaching the link from the node it points to, and new API to freeze
> and unfreeze a backing chain.
> 
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> ---
>  block.c                   | 66 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/block/block.h     |  5 ++++
>  include/block/block_int.h |  5 ++++
>  3 files changed, 76 insertions(+)

> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index f605622216..fd0e88d17a 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -661,6 +661,11 @@ struct BdrvChild {
>       */
>      uint64_t shared_perm;
>  
> +    /*
> +     * This link is frozen: the child cannot be detached from the parent.
> +     */
> +    bool frozen;
> +
>      QLIST_ENTRY(BdrvChild) next;
>      QLIST_ENTRY(BdrvChild) next_parent;
>  };

Is this enough, or should it prevent both detaching from the parent _and_
changing the child node it points to?

> diff --git a/block.c b/block.c
> index 4f5ff2cc12..51fac086c7 100644
> --- a/block.c
> +++ b/block.c
> @@ -2062,6 +2062,8 @@ static void bdrv_replace_child_noperm(BdrvChild *child,
>      BlockDriverState *old_bs = child->bs;
>      int i;
>  
> +    assert(!child->frozen);
> +
>      if (old_bs && new_bs) {
>          assert(bdrv_get_aio_context(old_bs) == bdrv_get_aio_context(new_bs));
>      }

Okay, this does forbid both, so I think it's just the comment that needs
to be changed in the hunk above.

In order to avoid running into an assertion failure, we need to detect
the situation in all callers, or audit that it can never happen:

* bdrv_replace_child()
    * bdrv_root_attach_child(): Creates a new BdrvChild, never frozen
    * bdrv_detach_child()
        * bdrv_root_unref_child()
            * blk_remove_bs(): Not a backing child, safe
            * block_job_remove_all_bdrv(): Not a backing child, safe
            * bdrv_unref_child()
                * bdrv_set_backing_hd(): Adds a check
                * bdrv_close():  Not a backing child, safe
                * bdrv_open_driver(): Not a backing child, safe
    * bdrv_drop_intermediate(): Adds a check, though see below

* bdrv_replace_node(): Missing check?
    * bdrv_append()
      For example, mirror_start_job() calls it to insert the
      mirror_top_bs node above the source, which could be anywhere in
      the graph. This may involve changing the target of backing links.
    * Other callers looks questionable, too

bdrv_replace_node() can return an error, so I think we should add a
check there.

For the bdrv_replace_child() call chain, the state looks better, but it
was tedious to verify and future additions could easily forget to add
the check. I wonder if we should allow some function there to return
errors so that we don't have to add the checks in the outermost
functions of the call chain.

> @@ -3813,6 +3819,62 @@ BlockDriverState *bdrv_find_base(BlockDriverState *bs)
>  }
>  
>  /*
> + * Return true if at least one of the backing links between @bs and
> + * @base is frozen. @errp is set if that's the case.
> + */
> +bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
> +                                  Error **errp)
> +{
> +    BlockDriverState *i;
> +
> +    for (i = bs; i != base && i->backing; i = backing_bs(i)) {
> +        if (i->backing->frozen) {
> +            error_setg(errp, "Cannot remove link from '%s' to '%s'",

Maybe s/remove/change/?

Might also be worth including the BdrvChild name in the error message.

> +                       i->node_name, backing_bs(i)->node_name);
> +            return true;
> +        }
> +    }
> +
> +    return false;
> +}

> @@ -3861,6 +3923,10 @@ int bdrv_drop_intermediate(BlockDriverState *top, BlockDriverState *base,
>          goto exit;
>      }
>  
> +    if (bdrv_is_backing_chain_frozen(top, base, NULL)) {
> +        goto exit;
> +    }
> +
>      /* If 'base' recursively inherits from 'top' then we should set
>       * base->inherits_from to top->inherits_from after 'top' and all
>       * other intermediate nodes have been dropped.

bdrv_drop_intermediate() doesn't change the links between in the chain
between top and base, but the links between the parents of top and top
are changed to point to base instead.

I think this is checking the wrong thing.

Kevin

  reply	other threads:[~2019-02-12 14:47 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-01-17 15:33 [Qemu-devel] [PATCH 00/13] Add a 'x-blockdev-reopen' QMP command Alberto Garcia
2019-01-17 15:33 ` [Qemu-devel] [PATCH 01/13] block: Allow freezing BdrvChild links Alberto Garcia
2019-02-12 14:47   ` Kevin Wolf [this message]
2019-02-14 14:13     ` Alberto Garcia
2019-02-14 15:52       ` Kevin Wolf
2019-02-18 13:35         ` Alberto Garcia
2019-01-17 15:33 ` [Qemu-devel] [PATCH 02/13] block: Freeze the backing chain for the duration of the commit job Alberto Garcia
2019-02-12 14:54   ` Kevin Wolf
2019-02-14 15:21     ` Alberto Garcia
2019-02-14 15:45       ` Kevin Wolf
2019-01-17 15:33 ` [Qemu-devel] [PATCH 03/13] block: Freeze the backing chain for the duration of the mirror job Alberto Garcia
2019-01-17 15:33 ` [Qemu-devel] [PATCH 04/13] block: Freeze the backing chain for the duration of the stream job Alberto Garcia
2019-02-12 15:15   ` Kevin Wolf
2019-02-12 16:06     ` Alberto Garcia
2019-01-17 15:33 ` [Qemu-devel] [PATCH 05/13] block: Add 'keep_old_opts' parameter to bdrv_reopen_queue() Alberto Garcia
2019-01-17 15:33 ` [Qemu-devel] [PATCH 06/13] block: Handle child references in bdrv_reopen_queue() Alberto Garcia
2019-02-12 16:28   ` Kevin Wolf
2019-02-12 16:55     ` [Qemu-devel] [Qemu-block] " Kevin Wolf
2019-02-19 16:00     ` [Qemu-devel] " Alberto Garcia
2019-01-17 15:33 ` [Qemu-devel] [PATCH 07/13] block: Allow omitting the 'backing' option in certain cases Alberto Garcia
2019-02-12 16:38   ` Kevin Wolf
2019-01-17 15:33 ` [Qemu-devel] [PATCH 08/13] block: Allow changing the backing file on reopen Alberto Garcia
2019-02-12 17:27   ` Kevin Wolf
2019-02-21 14:46     ` Alberto Garcia
2019-02-21 14:53     ` Alberto Garcia
2019-01-17 15:34 ` [Qemu-devel] [PATCH 09/13] block: Add 'runtime_opts' and 'mutable_opts' fields to BlockDriver Alberto Garcia
2019-02-12 18:02   ` Kevin Wolf
2019-03-01 12:12     ` Alberto Garcia
2019-03-01 12:36       ` Kevin Wolf
2019-03-01 12:42         ` Alberto Garcia
2019-03-01 12:56           ` Kevin Wolf
2019-03-01 13:05             ` Alberto Garcia
2019-03-01 14:18               ` Kevin Wolf
2019-03-01 14:37                 ` Alberto Garcia
2019-01-17 15:34 ` [Qemu-devel] [PATCH 10/13] block: Add bdrv_reset_options_allowed() Alberto Garcia
2019-01-17 15:34 ` [Qemu-devel] [PATCH 11/13] block: Remove the AioContext parameter from bdrv_reopen_multiple() Alberto Garcia
2019-01-17 15:34 ` [Qemu-devel] [PATCH 12/13] block: Add an 'x-blockdev-reopen' QMP command Alberto Garcia
2019-01-17 15:34 ` [Qemu-devel] [PATCH 13/13] qemu-iotests: Test the x-blockdev-reopen " Alberto Garcia
2019-01-17 15:50 ` [Qemu-devel] [PATCH 00/13] Add a 'x-blockdev-reopen' " Eric Blake
2019-01-17 16:05   ` Alberto Garcia
2019-01-22  8:15   ` Vladimir Sementsov-Ogievskiy
2019-01-23 15:56     ` Alberto Garcia
2019-01-31 15:11 ` Alberto Garcia

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=20190212144747.GC5283@localhost.localdomain \
    --to=kwolf@redhat.com \
    --cc=berto@igalia.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /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.