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
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.
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.
Considering this, I would be more in favor to stick to something simpler
for now. It should be trivial to change if one day introspection becomes
a real use case.
What do you think?
> With regards,
> Daniel
Regards,
Pierrick