Am 12.11.2020 um 19:34 hat Eric Blake geschrieben:
On 11/12/20 11:28 AM, Kevin Wolf wrote:
> Introduce alias definitions for object types (structs and unions). This
> allows using the same QAPI type and visitor for many syntax variations
> that exist in the external representation, like between QMP and the
> command line. It also provides a new tool for evolving the schema while
> maintaining backwards compatibility during a deprecation period.
Cool! Obvious followup patch series: deprecate all QAPI members spelled
with _ by making them aliases of new members spelled with -, so that we
can finally have consistent spellings.
Ah, that's a nice one, too. I didn't even think of it. Another one I'd
like to see is deprecation of SocketAddressLegacy.
There is one part missing in this series that we would first need to
address before we can actually use it to evolve parts of the schema that
are visible in QMP: Exposing aliases in introspection and expressing
that the original name of something is deprecated, but the alias will
stay around (and probably also deprecating an alias without the original
name or other aliases).
If we can easily figure out a way to express this that everyone agrees
with, I'm happy to include it in this series. Otherwise, since the first
user is the command line and not QMP, I'd leave that for the future.
For example, imagine we have an option 'foo' with a new alias 'bar'. If
we just directly expose the alias rule (which would be the simplest
solution from the QEMU perspective), management will check if the alias
exists before accessing 'bar'. But in the final state, we remove 'foo'
and 'bar' is not an alias any more, so the introspection for 'bar' would
change. Is this desirable?
On the other hand, we can't specify both as normal options because you
must set (at most) one of them, but not both. Also exposing things as
normal options becomes hard with wildcard aliases (mapping all fields
from a nested struct), especially if unions are involved where some
options exist in one or two variants, but not in others.
Given this, I think just exposing the alias rules and letting the
management tool check both alternatives - if the alias rule or the
future option exists - might actually still be the least bad option.
Hmm, I guess I should CC libvirt for this discussion, actually. :-)
> +=== Aliases ===
> +
> +Object types, including structs and unions, can contain alias
> +definitions.
> +
> +Aliases define alternative member names that may be used in the
> +external representation to provide a value for a member in the same
> +object or in a nested object.
> +
> +Syntax:
> + ALIAS = { '*alias': STRING,
> + 'source': [ STRING, ... ] }
> +
> +'source' is a list of member names representing the path to an object
> +member, starting from the type where the alias definition is
> +specified. It may refer to another alias name. It is allowed to use
> +a path that doesn't necessarily match an existing member in every
> +variant or even at all; in this case, the alias remains unused.
> +
> +If 'alias' is present, then the single member referred to by
'source'
> +is made accessible with the name given in 'alias' in the type where
> +the alias definition is specified.
> +
> +If 'alias' is not present, then all members in the object referred to
> +by 'source' are made accessible in the type where the alias definition
> +is specified with the same name as they have in 'source'.
Is it worth an example of how to use this?
Yes, I should have included an example. Or actually, probably one
example for aliasing a single field and another one for a wildcard alias
that maps all fields in a struct.
Kevin