On Fri, Oct 25, 2024 at 06:10:46PM -0400, Peter Xu wrote:
> On Fri, Oct 25, 2024 at 05:22:01PM +0100, Daniel P. Berrangé wrote:
> > On Fri, Oct 25, 2024 at 12:17:02PM -0400, Peter Xu wrote:
> > > On Fri, Oct 25, 2024 at 10:51:21AM +0100, Daniel P. Berrangé wrote:
> > > > > diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
> > > > > index e91a235347..ecc1cf781c 100644
> > > > > --- a/qom/qom-qmp-cmds.c
> > > > > +++ b/qom/qom-qmp-cmds.c
> > > > > @@ -126,6 +126,7 @@ ObjectPropertyInfoList 
> > > > > *qmp_device_list_properties(const char *typename,
> > > > >      ObjectProperty *prop;
> > > > >      ObjectPropertyIterator iter;
> > > > >      ObjectPropertyInfoList *prop_list = NULL;
> > > > > +    bool create;
> > > > >  
> > > > >      klass = module_object_class_by_name(typename);
> > > > >      if (klass == NULL) {
> > > > > @@ -141,7 +142,15 @@ ObjectPropertyInfoList 
> > > > > *qmp_device_list_properties(const char *typename,
> > > > >          return NULL;
> > > > >      }
> > > > >  
> > > > > -    obj = object_new(typename);
> > > > > +    /* Avoid creating multiple instances if the class is a singleton 
> > > > > */
> > > > > +    create = !object_class_is_singleton(klass) ||
> > > > > +        !singleton_get_instance(klass);
> > > > > +
> > > > > +    if (create) {
> > > > > +        obj = object_new(typename);
> > > > > +    } else {
> > > > > +        obj = singleton_get_instance(klass);
> > > > > +    }
> > > > 
> > > > This is the first foot-gun example.
> > > > 
> > > > I really strongly dislike that the design pattern forces us to
> > > > create code like this, as we can never be confident we've
> > > > correctly identified all the places which may call object_new
> > > > on a singleton...
> > > 
> > > Yeah I agree it's not pretty, IMHO it's a trade-off comparing to glib's,
> > > I'll comment below for that.
> > > 
> > > Meanwhile I hope there should be very limited places in QEMU to randomly
> > > create "any" object on the fly.. so far only qom/device-list-properties
> > > that I see.
> > 
> > There's -object/-device CLI, and their corresponding object_add
> > / device_add commands.
> 
> Ah I didn't mention that when reply, but this patch blocks properly any
> device-add for singleton objects for more than once.  Please see the change
> in qdev_device_add_from_qdict().
> 
> For migration object, it means it'll always fail because migration object
> is created very early, before someone can try to create it.  Not to mention
> it also has dc->hotpluggable==false, so things like -device will never work
> on migration object.
> 
> For object-add, IIUC migration object should always be safe because it has
> no USER_CREATABLE interface.
> 
> > 
> > They are not relevant for the migration object, but you're adding
> > this feature to QOM, so we have to take them into account. If anyone
> > defines another Object or Device class as a singleton, we will have
> > quite a few places where we can trigger the assert. This is especially
> > bad if we trigger it from anything in QMP as that kills a running
> > guest.

Sorry, for some reason I think I didn't notice the 2nd paragraph.. And
somehow I was only thinking the migration use case.

Indeed this part is not easy to get right.  I hope this is not a blocker
yet so far.  We can have a look when I send the new version; I'll start to
mark the series RFC.

Meanwhile I'll have a closer look, hopefully object_class_is_abstract() is
a good point of reference where I can track most of dynamic creations of
objects, and I'll go from there.

My current plan is we can have one helper object_new_allowed(), where it
should contain both the check over abstract & singleton classes before any
instantiations happen.

-- 
Peter Xu


Reply via email to