This function returns a BDS's driver-specific options, excluding also
those from its children. Since we have just removed all children
options from bs->options there's no need to do this last step.
We allow references to children, though ("backing": "node0"), so those
we still have to remove.
Signed-off-by: Alberto Garcia <berto@igalia.com>
---
 block.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/block.c b/block.c
index 58c8e8e677..9b91b01849 100644
--- a/block.c
+++ b/block.c
@@ -5210,16 +5210,13 @@ static bool append_open_options(QDict *d, BlockDriverState *bs)
     QemuOptDesc *desc;
     BdrvChild *child;
     bool found_any = false;
-    const char *p;
 
     for (entry = qdict_first(bs->options); entry;
          entry = qdict_next(bs->options, entry))
     {
-        /* Exclude options for children */
+        /* Exclude node-name references to children */
         QLIST_FOREACH(child, &bs->children, next) {
-            if (strstart(qdict_entry_key(entry), child->name, &p)
-                && (!*p || *p == '.'))
-            {
+            if (!strcmp(entry->key, child->name)) {
                 break;
             }
         }
-- 
2.11.0
                
            Am 29.06.2018 um 13:37 hat Alberto Garcia geschrieben:
> This function returns a BDS's driver-specific options, excluding also
> those from its children. Since we have just removed all children
> options from bs->options there's no need to do this last step.
> 
> We allow references to children, though ("backing": "node0"), so those
> we still have to remove.
> 
> Signed-off-by: Alberto Garcia <berto@igalia.com>
Hmm, yes, but if I compare this with the example you gave in an earlier
patch:
      $ qemu-img create -f qcow2 hd0.qcow2 10M
      $ qemu-img create -f qcow2 -b hd0.qcow2 hd1.qcow2
      $ qemu-img create -f qcow2 -b hd1.qcow2 hd2.qcow2
      $ $QEMU -drive file=hd2.qcow2,node-name=hd2,backing.node-name=hd1
    This opens a chain of images hd0 <- hd1 <- hd2. Now let's remove hd1
    using block_stream:
      (qemu) block_stream hd2 0 hd0.qcow2
    After this hd2 contains backing.node-name=hd1, which is no longer
    correct because hd1 doesn't exist anymore.
Doesn't backing=hd1 actually result in the same kind of inconsistency?
That is, bs->option will still have backing=hd1, but in reality we
reference hd0 now?
Should we get rid of child references in bs->(explicit_)options as well?
Kevin
                
            On Tue 14 Aug 2018 11:17:50 AM CEST, Kevin Wolf wrote:
> Am 29.06.2018 um 13:37 hat Alberto Garcia geschrieben:
>> This function returns a BDS's driver-specific options, excluding also
>> those from its children. Since we have just removed all children
>> options from bs->options there's no need to do this last step.
>> 
>> We allow references to children, though ("backing": "node0"), so those
>> we still have to remove.
>> 
>> Signed-off-by: Alberto Garcia <berto@igalia.com>
>
> Hmm, yes, but if I compare this with the example you gave in an earlier
> patch:
>
>       $ qemu-img create -f qcow2 hd0.qcow2 10M
>       $ qemu-img create -f qcow2 -b hd0.qcow2 hd1.qcow2
>       $ qemu-img create -f qcow2 -b hd1.qcow2 hd2.qcow2
>
>       $ $QEMU -drive file=hd2.qcow2,node-name=hd2,backing.node-name=hd1
>
>     This opens a chain of images hd0 <- hd1 <- hd2. Now let's remove hd1
>     using block_stream:
>
>       (qemu) block_stream hd2 0 hd0.qcow2
>
>     After this hd2 contains backing.node-name=hd1, which is no longer
>     correct because hd1 doesn't exist anymore.
>
> Doesn't backing=hd1 actually result in the same kind of inconsistency?
> That is, bs->option will still have backing=hd1, but in reality we
> reference hd0 now?
>
> Should we get rid of child references in bs->(explicit_)options as
> well?
I don't think so, at least not in general.
The main difference is that if you set backing.node-name=foo then it
means that 'node-name=foo' is an option of the child, the option doesn't
belong in the parent at all. So once it's transferred to the child
there's no reason why it shoud remain in the parent. It's redundant and
can interfere with the reopen operation (e.g. you change the option in
the child but when you reopen the parent it will try to revert the child
option to the previous value).
In the case of 'backing=foo' that's clearly an option of the parent,
there's no other place to put it. We could probably remove it as well,
but we have to see carefully that no parent needs to keep that
information. I think we want to keep child references because in general
we don't allow them to be changed in reopen.
Example: you cannot pass 'file=bar' on reopen unless 'bar' was already
the existing value of 'file' (i.e. you're not changing anything). We
need to look for the previous value in bs->options in order to know
that.
After x-blockdev-reopen is ready, 'backing' will perhaps be the
first/only exception, because we'll be able to change it and the
previous value doesn't matter.
But that's part of the patches I'm working on.
Berto
                
            Am 14.08.2018 um 12:52 hat Alberto Garcia geschrieben:
> On Tue 14 Aug 2018 11:17:50 AM CEST, Kevin Wolf wrote:
> > Am 29.06.2018 um 13:37 hat Alberto Garcia geschrieben:
> >> This function returns a BDS's driver-specific options, excluding also
> >> those from its children. Since we have just removed all children
> >> options from bs->options there's no need to do this last step.
> >> 
> >> We allow references to children, though ("backing": "node0"), so those
> >> we still have to remove.
> >> 
> >> Signed-off-by: Alberto Garcia <berto@igalia.com>
> >
> > Hmm, yes, but if I compare this with the example you gave in an earlier
> > patch:
> >
> >       $ qemu-img create -f qcow2 hd0.qcow2 10M
> >       $ qemu-img create -f qcow2 -b hd0.qcow2 hd1.qcow2
> >       $ qemu-img create -f qcow2 -b hd1.qcow2 hd2.qcow2
> >
> >       $ $QEMU -drive file=hd2.qcow2,node-name=hd2,backing.node-name=hd1
> >
> >     This opens a chain of images hd0 <- hd1 <- hd2. Now let's remove hd1
> >     using block_stream:
> >
> >       (qemu) block_stream hd2 0 hd0.qcow2
> >
> >     After this hd2 contains backing.node-name=hd1, which is no longer
> >     correct because hd1 doesn't exist anymore.
> >
> > Doesn't backing=hd1 actually result in the same kind of inconsistency?
> > That is, bs->option will still have backing=hd1, but in reality we
> > reference hd0 now?
> >
> > Should we get rid of child references in bs->(explicit_)options as
> > well?
> 
> I don't think so, at least not in general.
> 
> The main difference is that if you set backing.node-name=foo then it
> means that 'node-name=foo' is an option of the child, the option doesn't
> belong in the parent at all. So once it's transferred to the child
> there's no reason why it shoud remain in the parent. It's redundant and
> can interfere with the reopen operation (e.g. you change the option in
> the child but when you reopen the parent it will try to revert the child
> option to the previous value).
That's a rather reopen-centric point of view, though.
Redundant information isn't nice already, but what really makes it a
problem is that it's potentially incorrect information because it isn't
kept up to date. There is no point in keeping incorrect information, so
I agree that deleting it is best.
> In the case of 'backing=foo' that's clearly an option of the parent,
> there's no other place to put it. We could probably remove it as well,
> but we have to see carefully that no parent needs to keep that
> information. I think we want to keep child references because in general
> we don't allow them to be changed in reopen.
> 
> Example: you cannot pass 'file=bar' on reopen unless 'bar' was already
> the existing value of 'file' (i.e. you're not changing anything). We
> need to look for the previous value in bs->options in order to know
> that.
My point is the backing=foo has the same problem: Storing it in
bs->options is not only redundant, but potentially incorrect because we
never update it when we modify the graph. There is no point in keeping
potentially incorrect information.
When you actually use that incorrect information, you've got a bug.
Reopen with file=bar doesn't have to check whether 'file=bar' is in
bs->options (because that may be outdated information), but whether the
BdrvChild with the name 'file' points to a node called 'bar'.
Getting rid of the potentially incorrect information will make it more
obvious what you have to check to make things work correctly.
> After x-blockdev-reopen is ready, 'backing' will perhaps be the
> first/only exception, because we'll be able to change it and the
> previous value doesn't matter.
I certainly hope that it will not be the only kind of node references
that you can change. Adding/removing filter nodes requires to be able to
change more or less any kind of node references. But we'll see.
Kevin
                
            On Tue 14 Aug 2018 01:14:42 PM CEST, Kevin Wolf wrote: >> The main difference is that if you set backing.node-name=foo then it >> means that 'node-name=foo' is an option of the child, the option >> doesn't belong in the parent at all. So once it's transferred to the >> child there's no reason why it shoud remain in the parent. It's >> redundant and can interfere with the reopen operation (e.g. you >> change the option in the child but when you reopen the parent it will >> try to revert the child option to the previous value). > > That's a rather reopen-centric point of view, though. > > Redundant information isn't nice already, but what really makes it a > problem is that it's potentially incorrect information because it > isn't kept up to date. There is no point in keeping incorrect > information, so I agree that deleting it is best. Yes, it's indeed reopen-centric :-) I agree with you though, the reopen problem is a practical example of the consequences of keeping both options, but the main problem is that they can be different and therefore wrong. >> In the case of 'backing=foo' that's clearly an option of the parent, >> there's no other place to put it. We could probably remove it as >> well, but we have to see carefully that no parent needs to keep that >> information. I think we want to keep child references because in >> general we don't allow them to be changed in reopen. >> >> Example: you cannot pass 'file=bar' on reopen unless 'bar' was >> already the existing value of 'file' (i.e. you're not changing >> anything). We need to look for the previous value in bs->options in >> order to know that. > > My point is the backing=foo has the same problem: Storing it in > bs->options is not only redundant, but potentially incorrect because > we never update it when we modify the graph. There is no point in > keeping potentially incorrect information. I tend to agree, but there's one reason why it's not exactly the same case: with "backing=foo" we know not only that the backing node name is 'foo', but that it was added using a reference rather than with backing.node-name=foo. I'm not sure if that's information that we need for anything, however (probably not). > When you actually use that incorrect information, you've got a bug. > Reopen with file=bar doesn't have to check whether 'file=bar' is in > bs->options (because that may be outdated information), but whether > the BdrvChild with the name 'file' points to a node called 'bar'. Again, this is correct if we open the BDS with file.node-name=bar and then we allow reopening it with file=bar Different set of options, but the result still makes sense. For this we need a specific check to verify that this is correct. For the current behavior we don't need anything now: we only allow the exact same option. >> After x-blockdev-reopen is ready, 'backing' will perhaps be the >> first/only exception, because we'll be able to change it and the >> previous value doesn't matter. > > I certainly hope that it will not be the only kind of node references > that you can change. Adding/removing filter nodes requires to be able > to change more or less any kind of node references. But we'll see. No, but anything that we allow changing has to be done on a case-by-case basis. You can't simply allow changing any child reference, the specific driver has to be modified in order to allow that. Until the driver is changed, the current behavior prevails: if an option was modified, we return an error. Berto
Am 14.08.2018 um 13:48 hat Alberto Garcia geschrieben:
> >> In the case of 'backing=foo' that's clearly an option of the parent,
> >> there's no other place to put it. We could probably remove it as
> >> well, but we have to see carefully that no parent needs to keep that
> >> information. I think we want to keep child references because in
> >> general we don't allow them to be changed in reopen.
> >> 
> >> Example: you cannot pass 'file=bar' on reopen unless 'bar' was
> >> already the existing value of 'file' (i.e. you're not changing
> >> anything). We need to look for the previous value in bs->options in
> >> order to know that.
> >
> > My point is the backing=foo has the same problem: Storing it in
> > bs->options is not only redundant, but potentially incorrect because
> > we never update it when we modify the graph. There is no point in
> > keeping potentially incorrect information.
> 
> I tend to agree, but there's one reason why it's not exactly the same
> case: with "backing=foo" we know not only that the backing node name is
> 'foo', but that it was added using a reference rather than with
> backing.node-name=foo. I'm not sure if that's information that we need
> for anything, however (probably not).
Isn't the proper way to check this foo->inherits_from?
But generally, it shouldn't make a difference for most purposes which
way a node was created.
> > When you actually use that incorrect information, you've got a bug.
> > Reopen with file=bar doesn't have to check whether 'file=bar' is in
> > bs->options (because that may be outdated information), but whether
> > the BdrvChild with the name 'file' points to a node called 'bar'.
> 
> Again, this is correct if we open the BDS with
> 
>   file.node-name=bar
> 
> and then we allow reopening it with
> 
>   file=bar
> 
> Different set of options, but the result still makes sense. For this we
> need a specific check to verify that this is correct. For the current
> behavior we don't need anything now: we only allow the exact same
> option.
That's yet another case and another reason why we want to check
BdrvChild instead. If we take BlockdevOptions for blockdev-reopen, you
need to put something there for nodes that you created inline
originally, and just putting the node name there probably makes the most
sense.
Anyway, the case that I had in mind is the case where you removed a
backing file with a block job:
    base <- mid <- top
You stream top into mid, so at the end of the job, mid goes away and
base is the backing file of top. But since you opened top with
backing=mid, that's still what you get when you look at bs->options.
    base <- top
            (backing=mid)
If you now reopen top, and bdrv_reopen looks at bs->options to check
whether the operation is valid, you must specify backing=mid instead of
the correct backing=base so that reopen thinks it's unchanged.
> >> After x-blockdev-reopen is ready, 'backing' will perhaps be the
> >> first/only exception, because we'll be able to change it and the
> >> previous value doesn't matter.
> >
> > I certainly hope that it will not be the only kind of node references
> > that you can change. Adding/removing filter nodes requires to be able
> > to change more or less any kind of node references. But we'll see.
> 
> No, but anything that we allow changing has to be done on a case-by-case
> basis. You can't simply allow changing any child reference, the specific
> driver has to be modified in order to allow that.
> 
> Until the driver is changed, the current behavior prevails: if an option
> was modified, we return an error.
Makes sense to err on the safe side, though I expect that most drivers
don't need to do much more than just allowing the switch.
Maybe, if we want to keep things a bit safer, what we can do is check
that the same node is addressed when you skip all filters.
Kevin
                
            On Tue 14 Aug 2018 02:08:26 PM CEST, Kevin Wolf wrote: >> > When you actually use that incorrect information, you've got a bug. >> > Reopen with file=bar doesn't have to check whether 'file=bar' is in >> > bs->options (because that may be outdated information), but whether >> > the BdrvChild with the name 'file' points to a node called 'bar'. >> >> Again, this is correct if we open the BDS with >> >> file.node-name=bar >> >> and then we allow reopening it with >> >> file=bar >> >> Different set of options, but the result still makes sense. For this >> we need a specific check to verify that this is correct. For the >> current behavior we don't need anything now: we only allow the exact >> same option. > > That's yet another case and another reason why we want to check > BdrvChild instead. If we take BlockdevOptions for blockdev-reopen, you > need to put something there for nodes that you created inline > originally, and just putting the node name there probably makes the > most sense. > > Anyway, the case that I had in mind is the case where you removed a > backing file with a block job: > > base <- mid <- top > > You stream top into mid, so at the end of the job, mid goes away and > base is the backing file of top. But since you opened top with > backing=mid, that's still what you get when you look at bs->options. > > base <- top > (backing=mid) > > If you now reopen top, and bdrv_reopen looks at bs->options to check > whether the operation is valid, you must specify backing=mid instead > of the correct backing=base so that reopen thinks it's unchanged. Yes, that's correct, I'm aware of that problem. >> >> After x-blockdev-reopen is ready, 'backing' will perhaps be the >> >> first/only exception, because we'll be able to change it and the >> >> previous value doesn't matter. >> > >> > I certainly hope that it will not be the only kind of node references >> > that you can change. Adding/removing filter nodes requires to be able >> > to change more or less any kind of node references. But we'll see. >> >> No, but anything that we allow changing has to be done on a case-by-case >> basis. You can't simply allow changing any child reference, the specific >> driver has to be modified in order to allow that. >> >> Until the driver is changed, the current behavior prevails: if an option >> was modified, we return an error. > > Makes sense to err on the safe side, though I expect that most drivers > don't need to do much more than just allowing the switch. > > Maybe, if we want to keep things a bit safer, what we can do is check > that the same node is addressed when you skip all filters. The proper fix could be something alone those lines, yes. I'll give it a try and see what happens. This would be a separate patch, though, the ones that I sent shouldn't need changes. Berto
© 2016 - 2025 Red Hat, Inc.