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.
>
> >
> > I think glib's implementation is not thread safe on its own... consider two
> > threads invoke g_object_new() on the singleton without proper locking. I
> > am guessing it could be relevant to glib's heavy event model.
>
> I've not checked the full code path, to see if they have a serialization
> point somewhere it the g_object_new call chain, but yes, it is a valid
> concern that would need to be resolved.
Thanks,
--
Peter Xu