From: Jeff Cody <jcody@redhat.com>
To: Eric Blake <eblake@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 4/5] block: Accept node-name arguments for block-commit
Date: Thu, 15 May 2014 14:04:03 -0400 [thread overview]
Message-ID: <20140515180403.GK8452@localhost.localdomain> (raw)
In-Reply-To: <5374E04F.6010205@redhat.com>
On Thu, May 15, 2014 at 09:42:07AM -0600, Eric Blake wrote:
> On 05/14/2014 09:20 PM, Jeff Cody wrote:
> > This modifies the block operation block-commit so that it will
> > accept node-name arguments for either 'top' or 'base' BDS.
> >
> > The filename and node-name are mutually exclusive to each other;
> > i.e.:
> > "top" and "top-node-name" are mutually exclusive (enforced)
> > "base" and "base-node-name" are mutually exclusive (enforced)
>
> Hmm - we have a bug in existing commands for NOT forcing mutual
> exclusion even though the schema says they are exclusive.
Those are a slightly different scenario, however. In this patch, we
are dealing with a filename string, and a node-name string. There is
more of a 1:1 relationship between those two (both identify a
particular image). The other existing commands, however, deal with a
device name string (identifying a drive chain) or a node-name string
(identifying a particular image).
That said, I think the other commands should be modified to enforce
the documentation, but it doesn't really relate to this patch.
> For example,
> qmp_block_passwd() blindly calls:
>
> bs = bdrv_lookup_bs(has_device ? device : NULL,
> has_node_name ? node_name : NULL,
> &local_err);
>
> and _that_ function blindly favors device name over node name, rather
> than erroring out if both are supplied.
I find this an odd function to begin with, because node_name uniquely
identifies any given BDS from any chain. Device name will uniquely
identify a whole chain, by returning its top-most BDS.
The function seems confused.
> I think we should fix that
> first - I'd rather that bdrv_lookup_bs either errors out if both names
> are supplied (rather than making each caller repeat the work), or that
> it checks that if both names are supplied then it resolves to the same bs.
>
I disagree on this part, at least partially. It think it needs to be
changed, but I don't think it needs to be part of this series. I
think that can be a separate series, to address that across the other
QAPI commands that accept node-name and device name
> Hmm - if I have device "foo" with chain "base <- top", would
> bdrv_lookup_bs("foo", "base") be okay ("base" is a node-name that
> resides within "device"'s chain) or an error ("base" resolves to a
> different bs than "device")? Again, all the more reason to have a
> common function decide the semantics we want, then all other clients
> automatically pick up on those semantics.
>
> >
> > The preferred and recommended method now of using block-commit
> > is to specify the BDS to operate on via their node-name arguments.
> >
> > This also adds an explicit check that base_bs is in the chain of
> > top_bs, because if they are referenced by their unique node-name
> > arguments, the discovery process does not intrinsically verify
> > they are in the same chain.
>
> I like this addition.
>
> >
> > Signed-off-by: Jeff Cody <jcody@redhat.com>
> > ---
> > blockdev.c | 35 +++++++++++++++++++++++++++++++++--
> > qapi-schema.json | 35 ++++++++++++++++++++++++++---------
> > qmp-commands.hx | 29 ++++++++++++++++++++++-------
> > 3 files changed, 81 insertions(+), 18 deletions(-)
> >
>
>
>
> >
> > - if (top) {
> > + /* Find the 'top' image file for the commit */
> > + if (has_top_node_name) {
> > + top_bs = bdrv_lookup_bs(NULL, top_node_name, &local_err);
>
> Hmm. Shouldn't you ALSO verify that 'top_bs' belongs to the chain owned
> by 'device'? Later on, you verify that 'base_bs' belongs to 'top_bs',
> but if I pass node names, those names could have found a top unrelated
> to 'device'; and base related to that top.
>
It is not needed - it is not relevant for the active commit case (the
current check will catch that, since top_bs == bs). And for the
non-active commit case, commit_start() will return an error if
'top_bs' is not in 'bs', so the case of 'base_bs' or 'top_bs' not
being in 'device' is already covered.
> Maybe that gives more weight to my idea of possibly allowing
> bdrv_lookup_bs(device, top_node_name), where the lookup succeeds even
> when device and top_node_name resolve to different bs, but where
> top_node_name is a node in the chain of device.
>
> >
> > - if (has_base && base) {
> > + /* Find the 'base' image file for the commit */
> > + if (has_base_node_name) {
> > + base_bs = bdrv_lookup_bs(NULL, base_node_name, &local_err);
> > + if (local_err) {
> > + error_propagate(errp, local_err);
> > + return;
> > + }
> > + } else if (has_base && base) {
>
> Here, it doesn't matter whether you pass device or NULL for the device
> name...
>
This conditional is just to determine if we are finding the backing
image referenced by the string "base" or just using the default
bottom-most base image.
> >
> > + /* Verify that 'base' is in the same chain as 'top' */
> > + if (!bdrv_is_in_chain(top_bs, base_bs)) {
> > + error_setg(errp, "'base' and 'top' are not in the same chain");
> > + return;
>
> ...because this check is still mandatory to prove that a user with chain:
> base <- sn1 <- sn2 <- active
>
> is not calling 'device':'active', 'top-node-name':'sn1',
> 'base-node-name':'sn2' (all that bdrv_lookup_bs can do is verify that
> base-node-name belongs to device, not that it _also_ belongs to top_bs).
>
>
> > -# @base: #optional The file name of the backing image to write data into.
> > -# If not specified, this is the deepest backing image
> > +# For 'base', either @base or @base-node-name may be set but not both. If
> > +# neither is specified, this is the deepest backing image
>
> I like how you factored th is out up front...
>
> > #
> > -# @top: #optional The file name of the backing image within the image chain,
> > -# which contains the topmost data to be committed down. If
> > -# not specified, this is the active layer.
> > +# @base: #optional The file name of the backing image to write data
> > +# into.
> > +#
> > +# @base-node-name #optional The name of the block driver state node of the
> > +# backing image to write data into.
> > +# (Since 2.1)
> > +#
> > +# For 'top', either @top or @top-node-name must be set but not both.
>
> ...but here, you were not consistent. I'd add "If neither is specified,
> this is the active image" here...
>
OK, thanks.
> > +#
> > +# @top: #optional The file name of the backing image within the image
> > +# chain, which contains the topmost data to be
> > +# committed down. If not specified, this is the
> > +# active layer.
>
> ...and drop the second sentence from here.
>
OK, thanks.
> > +#
> > +# @top-node-name: #optional The block driver state node name of the backing
> > +# image within the image chain, which contains the
> > +# topmost data to be committed down.
> > +# (Since 2.1)
> > #
> > # If top == base, that is an error.
> > # If top == active, the job will not be completed by itself,
> > @@ -2120,17 +2135,19 @@
> > #
> > # Returns: Nothing on success
> > # If commit or stream is already active on this device, DeviceInUse
> > -# If @device does not exist, DeviceNotFound
> > +# If @device does not exist or cannot be determined, DeviceNotFound
> > # If image commit is not supported by this device, NotSupported
> > -# If @base or @top is invalid, a generic error is returned
> > +# If @base, @top, @base-node-name, @top-node-name invalid, GenericError
> > # 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
>
> These last two are arguably sub-conditions of the earlier statement
> about @top and @top-node-name being invalid (since being invalid can
> include when both strings are used at once). It wouldn't hurt my
> feelings to reduce the docs by two lines.
>
OK. I called it out explicitly, since it is currently different
behavior from the other functions.
> > # Since: 1.3
> > #
> > ##
> > { 'command': 'block-commit',
> > - 'data': { 'device': 'str', '*base': 'str', '*top': 'str',
> > - '*speed': 'int' } }
> > + 'data': { 'device': 'str', '*base': 'str', '*base-node-name': 'str',
> > + '*top': 'str', '*top-node-name': 'str', '*speed': 'int' } }
>
> I'm okay with keeping 'device' mandatory, even though technically the
> use of a node-name could imply which device is intended. That is, as
> long as the code correctly errors out when device and top-node-name
> don't resolve to the same chain :)
>
I had thought about making it optional, but I do think it is better as
mandatory - it makes sure the user knows which chain they are
operating on, so it acts as a (small) check against user mistakes.
>
> > +
> > +For 'top', either top or top-node-name must be set but not both.
> > +
> > +- "top": The file name of the backing image within the image chain,
> > + which contains the topmost data to be committed down. If
> > + not specified, this is the active layer.
> > + (json-string, optional)
>
> Same blurb about hoisting the 'not specified => active' sentence to the
> common text, rather than leaving it in the 'top' text.
>
OK, thanks.
next prev parent reply other threads:[~2014-05-15 18:04 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 [this message]
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
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=20140515180403.GK8452@localhost.localdomain \
--to=jcody@redhat.com \
--cc=benoit.canet@irqsave.net \
--cc=eblake@redhat.com \
--cc=famz@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.