On Wed, Aug 12, 2026 at 05:54:49AM -0700, Pierrick Bouvier wrote:
> On 8/12/2026 3:52 AM, Daniel P. Berrangé wrote:
> > On Mon, Aug 10, 2026 at 03:26:26PM -0700, Pierrick Bouvier wrote:
> >> I have been experimenting today with static filtering of types, as you
> >> suggested, and came up with two possibilities. Before implementing this
> >> for all types, I would like to get some feedback on which way is the
> >> best for you.
> >>
> >> 1. Add a new callback is_available to TypeInfo, similar to existing
> >> interface.
> >> Pros: local information is present in type definition, making obvious
> >> why a type is available or not. Very easy to implement
> >> since only type_register_static has to be modified to check it.
> >> Cons: Add a new field to each existing type. Not the end of the world
> >> in terms of memory consumption, but worth mentioning.
> >> 2. Add conditional around each type_register_static, or add an
> >> alternative type_register_static_cond function.
> >> Pros: I don't see any
> >> Cons: Decouples type information from type definition, makes it harder
> >> to follow why a type is available or not. Much more verbose since
> >> we need to modify all type_register_static buried in macros.
> >>
> >> Based on this, I'm much more in favor or 1. The fact availability
> >> information is in the same location than type definition is the biggest
> >> advantage for me.
> >>
> >> On example given above, this would give something like this:
> >> static const TypeInfo emulated_card_info = {
> >> .name = TYPE_EMULATED_CCID,
> >> .parent = TYPE_CCID_CARD,
> >> .instance_size = sizeof(EmulatedState),
> >> .class_init = emulated_class_initfn,
> >> .is_available = target_config_X,
> >> };
> >>
> >> Would that work for you?
> >> Do you have a 3rd way to offer to solve the problem we have?
> >
> > In the case of user creatable objects, we represented a classes'
> > conditional availablity in QAPI schema. For example:
> >
> > { 'struct': 'InputLinuxProperties',
> > 'data': { 'evdev': 'str',
> > '*grab_all': 'bool',
> > '*repeat': 'bool',
> > '*grab-toggle': 'GrabToggleKeys' },
> > 'if': 'CONFIG_LINUX' }
> >
> > Now this isn't quite a match for what we want, as QAPI schema is
> > common to all targets and used to control the code generator to
> > turn off output. Thus the permitted CONFIG_xxx are only those in
> > config-host.mak, not any from $TARGET-softmmu-config-devices.mak
> >
> > The other scenario in QAPI is the concept of features:
> >
> > { 'struct': 'SevCommonProperties',
> > 'data': { '*sev-device': 'str',
> > '*cbitpos': 'uint32',
> > 'reduced-phys-bits': 'uint32',
> > '*kernel-hashes': 'bool' },
> > 'features': ['confidential-guest-reset']}
> >
> > where again we just have a list of named strings. Features are fully
> > dynamic, and crucially they are introspectable so applications can
> > query at runtime what is available.
> >
> > The introspection concept is something that is highly likely to be
> > relevant to our use cases here. If we have a single binary with all
> > types, it would be very valuable to be able to query it once to
> > discover everything in one go, instead of havnig to query it over
> > and over again for each target. That implies the application doing
> > the query needs to be told about per-target usage restrictions on
> > types it is querying.
> >
> > We don't have QAPI schema for QDev devices currently, but it is likely
> > we will do so in the future. We can't wait for that though as there is
> > no clear ETA.
> >
> > What this all says to me though, is that instead of an 'is_available'
> > method, we should instead just list the conditions as data in the
> > TypeInfo struct directly. IOW a list of const strings like this:
> >
> > static const TypeInfo emulated_card_info = {
> > .name = TYPE_EMULATED_CCID,
> > .parent = TYPE_CCID_CARD,
> > .instance_size = sizeof(EmulatedState),
> > .class_init = emulated_class_initfn,
> > .available = (const char *[]){ TARGET_AARCH64, CONFIG_something
> > .... },
> > };
> >
> > This will make it easy to add in introspection at a later date.
> >
> > The limitation is that this can only express an "AND" condition.
> > You can not do complex AND+OR+grouping conditions that you could
> > express in code, but IMHO that is not likely to be a problem.
> > In the worst case you can define a higher level "CONFIG_BLAH"
> > that encapsulates the complex condition.
> >
>
> Those strings names reuse existing target config identifiers, which
> can't be done because of config poisoning.
> The string compare will definitively be visible at boot time, so we
> should rely on enum instead if we go in this direction.
>
> I'm a bit worried about verbosity of the result:
> .available = (const char *[]){ ENUM_NAME_TARGET_AARCH64, {} }
> versus:
> is_available = target_aarch64
The verbosity could be hidden behind a macro that takes a tar
#define QOM_AVAIL_TGT(name) \
.available = (const char *[]) ENUM_TARGET # name, NULL }
So usage becomes
static const TypeInfo emulated_card_info = {
.name = TYPE_EMULATED_CCID,
.parent = TYPE_CCID_CARD,
.instance_size = sizeof(EmulatedState),
.class_init = emulated_class_initfn,
QOM_AVAIL_TGT(AARCH64),
}
A separate macro could be defined for the more complex case
wanting multiple config options.
> 99% of the types will be filtered by target only, for which we have
> functions in target-info API. Only a few of them will need custom
> functions. It would be worth having a nice/short way to write this
> without having to declare all combination in a file.
> One of your point was to not include more macros, and seems like we'll
> end up this way.
In this case the macros expand to data that is machine consumable
at runtime, so I thjnk that's a good tradeoff.
> The introspection argument is good, but will we really need that? The
> whole point of conversation was to register only types available,
> ignoring the rest. If you want introspection, it means registering all
> types and selectively filter them.
Yes, introspection is critical to mgmt apps and places where we
forget/miss it cause endless pain.
With regards,
Daniel
--
|: https://berrange.com ~~ https://hachyderm.io/@berrange :|
|: https://libvirt.org ~~ https://entangle-photo.org :|
|: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|