All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Damien Hedde <damien.hedde@greensocs.com>
Cc: lvivier@redhat.com, pkrempa@redhat.com, berrange@redhat.com,
	ehabkost@redhat.com, qemu-block@nongnu.org, mst@redhat.com,
	libvir-list@redhat.com, quintela@redhat.com,
	qemu-devel@nongnu.org, armbru@redhat.com, its@irrelevant.dk,
	pbonzini@redhat.com, jfreimann@redhat.com
Subject: Re: [PATCH 09/11] qdev: Avoid QemuOpts in QMP device_add
Date: Tue, 5 Oct 2021 16:37:33 +0200	[thread overview]
Message-ID: <YVxjLf9vJlBqeKKh@redhat.com> (raw)
In-Reply-To: <YVGtXMq+JGKIIUrQ@redhat.com>

Am 27.09.2021 um 13:39 hat Kevin Wolf geschrieben:
> Am 27.09.2021 um 13:06 hat Damien Hedde geschrieben:
> > On 9/24/21 11:04, Kevin Wolf wrote:
> > > Directly call qdev_device_add_from_qdict() for QMP device_add instead of
> > > first going through QemuOpts and converting back to QDict.
> > > 
> > > Note that this changes the behaviour of device_add, though in ways that
> > > should be considered bug fixes:
> > > 
> > > QemuOpts ignores differences between data types, so you could
> > > successfully pass a string "123" for an integer property, or a string
> > > "on" for a boolean property (and vice versa).  After this change, the
> > > correct data type for the property must be used in the JSON input.
> > > 
> > > qemu_opts_from_qdict() also silently ignores any options whose value is
> > > a QDict, QList or QNull.
> > > 
> > > To illustrate, the following QMP command was accepted before and is now
> > > rejected for both reasons:
> > > 
> > > { "execute": "device_add",
> > >    "arguments": { "driver": "scsi-cd",
> > >                   "drive": { "completely": "invalid" },
> > >                   "physical_block_size": "4096" } }
> > > 
> > > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > > ---
> > >   softmmu/qdev-monitor.c | 18 +++++++++++-------
> > >   1 file changed, 11 insertions(+), 7 deletions(-)
> > > 
> > > diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
> > > index c09b7430eb..8622ccade6 100644
> > > --- a/softmmu/qdev-monitor.c
> > > +++ b/softmmu/qdev-monitor.c
> > > @@ -812,7 +812,8 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict)
> > >       qdev_print_devinfos(true);
> > >   }
> > > -void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
> > > +static void monitor_device_add(QDict *qdict, QObject **ret_data,
> > > +                               bool from_json, Error **errp)
> > >   {
> > >       QemuOpts *opts;
> > >       DeviceState *dev;
> > > @@ -825,7 +826,9 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
> > >           qemu_opts_del(opts);
> > >           return;
> > >       }
> > > -    dev = qdev_device_add(opts, errp);
> > > +    qemu_opts_del(opts);
> > > +
> > > +    dev = qdev_device_add_from_qdict(qdict, from_json, errp);
> > 
> > Hi Kevin,
> > 
> > I'm wandering if deleting the opts (which remove it from the "device" opts
> > list) is really a no-op ?
> 
> It's not exactly a no-op. Previously, the QemuOpts would only be freed
> when the device is destroying, now we delete it immediately after
> creating the device. This could matter in some cases.
> 
> The one case I was aware of is that QemuOpts used to be responsible for
> checking for duplicate IDs. Obviously, it can't do this job any more
> when we call qemu_opts_del() right after creating the device. This is
> the reason for patch 6.
> 
> > The opts list is, eg, traversed in hw/net/virtio-net.c in the function
> > failover_find_primary_device_id() which may be called during the
> > virtio_net_set_features() (a TYPE_VIRTIO_NET method).
> > I do not have the knowledge to tell when this method is called. But If this
> > is after we create the devices. Then the list will be empty at this point
> > now.
> > 
> > It seems, there are 2 other calling sites of
> > "qemu_opts_foreach(qemu_find_opts("device"), [...]" in net/vhost-user.c and
> > net/vhost-vdpa.c
> 
> Yes, you are right. These callers probably need to be changed. Going
> through the command line options rather than looking at the actual
> device objects that exist doesn't feel entirely clean anyway.

So I tried to have a look at the virtio-net case, and ended up very
confused.

Obviously looking at command line options (even of a differrent device)
from within a device is very unclean. With a non-broken, i.e. type safe,
device-add (as well as with the JSON CLI option introduced by this
series), we can't have a QemuOpts any more that is by definition unsafe.
So this code needs a replacement.

My naive idea was that we just need to look at runtime state instead.
Don't search the options for a device with a matching 'failover_pair_id'
(which, by the way, would fail as soon as any other device introduces a
property with the same name), but search for actual PCIDevices in qdev
that have pci_dev->failover_pair_id set accordingly.

