Statistics
| Branch: | Revision:

root / docs / qapi-code-gen.txt @ 69dd62df

History | View | Annotate | Download (14.3 kB)

1
= How to use the QAPI code generator =
2

    
3
* Note: as of this writing, QMP does not use QAPI. Eventually QMP
4
commands will be converted to use QAPI internally. The following
5
information describes QMP/QAPI as it will exist after the
6
conversion.
7

    
8
QAPI is a native C API within QEMU which provides management-level
9
functionality to internal/external users. For external
10
users/processes, this interface is made available by a JSON-based
11
QEMU Monitor protocol that is provided by the QMP server.
12

    
13
To map QMP-defined interfaces to the native C QAPI implementations,
14
a JSON-based schema is used to define types and function
15
signatures, and a set of scripts is used to generate types/signatures,
16
and marshaling/dispatch code. The QEMU Guest Agent also uses these
17
scripts, paired with a separate schema, to generate
18
marshaling/dispatch code for the guest agent server running in the
19
guest.
20

    
21
This document will describe how the schemas, scripts, and resulting
22
code is used.
23

    
24

    
25
== QMP/Guest agent schema ==
26

    
27
This file defines the types, commands, and events used by QMP.  It should
28
fully describe the interface used by QMP.
29

    
30
This file is designed to be loosely based on JSON although it's technically
31
executable Python.  While dictionaries are used, they are parsed as
32
OrderedDicts so that ordering is preserved.
33

    
34
There are two basic syntaxes used, type definitions and command definitions.
35

    
36
The first syntax defines a type and is represented by a dictionary.  There are
37
three kinds of user-defined types that are supported: complex types,
38
enumeration types and union types.
39

    
40
Generally speaking, types definitions should always use CamelCase for the type
41
names. Command names should be all lower case with words separated by a hyphen.
42

    
43
=== Complex types ===
44

    
45
A complex type is a dictionary containing a single key whose value is a
46
dictionary.  This corresponds to a struct in C or an Object in JSON.  An
47
example of a complex type is:
48

    
49
 { 'type': 'MyType',
50
   'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
51

    
52
The use of '*' as a prefix to the name means the member is optional.  Optional
53
members should always be added to the end of the dictionary to preserve
54
backwards compatibility.
55

    
56
=== Enumeration types ===
57

    
58
An enumeration type is a dictionary containing a single key whose value is a
59
list of strings.  An example enumeration is:
60

    
61
 { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
62

    
63
=== Union types ===
64

    
65
Union types are used to let the user choose between several different data
66
types.  A union type is defined using a dictionary as explained in the
67
following paragraphs.
68

    
69

    
70
A simple union type defines a mapping from discriminator values to data types
71
like in this example:
72

    
73
 { 'type': 'FileOptions', 'data': { 'filename': 'str' } }
74
 { 'type': 'Qcow2Options',
75
   'data': { 'backing-file': 'str', 'lazy-refcounts': 'bool' } }
76

    
77
 { 'union': 'BlockdevOptions',
78
   'data': { 'file': 'FileOptions',
79
             'qcow2': 'Qcow2Options' } }
80

    
81
In the QMP wire format, a simple union is represented by a dictionary that
82
contains the 'type' field as a discriminator, and a 'data' field that is of the
83
specified data type corresponding to the discriminator value:
84

    
85
 { "type": "qcow2", "data" : { "backing-file": "/some/place/my-image",
86
                               "lazy-refcounts": true } }
87

    
88

    
89
A union definition can specify a complex type as its base. In this case, the
90
fields of the complex type are included as top-level fields of the union
91
dictionary in the QMP wire format. An example definition is:
92

    
93
 { 'type': 'BlockdevCommonOptions', 'data': { 'readonly': 'bool' } }
94
 { 'union': 'BlockdevOptions',
95
   'base': 'BlockdevCommonOptions',
96
   'data': { 'raw': 'RawOptions',
97
             'qcow2': 'Qcow2Options' } }
98

    
99
And it looks like this on the wire:
100

    
101
 { "type": "qcow2",
102
   "readonly": false,
103
   "data" : { "backing-file": "/some/place/my-image",
104
              "lazy-refcounts": true } }
105

    
106

    
107
Flat union types avoid the nesting on the wire. They are used whenever a
108
specific field of the base type is declared as the discriminator ('type' is
109
then no longer generated). The discriminator must always be a string field.
110
The above example can then be modified as follows:
111

    
112
 { 'type': 'BlockdevCommonOptions',
113
   'data': { 'driver': 'str', 'readonly': 'bool' } }
114
 { 'union': 'BlockdevOptions',
115
   'base': 'BlockdevCommonOptions',
116
   'discriminator': 'driver',
117
   'data': { 'raw': 'RawOptions',
118
             'qcow2': 'Qcow2Options' } }
119

    
120
Resulting in this JSON object:
121

    
122
 { "driver": "qcow2",
123
   "readonly": false,
124
   "backing-file": "/some/place/my-image",
125
   "lazy-refcounts": true }
126

    
127

    
128
A special type of unions are anonymous unions. They don't form a dictionary in
129
the wire format but allow the direct use of different types in their place. As
130
they aren't structured, they don't have any explicit discriminator but use
131
the (QObject) data type of their value as an implicit discriminator. This means
132
that they are restricted to using only one discriminator value per QObject
133
type. For example, you cannot have two different complex types in an anonymous
134
union, or two different integer types.
135

    
136
Anonymous unions are declared using an empty dictionary as their discriminator.
137
The discriminator values never appear on the wire, they are only used in the
138
generated C code. Anonymous unions cannot have a base type.
139

    
140
 { 'union': 'BlockRef',
141
   'discriminator': {},
142
   'data': { 'definition': 'BlockdevOptions',
143
             'reference': 'str' } }
144

    
145
This example allows using both of the following example objects:
146

    
147
 { "file": "my_existing_block_device_id" }
148
 { "file": { "driver": "file",
149
             "readonly": false,
150
             'filename': "/tmp/mydisk.qcow2" } }
151

    
152

    
153
=== Commands ===
154

    
155
Commands are defined by using a list containing three members.  The first
156
member is the command name, the second member is a dictionary containing
157
arguments, and the third member is the return type.
158

    
159
An example command is:
160

    
161
 { 'command': 'my-command',
162
   'data': { 'arg1': 'str', '*arg2': 'str' },
163
   'returns': 'str' }
164

    
165

    
166
== Code generation ==
167

    
168
Schemas are fed into 3 scripts to generate all the code/files that, paired
169
with the core QAPI libraries, comprise everything required to take JSON
170
commands read in by a QMP/guest agent server, unmarshal the arguments into
171
the underlying C types, call into the corresponding C function, and map the
172
response back to a QMP/guest agent response to be returned to the user.
173

    
174
As an example, we'll use the following schema, which describes a single
175
complex user-defined type (which will produce a C struct, along with a list
176
node structure that can be used to chain together a list of such types in
177
case we want to accept/return a list of this type with a command), and a
178
command which takes that type as a parameter and returns the same type:
179

    
180
    mdroth@illuin:~/w/qemu2.git$ cat example-schema.json
181
    { 'type': 'UserDefOne',
182
      'data': { 'integer': 'int', 'string': 'str' } }
183

    
184
    { 'command': 'my-command',
185
      'data':    {'arg1': 'UserDefOne'},
186
      'returns': 'UserDefOne' }
187
    mdroth@illuin:~/w/qemu2.git$
188

    
189
=== scripts/qapi-types.py ===
190

    
191
Used to generate the C types defined by a schema. The following files are
192
created:
193

    
194
$(prefix)qapi-types.h - C types corresponding to types defined in
195
                        the schema you pass in
196
$(prefix)qapi-types.c - Cleanup functions for the above C types
197

    
198
The $(prefix) is an optional parameter used as a namespace to keep the
199
generated code from one schema/code-generation separated from others so code
200
can be generated/used from multiple schemas without clobbering previously
201
created code.
202

    
203
Example:
204

    
205
    mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
206
      --output-dir="qapi-generated" --prefix="example-" < example-schema.json
207
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
208
    /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
209

    
210
    #include "qapi/qapi-dealloc-visitor.h"
211
    #include "example-qapi-types.h"
212
    #include "example-qapi-visit.h"
213

    
214
    void qapi_free_UserDefOne(UserDefOne * obj)
215
    {
216
        QapiDeallocVisitor *md;
217
        Visitor *v;
218

    
219
        if (!obj) {
220
            return;
221
        }
222

    
223
        md = qapi_dealloc_visitor_new();
224
        v = qapi_dealloc_get_visitor(md);
225
        visit_type_UserDefOne(v, &obj, NULL, NULL);
226
        qapi_dealloc_visitor_cleanup(md);
227
    }
228

    
229
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.h
230
    /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
231
    #ifndef QAPI_GENERATED_EXAMPLE_QAPI_TYPES
232
    #define QAPI_GENERATED_EXAMPLE_QAPI_TYPES
233

    
234
    #include "qapi/qapi-types-core.h"
235

    
236
    typedef struct UserDefOne UserDefOne;
237

    
238
    typedef struct UserDefOneList
239
    {
240
        UserDefOne *value;
241
        struct UserDefOneList *next;
242
    } UserDefOneList;
243

    
244
    struct UserDefOne
245
    {
246
        int64_t integer;
247
        char * string;
248
    };
249

    
250
    void qapi_free_UserDefOne(UserDefOne * obj);
251

    
252
    #endif
253

    
254

    
255
=== scripts/qapi-visit.py ===
256

    
257
Used to generate the visitor functions used to walk through and convert
258
a QObject (as provided by QMP) to a native C data structure and
259
vice-versa, as well as the visitor function used to dealloc a complex
260
schema-defined C type.
261

    
262
The following files are generated:
263

    
264
$(prefix)qapi-visit.c: visitor function for a particular C type, used
265
                       to automagically convert QObjects into the
266
                       corresponding C type and vice-versa, as well
267
                       as for deallocating memory for an existing C
268
                       type
269

    
270
$(prefix)qapi-visit.h: declarations for previously mentioned visitor
271
                       functions
272

    
273
Example:
274

    
275
    mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
276
        --output-dir="qapi-generated" --prefix="example-" < example-schema.json
277
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
278
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
279

    
280
    #include "example-qapi-visit.h"
281

    
282
    void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp)
283
    {
284
        visit_start_struct(m, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), errp);
285
        visit_type_int(m, (obj && *obj) ? &(*obj)->integer : NULL, "integer", errp);
286
        visit_type_str(m, (obj && *obj) ? &(*obj)->string : NULL, "string", errp);
287
        visit_end_struct(m, errp);
288
    }
