qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Integrating QOM into QAPI (was: Making QEMU easier for management tools


From: Markus Armbruster
Subject: Integrating QOM into QAPI (was: Making QEMU easier for management tools and applications)
Date: Tue, 21 Jan 2020 14:36:17 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Marc-André Lureau <address@hidden> writes:

> Hi
>
> On Tue, Jan 21, 2020 at 3:32 PM Stefan Hajnoczi <address@hidden> wrote:
>>
>> On Tue, Jan 21, 2020 at 06:42:47AM +0100, Markus Armbruster wrote:
>> > Stefan Hajnoczi <address@hidden> writes:
>> >
>> > > On Wed, Jan 15, 2020 at 01:15:17PM +0100, Markus Armbruster wrote:
>> > >> Christophe de Dinechin <address@hidden> writes:
>> > >> >> On 15 Jan 2020, at 10:20, Markus Armbruster <address@hidden> wrote:
>> > >> * qemuMonitorJSONSetIOThread() uses it to control iothread's properties
>> > >>   poll-max-ns, poll-grow, poll-shrink.  Their use with -object is
>> > >>   documented (in qemu-options.hx), their use with qom-set is not.
>> > >
>> > > I'm happy to use a different interface.
>> > >
>> > > Writing a boilerplate "iothread-set-poll-params" QMP command in C would
>> > > be a step backwards.
>> >
>> > No argument.
>> >
>> > > Maybe the QAPI code generator could map something like this:
>> > >
>> > >   { 'command': 'iothread-set-poll-params',
>> > >     'data': {
>> > >         'id': 'str',
>> > >     '*max-ns': 'uint64',
>> > >     '*grow': 'uint64',
>> > >     '*shrink': 'uint64'
>> > >     },
>> > >     'map-to-qom-set': 'IOThread'
>> > >   }
>> > >
>> > > And turn it into QOM accessors on the IOThread object.
>> >
>> > I think a generic "set this configuration to that value" command is just
>> > fine.  qom-set fails on several counts, though:
>> >
>> > * Tolerable: qom-set is not actually generic, it applies only to QOM.
>> >
>> > * qom-set lets you set tons of stuff that is not meant to be changed at
>> >   run time.  If it breaks your guest, you get to keep the pieces.
>> >
>> > * There is virtually no documentation on what can be set to what values,
>> >   and their semantics.
>> >
>> > In its current state, QOM is a user interface superfund site.
>>
>> Thoughts about a solution:
>>
>> Static QOM properties should be declared via QAPI instead of
>> imperatively via QOM APIs.  That way they are introspectable and type
>> information is present in the schema.
>>
>> The QAPI code generator could emit a function that is callable from
>> .class_init().  This eliminates the need to manually call
>> object_class_property_add().

We need to make up our minds what exactly we want generated.  Then we
can design the QAPI language, and code up the generator.

Skeleton QOM type, to help with the discussion:

    #define TYPE_FOO "foo"

    #define FOO(obj) OBJECT_CHECK(Foo, (obj), TYPE_FOO)
    #define FOO_CLASS(klass) \
        OBJECT_CLASS_CHECK(FooClass, (klass), TYPE_FOO)
    #define FOO_GET_CLASS(obj) \
        OBJECT_GET_CLASS(FooClass, (obj), TYPE_FOO)

    typedef FooClass {
        ParentClass parent_class;
        ... // hand-written per-class state
    }

    struct Chardev {
        ParentObject parent_obj;
        ... // hand-written instance (per-object) state
    };

    static const TypeInfo char_type_info = {
        .name = TYPE_FOO,
        .parent = TYPE_OBJECT,
        .instance_size = sizeof(Foo),
        .instance_init = ...,                   // methods to initialize
        .instance_post_init = ...,              // and finalize instances,
        .instance_finalize = ...,               // all optional
        .abstract = ...,                        // true or false (d'oh)
        .class_size = sizeof(FooClass),
        .class_init = ...,                      // methods to initialize
        .class_base_init = ...,                 // classes, optional
        .class_data = ...,                      // extra argument for them
        .interfaces = ...
    };

There's substantial boilerplate, with plenty of hand-written code in the
gaps.  What of the boilerplate do we plan to generate?  How do we plan
to fill the gaps, if any?

A "property" is always a property of an instance.  It can either be
registered with the instance (with object_property_add() & friends) or
the class (with object_class_property_add() & friends).  Yes, the naming
is confusing.

To have QAPI register properties with the class, it needs to generate
a variation of

    object_class_property_add(cls, prop_name, type_name,
                              get, set, release, opaque, &err)

for each property "somewhere", so it runs within .class_init().  For
real QAPI integration, the property's type must be a QAPI type.  QAPI
needs to generate the callbacks get(), set() and release() then.

Existing properties could conceivably do funny things in their
handwritten callbacks, defying conversion to this scheme.  There's just
one way to find out: attempt to convert all of them.

> I have this in mind too. First step is probably to move as much as
> possible as class properties.

We don't *have* to move "as much as possible" to support such a QAPI
integration, only the ones we want to expose to the user via QAPI.  But
we *want* to, because its an improvement on its own.

>                               Please review
> https://patchew.org/QEMU/address@hidden/,
> I have more of this kind of qdev/qom cleanups pending.

Please lend Marc-André a hand whenever this work touches your area of
expertise :)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]