However, the logic in failover_add_primary() suggests that we can have a
state where QemuOpts for a device exist, but the device doesn't, and
then it hotplugs the device from the command line options. How would we
ever get into such an inconsistent state where QemuOpts contains a
device that doesn't exist? Normally devices get their QemuOpts when they
are created and device_finalize() deletes the QemuOpts again.

Any suggestions how to get rid of the QemuOpts abuse in the failover
code?

If this is a device that we previously managed to rip out without
deleting its QemuOpts, can we store its dev->opts (which is a type safe
QDict after this series) somewhere locally instead of looking at global
state? Preferably I would even like to get rid of dev->opts because we
really should look at live state rather than command line options after
device creation, but I guess one step at a time.

(Actually, I'm half tempted to just break it because no test cases seem
to exist, so apparently nobody is really interested in it.)

Kevin



  reply	other threads:[~2021-10-05 15:05 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-24  9:04 [PATCH 00/11] qdev: Add JSON -device and fix QMP device_add Kevin Wolf
2021-09-24  9:04 ` [PATCH 01/11] qom: Reduce use of error_propagate() Kevin Wolf
2021-09-24 13:23   ` Vladimir Sementsov-Ogievskiy
2021-09-24 14:04   ` Markus Armbruster
2021-09-24 18:14   ` Eric Blake
2021-09-24  9:04 ` [PATCH 02/11] iotests/245: Fix type for iothread property Kevin Wolf
2021-09-24 13:33   ` Vladimir Sementsov-Ogievskiy
2021-09-24  9:04 ` [PATCH 03/11] iotests/051: Fix typo Kevin Wolf
2021-09-24 13:35   ` Vladimir Sementsov-Ogievskiy
2021-09-24  9:04 ` [PATCH 04/11] qdev: Avoid using string visitor for properties Kevin Wolf
2021-09-24 18:40   ` Eric Blake
2021-09-24  9:04 ` [PATCH 05/11] qdev: Make DeviceState.id independent of QemuOpts Kevin Wolf
2021-09-24 14:02   ` Vladimir Sementsov-Ogievskiy
2021-09-24 15:10     ` Kevin Wolf
2021-09-24 15:14       ` Vladimir Sementsov-Ogievskiy
2021-09-24  9:04 ` [PATCH 06/11] qdev: Add Error parameter to qdev_set_id() Kevin Wolf
2021-09-24 14:09   ` Vladimir Sementsov-Ogievskiy
2021-09-27 10:33     ` Damien Hedde
2021-10-05 11:09       ` Kevin Wolf
2021-09-24  9:04 ` [PATCH 07/11] qemu-option: Allow deleting opts during qemu_opts_foreach() Kevin Wolf
2021-09-24 14:14   ` Vladimir Sementsov-Ogievskiy
2021-09-24  9:04 ` [PATCH 08/11] qdev: Base object creation on QDict rather than QemuOpts Kevin Wolf
2021-09-24 18:53   ` Eric Blake
2021-09-24  9:04 ` [PATCH 09/11] qdev: Avoid QemuOpts in QMP device_add Kevin Wolf
2021-09-24 18:56   ` Eric Blake
2021-09-27 11:06   ` Damien Hedde
2021-09-27 11:39     ` Kevin Wolf
2021-10-05 14:37       ` Kevin Wolf [this message]
2021-10-05 15:52         ` Damien Hedde
2021-10-05 17:33           ` Kevin Wolf
2021-10-06  8:21             ` Juan Quintela
2021-10-06  9:20               ` Laurent Vivier
2021-10-06 10:53                 ` Kevin Wolf
2021-10-06 11:09                   ` Laurent Vivier
2021-10-01 14:42   ` Peter Krempa
2021-10-04 12:18     ` Damien Hedde
2021-10-04 14:22       ` Kevin Wolf
2021-09-24  9:04 ` [PATCH 10/11] vl: Enable JSON syntax for -device Kevin Wolf
2021-09-24 19:00   ` Eric Blake
2021-09-24  9:04 ` [PATCH 11/11] Deprecate stable non-JSON -device and -object Kevin Wolf
2021-09-24 19:02   ` Eric Blake
2021-09-27  8:15   ` Paolo Bonzini
2021-09-27  8:21     ` Daniel P. Berrangé
2021-09-27 10:17       ` Kevin Wolf
2021-09-27 10:37         ` Daniel P. Berrangé
2021-09-27  9:00   ` Peter Maydell
2021-09-27 11:27     ` Kevin Wolf
2021-09-27 12:52       ` Peter Maydell
2021-09-27 16:10         ` Kevin Wolf

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=YVxjLf9vJlBqeKKh@redhat.com \
    --to=kwolf@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=damien.hedde@greensocs.com \
    --cc=ehabkost@redhat.com \
    --cc=its@irrelevant.dk \
    --cc=jfreimann@redhat.com \
    --cc=libvir-list@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=pkrempa@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@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.