289

    
290
    void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp)
291
    {
292
        GenericList *i, **prev = (GenericList **)obj;
293

    
294
        visit_start_list(m, name, errp);
295

    
296
        for (; (i = visit_next_list(m, prev, errp)) != NULL; prev = &i) {
297
            UserDefOneList *native_i = (UserDefOneList *)i;
298
            visit_type_UserDefOne(m, &native_i->value, NULL, errp);
299
        }
300

    
301
        visit_end_list(m, errp);
302
    }
303
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.h
304
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
305

    
306
    #ifndef QAPI_GENERATED_EXAMPLE_QAPI_VISIT
307
    #define QAPI_GENERATED_EXAMPLE_QAPI_VISIT
308

    
309
    #include "qapi/qapi-visit-core.h"
310
    #include "example-qapi-types.h"
311

    
312
    void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp);
313
    void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp);
314

    
315
    #endif
316
    mdroth@illuin:~/w/qemu2.git$
317

    
318
(The actual structure of the visit_type_* functions is a bit more complex
319
in order to propagate errors correctly and avoid leaking memory).
320

    
321
=== scripts/qapi-commands.py ===
322

    
323
Used to generate the marshaling/dispatch functions for the commands defined
324
in the schema. The following files are generated:
325

    
326
$(prefix)qmp-marshal.c: command marshal/dispatch functions for each
327
                        QMP command defined in the schema. Functions
