Re: [PATCH 00/54] qom/qdev: associate properties with QAPI schema types
Marc-André Lureau <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <CAJ+F1C+buFmV5X+ZJeR8aX9JhXiRPEdcTHaPA58kvJDD9UYm-A@mail.gmail.com> |
Hi On Wed, Jul 29, 2026 at 4:43 PM Markus Armbruster <[email protected]> wrote: > > Marc-André Lureau <[email protected]> writes: > > > Hi > > > > On Wed, Jul 29, 2026 at 11:29 AM Markus Armbruster via qemu > > development <[email protected]> wrote: > >> Before I dive into individual patches, let me try to work out what the > >> series does as a whole. > >> > >> > This series adds: > >> > - A new QAPITypeInfo struct that pairs a property with its QAPI schema > >> > type name, enum lookup table, and list-element type. > >> > >> Peeking at the code, I see that ObjectProperty gains a member @qapi_type > >> pointing to its QAPITypeInfo. > >> > >> It is null when the ObjectProperty doesn't have a QAPI type. > >> > >> If it's non-null, then ObjectProperty members @name and @type are > >> redundant with qapi_type.name and .type. > >> > >> Correct? > > > > Almost. @name is the property name (e.g. "policy"), not the type name. > > But @type becomes redundant with qapi_type->name when qapi_type is set > > (object_property_add_qapi derive prop->type from qapi_type->name). > > > > Also @type carries additional information for some property kinds that > > @qapi_type doesn't cover: child<T> and link<T> embed the linked > > object's QOM type name in the type string. qapi_type can't represent > > that atm. > > Can child and link properties have non-null @qapi_type? No. Both object_property_add_child() and object_property_add_link() use the base object_property_add(), not the _qapi variants, so qapi_type stays NULL. On the qdev side, qdev_prop_link.qapi_type is &str_type_info, but create_link_property() calls object_class_property_add_link() which bypasses that, so the ObjectProperty ends up with qapi_type == NULL and type = "link<T>". > > >> Would "every ObjectProperty has a QAPI type" be a reasonable goal for > >> the future? > > > > Maybe? we would need to address the child<>/link<> gap. At least we > > can make raw object_property_add() deprecated/static in object.c after > > this series > > Interesting! > > >> > - A QAPI code generator (qapi-type-infos) that emits a QAPITypeInfo > >> > instance for every schema-defined type, including the mapping > >> > between internal C names and the schema name visible to clients. > >> > >> Peeking at the code, I find: > >> > >> * The type > >> > >> typedef struct QAPITypeInfo { > >> const char *name; > >> const char *schema_name; > >> const QEnumLookup *lookup; > >> const struct QAPITypeInfo *list; > >> } QAPITypeInfo; > >> > >> * A T_type_info for each QAPI type T, including built-in types. > >> > >> * T_type_info member @name is T's QAPI name, i.e. "T". > >> > >> * T_type_info member @schema_name is T's masked name used in > >> query-qmp-schema output, null when T is elided there. > >> > >> * T_type_info member @list points to TList_type_info when that exists, > >> else it's null. > >> > >> * T_type_info member @lookup points to T_lookup when T is an enum, else > >> it's null. > >> > >> Correct? > > > > Yes > > > >> > - A "qapi-type" field in the ObjectPropertyInfo and > >> > ObjectPropertyValue QMP structs, populated from the QAPITypeInfo > >> > when present giving clients a cross-reference into query-qmp-schema > >> > output. > >> > >> To be precise: when ObjectPropertyInfo member @type is "T", then member > >> @qapi-type is T_type_info.qapi-type. Correct? > > > > @qapi-type is T_type_info.schema_name, the masked name > > Right. > > >> If .qapi-type is non-null, you can use it to look up precise type > >> information via QAPI introspection, i.e. query-qmp-schema. > >> > >> Correct? > > > > Yes > > > >> > >> Possible problem: query-qmp-schema covers only types that are actually > >> used in QMP. But the above technique additionally wants QOM property > >> types. I haven't checked what your series does about this, if anything. > > > > Most types used as QOM properties are also used by QMP commands. But > > it's true that types not used by QMP get schame_name = NULL atm. > > So the problem is real, and to reap the full benefit of your work, we > need to solve it. Not necessarily right away. > > > Should we have a new pragma? Even if we have conditions, we may end up > > with unused types in the build, but that shouldn't be a big issue. Or > > we would need a more complicated several step build. > > No need not worry about the how right now. > > >> ObjectPropertyInfo is only used with QMP command handlers. It is > >> computed from ObjectProperty. > >> > >> > - Conversion of all PropertyInfo definitions from the old > >> > .type/.enum_table strings to the new .qapi_type pointer. > >> > >> The above is QOM, this is qdev. > >> > >> Like ObjectProperty, PropertyInfo gains a member @qapi_type pointing to > >> its QAPITypeInfo. Howver, this one cannot be null. > >> > >> PropertyInfo members @type and @enum_table are dropped, because they are > >> redundant with qapi_type.type and .lookup. > >> > >> Correct? > > > > Almost. Every PropertyInfo has a non-NULL qapi_type, except the array > > ones (created with DEFINE_PROP_ARRAY_INFO) which leave .qapi_type NULL > > and derive it at registration time from > > .element_info->qapi_type->list. > > Can you point me to the code setting it? Would save me the digging. qdev_prop_qapi_type(), when info->qapi_type is NULL (the array PropertyInfos created by DEFINE_PROP_ARRAY_INFO), it follows element_info->qapi_type->list. For example, qdev_prop_uint32_list has .element_info = &qdev_prop_uint32, so it resolves uint32_type_info.list -> uint32List_type_info. Not perfect, we can improve later. hopefully > > > Either way, the resulting > > ObjectProperty always ends up with a non-NULL qapi_type. > > > > PropertyInfo members @type and @enum_table are dropped, because they > > are redundant with qapi_type->name and ->lookup. > > Yes. > > >> > - Replacement of the generic qdev_prop_array with typed per-element > >> > array PropertyInfos, removing the arrayinfo/arrayfieldsize > >> > indirection from struct Property. > >> > >> Before the series, an array-valued Property's @info member is > >> @qdev_prop_array. @qdev_prop_array provides no information on the array > >> elements. Instead, Property member @arrayinfo points to the > >> PropertyInfo for the elements, and @arrayfieldsize is the size of an > >> element. > >> > >> Your series makes PropertyInfo array-capable: new members @element_info > >> and @element_size are the elements' PropertyInfo and size. It then adds > >> a proper PropertyInfo for each such property, and drops > >> @qdev_prop_array. > >> > >> Correct? > > > > Yes > > > >> > >> This could perhaps be spun out and merged separately to reduce the size > >> of future respins. > > > > I can split it out if it helps > > Splitting off self-contained parts of a big series can help if they can > be merged quicker than the entire series. We'll see. > > >> Not mentioned: > >> > >> - New QOM property creation functions for creating properties of > >> QAPI type. These take a QAPITypeInfo. > >> > >> - Convert some properties to use them. > >> > >> > - Removal of the deprecated PropertyInfo.type and .enum_table fields, > >> > and of the old object_property_add_enum/add_tm APIs. > >> > > >> > Along the way, a few pre-existing type mismatches in property > >> > definitions are fixed, the "struct tm" RTC property is replaced with a > >> > proper QAPI StructTm type etc. Introducing more specific types or a > >> > "typedef" to QAPI could help provide better associated type informations > >> > than plain "str" in many cases, for example. > >> > >> Examples? > >> > > > > Properties using str_type_info that carry structured values with their > > own validation: macaddr ("52:54:00:12:34:56"), PCI addresses > > ("04:00.0"), netdev names, chardev names, drive names, UUID strings. A > > QAPI "typedef" (or newtype) for e.g. MacAddr, PciDevAddr, UUID could > > let tools know these aren't arbitrary strings (see "hw/nvdimm: convert > > UUID property to QAPI-aware registration" patch). > > Two separate kinds: > > 1. Strings we need to parse: PCI addresses, MAC addresses, UUIDs, ... > > Parsing maps the string to something else, usually some object that > isn't a string. > > We avoid string parsing in QAPI/QMP whenever practical. You quoted > several examples where we don't. > > 2. IDs of things we need to resolve > > Resolving maps the string to the object it names. > > In both cases, we map strings to objects. > > QAPI is unaware of this. It simply uses strings in generated C. > > What if QAPI was aware? If the schema specified the object type, and > how to map from string to it? This is a step beyond a mere typedef. > The mapping would move from handwritten code to generated code. > Generated interfaces would use the object types instead of strings. > > Not now, of course. > > >> > Comments welcome! > >> > > >> > Signed-off-by: Marc-André Lureau <[email protected]> > >> > >