328
                        generated by qapi-visit.py are used to
329
                        convert QObjects received from the wire into
330
                        function parameters, and uses the same
331
                        visitor functions to convert native C return
332
                        values to QObjects from transmission back
333
                        over the wire.
334

    
335
$(prefix)qmp-commands.h: Function prototypes for the QMP commands
336
                         specified in the schema.
337

    
338
Example:
339

    
340
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qmp-marshal.c
341
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
342

    
343
    #include "qemu-objects.h"
344
    #include "qapi/qmp-core.h"
345
    #include "qapi/qapi-visit-core.h"
346
    #include "qapi/qmp-output-visitor.h"
347
    #include "qapi/qmp-input-visitor.h"
348
    #include "qapi/qapi-dealloc-visitor.h"
349
    #include "example-qapi-types.h"
350
    #include "example-qapi-visit.h"
351

    
352
    #include "example-qmp-commands.h"
353
    static void qmp_marshal_output_my_command(UserDefOne * ret_in, QObject **ret_out, Error **errp)
354
    {
355
        QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
356
        QmpOutputVisitor *mo = qmp_output_visitor_new();
357
        Visitor *v;
358

    
359
        v = qmp_output_get_visitor(mo);
360
        visit_type_UserDefOne(v, &ret_in, "unused", errp);
361
        v = qapi_dealloc_get_visitor(md);
362
        visit_type_UserDefOne(v, &ret_in, "unused", errp);
363
        qapi_dealloc_visitor_cleanup(md);
364

    
365

    
366
        *ret_out = qmp_output_get_qobject(mo);
367
    }
368

    
369
    static void qmp_marshal_input_my_command(QmpState *qmp__sess, QDict *args, QObject **ret, Error **errp)
370
    {
371
        UserDefOne * retval = NULL;
372
        QmpInputVisitor *mi;
373
        QapiDeallocVisitor *md;
374
        Visitor *v;
375
        UserDefOne * arg1 = NULL;
376

    
377
        mi = qmp_input_visitor_new(QOBJECT(args));
378
        v = qmp_input_get_visitor(mi);
379
        visit_type_UserDefOne(v, &arg1, "arg1", errp);
380

    
381
        if (error_is_set(errp)) {
382
            goto out;
383
        }
384
        retval = qmp_my_command(arg1, errp);
385
        qmp_marshal_output_my_command(retval, ret, errp);
386

    
387
    out:
388
        md = qapi_dealloc_visitor_new();
389
        v = qapi_dealloc_get_visitor(md);
390
        visit_type_UserDefOne(v, &arg1, "arg1", errp);
391
        qapi_dealloc_visitor_cleanup(md);
392
        return;
393
    }
394

    
395
    static void qmp_init_marshal(void)
396
    {
397
        qmp_register_command("my-command", qmp_marshal_input_my_command);
398
    }
399

    
400
    qapi_init(qmp_init_marshal);
401
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qmp-commands.h
402
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
403

    
404
    #ifndef QAPI_GENERATED_EXAMPLE_QMP_COMMANDS
405
    #define QAPI_GENERATED_EXAMPLE_QMP_COMMANDS
406

    
407
    #include "example-qapi-types.h"
408
    #include "error.h"
409

    
410
    UserDefOne * qmp_my_command(UserDefOne * arg1, Error **errp);
411

    
412
    #endif
413
    mdroth@illuin:~/w/qemu2.git$