Statistics
| Branch: | Revision:

root / docs / qapi-code-gen.txt @ 2542bfd5

History | View | Annotate | Download (10.9 kB)

1 b84da831 Michael Roth
= How to use the QAPI code generator =
2 b84da831 Michael Roth
3 b84da831 Michael Roth
* Note: as of this writing, QMP does not use QAPI. Eventually QMP
4 b84da831 Michael Roth
commands will be converted to use QAPI internally. The following
5 b84da831 Michael Roth
information describes QMP/QAPI as it will exist after the
6 b84da831 Michael Roth
conversion.
7 b84da831 Michael Roth
8 b84da831 Michael Roth
QAPI is a native C API within QEMU which provides management-level
9 b84da831 Michael Roth
functionality to internal/external users. For external
10 b84da831 Michael Roth
users/processes, this interface is made available by a JSON-based
11 b84da831 Michael Roth
QEMU Monitor protocol that is provided by the QMP server.
12 b84da831 Michael Roth
13 b84da831 Michael Roth
To map QMP-defined interfaces to the native C QAPI implementations,
14 b84da831 Michael Roth
a JSON-based schema is used to define types and function
15 b84da831 Michael Roth
signatures, and a set of scripts is used to generate types/signatures,
16 b84da831 Michael Roth
and marshaling/dispatch code. The QEMU Guest Agent also uses these
17 b84da831 Michael Roth
scripts, paired with a seperate schema, to generate
18 b84da831 Michael Roth
marshaling/dispatch code for the guest agent server running in the
19 b84da831 Michael Roth
guest.
20 b84da831 Michael Roth
21 b84da831 Michael Roth
This document will describe how the schemas, scripts, and resulting
22 b84da831 Michael Roth
code is used.
23 b84da831 Michael Roth
24 b84da831 Michael Roth
25 b84da831 Michael Roth
== QMP/Guest agent schema ==
26 b84da831 Michael Roth
27 b84da831 Michael Roth
This file defines the types, commands, and events used by QMP.  It should
28 b84da831 Michael Roth
fully describe the interface used by QMP.
29 b84da831 Michael Roth
30 b84da831 Michael Roth
This file is designed to be loosely based on JSON although it's technically
31 b84da831 Michael Roth
executable Python.  While dictionaries are used, they are parsed as
32 b84da831 Michael Roth
OrderedDicts so that ordering is preserved.
33 b84da831 Michael Roth
34 b84da831 Michael Roth
There are two basic syntaxes used, type definitions and command definitions.
35 b84da831 Michael Roth
36 b84da831 Michael Roth
The first syntax defines a type and is represented by a dictionary.  There are
37 b84da831 Michael Roth
two kinds of types that are supported: complex user-defined types, and enums.
38 b84da831 Michael Roth
39 b84da831 Michael Roth
A complex type is a dictionary containing a single key who's value is a
40 b84da831 Michael Roth
dictionary.  This corresponds to a struct in C or an Object in JSON.  An
41 b84da831 Michael Roth
example of a complex type is:
42 b84da831 Michael Roth
43 b84da831 Michael Roth
 { 'type': 'MyType',
44 b84da831 Michael Roth
   'data' { 'member1': 'str', 'member2': 'int', '*member3': 'str } }
45 b84da831 Michael Roth
46 b84da831 Michael Roth
The use of '*' as a prefix to the name means the member is optional.  Optional
47 b84da831 Michael Roth
members should always be added to the end of the dictionary to preserve
48 b84da831 Michael Roth
backwards compatibility.
49 b84da831 Michael Roth
50 b84da831 Michael Roth
An enumeration type is a dictionary containing a single key who's value is a
51 b84da831 Michael Roth
list of strings.  An example enumeration is:
52 b84da831 Michael Roth
53 b84da831 Michael Roth
 { 'enum': 'MyEnum', 'data': [ 'value1', 'value2', 'value3' ] }
54 b84da831 Michael Roth
55 b84da831 Michael Roth
Generally speaking, complex types and enums should always use CamelCase for
56 b84da831 Michael Roth
the type names.
57 b84da831 Michael Roth
58 b84da831 Michael Roth
Commands are defined by using a list containing three members.  The first
59 b84da831 Michael Roth
member is the command name, the second member is a dictionary containing
60 b84da831 Michael Roth
arguments, and the third member is the return type.
61 b84da831 Michael Roth
62 b84da831 Michael Roth
An example command is:
63 b84da831 Michael Roth
64 b84da831 Michael Roth
 { 'command': 'my-command',
65 b84da831 Michael Roth
   'data': { 'arg1': 'str', '*arg2': 'str' },
66 b84da831 Michael Roth
   'returns': 'str' ]
67 b84da831 Michael Roth
68 b84da831 Michael Roth
Command names should be all lower case with words separated by a hyphen.
69 b84da831 Michael Roth
70 b84da831 Michael Roth
71 b84da831 Michael Roth
== Code generation ==
72 b84da831 Michael Roth
73 b84da831 Michael Roth
Schemas are fed into 3 scripts to generate all the code/files that, paired
74 b84da831 Michael Roth
with the core QAPI libraries, comprise everything required to take JSON
75 b84da831 Michael Roth
commands read in by a QMP/guest agent server, unmarshal the arguments into
76 b84da831 Michael Roth
the underlying C types, call into the corresponding C function, and map the
77 b84da831 Michael Roth
response back to a QMP/guest agent response to be returned to the user.
78 b84da831 Michael Roth
79 b84da831 Michael Roth
As an example, we'll use the following schema, which describes a single
80 b84da831 Michael Roth
complex user-defined type (which will produce a C struct, along with a list
81 b84da831 Michael Roth
node structure that can be used to chain together a list of such types in
82 b84da831 Michael Roth
case we want to accept/return a list of this type with a command), and a
83 b84da831 Michael Roth
command which takes that type as a parameter and returns the same type:
84 b84da831 Michael Roth
85 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat example-schema.json
86 b84da831 Michael Roth
    { 'type': 'UserDefOne',
87 b84da831 Michael Roth
      'data': { 'integer': 'int', 'string': 'str' } }
88 b84da831 Michael Roth
89 b84da831 Michael Roth
    { 'command': 'my-command',
90 b84da831 Michael Roth
      'data':    {'arg1': 'UserDefOne'},
91 b84da831 Michael Roth
      'returns': 'UserDefOne' }
92 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$
93 b84da831 Michael Roth
94 b84da831 Michael Roth
=== scripts/qapi-types.py ===
95 b84da831 Michael Roth
96 b84da831 Michael Roth
Used to generate the C types defined by a schema. The following files are
97 b84da831 Michael Roth
created:
98 b84da831 Michael Roth
99 b84da831 Michael Roth
$(prefix)qapi-types.h - C types corresponding to types defined in
100 b84da831 Michael Roth
                        the schema you pass in
101 b84da831 Michael Roth
$(prefix)qapi-types.c - Cleanup functions for the above C types
102 b84da831 Michael Roth
103 b84da831 Michael Roth
The $(prefix) is an optional parameter used as a namespace to keep the
104 b84da831 Michael Roth
generated code from one schema/code-generation separated from others so code
105 b84da831 Michael Roth
can be generated/used from multiple schemas without clobbering previously
106 b84da831 Michael Roth
created code.
107 b84da831 Michael Roth
108 b84da831 Michael Roth
Example:
109 b84da831 Michael Roth
110 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
111 b84da831 Michael Roth
      --output-dir="qapi-generated" --prefix="example-" < example-schema.json
112 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
113 b84da831 Michael Roth
    /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
114 b84da831 Michael Roth
115 b84da831 Michael Roth
    #include "qapi/qapi-dealloc-visitor.h"
116 b84da831 Michael Roth
    #include "example-qapi-types.h"
117 b84da831 Michael Roth
    #include "example-qapi-visit.h"
118 b84da831 Michael Roth
119 b84da831 Michael Roth
    void qapi_free_UserDefOne(UserDefOne * obj)
120 b84da831 Michael Roth
    {
121 b84da831 Michael Roth
        QapiDeallocVisitor *md;
122 b84da831 Michael Roth
        Visitor *v;
123 b84da831 Michael Roth
124 b84da831 Michael Roth
        if (!obj) {
125 b84da831 Michael Roth
            return;
126 b84da831 Michael Roth
        }
127 b84da831 Michael Roth
128 b84da831 Michael Roth
        md = qapi_dealloc_visitor_new();
129 b84da831 Michael Roth
        v = qapi_dealloc_get_visitor(md);
130 b84da831 Michael Roth
        visit_type_UserDefOne(v, &obj, NULL, NULL);
131 b84da831 Michael Roth
        qapi_dealloc_visitor_cleanup(md);
132 b84da831 Michael Roth
    }
133 b84da831 Michael Roth
134 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.h
135 b84da831 Michael Roth
    /* AUTOMATICALLY GENERATED, DO NOT MODIFY */
136 b84da831 Michael Roth
    #ifndef QAPI_GENERATED_EXAMPLE_QAPI_TYPES
137 b84da831 Michael Roth
    #define QAPI_GENERATED_EXAMPLE_QAPI_TYPES
138 b84da831 Michael Roth
139 b84da831 Michael Roth
    #include "qapi/qapi-types-core.h"
140 b84da831 Michael Roth
141 b84da831 Michael Roth
    typedef struct UserDefOne UserDefOne;
142 b84da831 Michael Roth
143 b84da831 Michael Roth
    typedef struct UserDefOneList
144 b84da831 Michael Roth
    {
145 b84da831 Michael Roth
        UserDefOne *value;
146 b84da831 Michael Roth
        struct UserDefOneList *next;
147 b84da831 Michael Roth
    } UserDefOneList;
148 b84da831 Michael Roth
149 b84da831 Michael Roth
    struct UserDefOne
150 b84da831 Michael Roth
    {
151 b84da831 Michael Roth
        int64_t integer;
152 b84da831 Michael Roth
        char * string;
153 b84da831 Michael Roth
    };
154 b84da831 Michael Roth
155 b84da831 Michael Roth
    void qapi_free_UserDefOne(UserDefOne * obj);
156 b84da831 Michael Roth
157 b84da831 Michael Roth
    #endif
158 b84da831 Michael Roth
159 b84da831 Michael Roth
160 b84da831 Michael Roth
=== scripts/qapi-visit.py ===
161 b84da831 Michael Roth
162 b84da831 Michael Roth
Used to generate the visitor functions used to walk through and convert
163 b84da831 Michael Roth
a QObject (as provided by QMP) to a native C data structure and
164 b84da831 Michael Roth
vice-versa, as well as the visitor function used to dealloc a complex
165 b84da831 Michael Roth
schema-defined C type.
166 b84da831 Michael Roth
167 b84da831 Michael Roth
The following files are generated:
168 b84da831 Michael Roth
169 b84da831 Michael Roth
$(prefix)qapi-visit.c: visitor function for a particular C type, used
170 b84da831 Michael Roth
                       to automagically convert QObjects into the
171 b84da831 Michael Roth
                       corresponding C type and vice-versa, as well
172 b84da831 Michael Roth
                       as for deallocating memory for an existing C
173 b84da831 Michael Roth
                       type
174 b84da831 Michael Roth
175 b84da831 Michael Roth
$(prefix)qapi-visit.h: declarations for previously mentioned visitor
176 b84da831 Michael Roth
                       functions
177 b84da831 Michael Roth
178 b84da831 Michael Roth
Example:
179 b84da831 Michael Roth
180 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
181 b84da831 Michael Roth
        --output-dir="qapi-generated" --prefix="example-" < example-schema.json
182 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
183 b84da831 Michael Roth
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
184 b84da831 Michael Roth
185 b84da831 Michael Roth
    #include "example-qapi-visit.h"
186 b84da831 Michael Roth
187 b84da831 Michael Roth
    void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp)
188 b84da831 Michael Roth
    {
189 b84da831 Michael Roth
        visit_start_struct(m, (void **)obj, "UserDefOne", name, sizeof(UserDefOne), errp);
190 b84da831 Michael Roth
        visit_type_int(m, (obj && *obj) ? &(*obj)->integer : NULL, "integer", errp);
191 b84da831 Michael Roth
        visit_type_str(m, (obj && *obj) ? &(*obj)->string : NULL, "string", errp);
192 b84da831 Michael Roth
        visit_end_struct(m, errp);
193 b84da831 Michael Roth
    }
194 b84da831 Michael Roth
195 b84da831 Michael Roth
    void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp)
196 b84da831 Michael Roth
    {
197 b84da831 Michael Roth
        GenericList *i;
198 b84da831 Michael Roth
199 b84da831 Michael Roth
        visit_start_list(m, name, errp);
200 b84da831 Michael Roth
201 b84da831 Michael Roth
        for (i = visit_next_list(m, (GenericList **)obj, errp); i; i = visit_next_list(m, &i, errp)) {
202 b84da831 Michael Roth
            UserDefOneList *native_i = (UserDefOneList *)i;
203 b84da831 Michael Roth
            visit_type_UserDefOne(m, &native_i->value, NULL, errp);
204 b84da831 Michael Roth
        }
205 b84da831 Michael Roth
206 b84da831 Michael Roth
        visit_end_list(m, errp);
207 b84da831 Michael Roth
    }
208 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.h
209 b84da831 Michael Roth
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
210 b84da831 Michael Roth
211 b84da831 Michael Roth
    #ifndef QAPI_GENERATED_EXAMPLE_QAPI_VISIT
212 b84da831 Michael Roth
    #define QAPI_GENERATED_EXAMPLE_QAPI_VISIT
213 b84da831 Michael Roth
214 b84da831 Michael Roth
    #include "qapi/qapi-visit-core.h"
215 b84da831 Michael Roth
    #include "example-qapi-types.h"
216 b84da831 Michael Roth
217 b84da831 Michael Roth
    void visit_type_UserDefOne(Visitor *m, UserDefOne ** obj, const char *name, Error **errp);
218 b84da831 Michael Roth
    void visit_type_UserDefOneList(Visitor *m, UserDefOneList ** obj, const char *name, Error **errp);
219 b84da831 Michael Roth
220 b84da831 Michael Roth
    #endif
221 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$
222 b84da831 Michael Roth
223 b84da831 Michael Roth
224 b84da831 Michael Roth
=== scripts/qapi-commands.py ===
225 b84da831 Michael Roth
226 b84da831 Michael Roth
Used to generate the marshaling/dispatch functions for the commands defined
227 b84da831 Michael Roth
in the schema. The following files are generated:
228 b84da831 Michael Roth
229 b84da831 Michael Roth
$(prefix)qmp-marshal.c: command marshal/dispatch functions for each
230 b84da831 Michael Roth
                        QMP command defined in the schema. Functions
231 b84da831 Michael Roth
                        generated by qapi-visit.py are used to
232 2542bfd5 Stefan Weil
                        convert QObjects received from the wire into
233 b84da831 Michael Roth
                        function parameters, and uses the same
234 b84da831 Michael Roth
                        visitor functions to convert native C return
235 b84da831 Michael Roth
                        values to QObjects from transmission back
236 b84da831 Michael Roth
                        over the wire.
237 b84da831 Michael Roth
238 b84da831 Michael Roth
$(prefix)qmp-commands.h: Function prototypes for the QMP commands
239 b84da831 Michael Roth
                         specified in the schema.
240 b84da831 Michael Roth
241 b84da831 Michael Roth
Example:
242 b84da831 Michael Roth
243 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qmp-marshal.c
244 b84da831 Michael Roth
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
245 b84da831 Michael Roth
246 b84da831 Michael Roth
    #include "qemu-objects.h"
247 b84da831 Michael Roth
    #include "qapi/qmp-core.h"
248 b84da831 Michael Roth
    #include "qapi/qapi-visit-core.h"
249 b84da831 Michael Roth
    #include "qapi/qmp-output-visitor.h"
250 b84da831 Michael Roth
    #include "qapi/qmp-input-visitor.h"
251 b84da831 Michael Roth
    #include "qapi/qapi-dealloc-visitor.h"
252 b84da831 Michael Roth
    #include "example-qapi-types.h"
253 b84da831 Michael Roth
    #include "example-qapi-visit.h"
254 b84da831 Michael Roth
255 b84da831 Michael Roth
    #include "example-qmp-commands.h"
256 b84da831 Michael Roth
    static void qmp_marshal_output_my_command(UserDefOne * ret_in, QObject **ret_out, Error **errp)
257 b84da831 Michael Roth
    {
258 b84da831 Michael Roth
        QapiDeallocVisitor *md = qapi_dealloc_visitor_new();
259 b84da831 Michael Roth
        QmpOutputVisitor *mo = qmp_output_visitor_new();
260 b84da831 Michael Roth
        Visitor *v;
261 b84da831 Michael Roth
262 b84da831 Michael Roth
        v = qmp_output_get_visitor(mo);
263 b84da831 Michael Roth
        visit_type_UserDefOne(v, &ret_in, "unused", errp);
264 b84da831 Michael Roth
        v = qapi_dealloc_get_visitor(md);
265 b84da831 Michael Roth
        visit_type_UserDefOne(v, &ret_in, "unused", errp);
266 b84da831 Michael Roth
        qapi_dealloc_visitor_cleanup(md);
267 b84da831 Michael Roth
268 b84da831 Michael Roth
269 b84da831 Michael Roth
        *ret_out = qmp_output_get_qobject(mo);
270 b84da831 Michael Roth
    }
271 b84da831 Michael Roth
272 b84da831 Michael Roth
    static void qmp_marshal_input_my_command(QmpState *qmp__sess, QDict *args, QObject **ret, Error **errp)
273 b84da831 Michael Roth
    {
274 b84da831 Michael Roth
        UserDefOne * retval = NULL;
275 b84da831 Michael Roth
        QmpInputVisitor *mi;
276 b84da831 Michael Roth
        QapiDeallocVisitor *md;
277 b84da831 Michael Roth
        Visitor *v;
278 b84da831 Michael Roth
        UserDefOne * arg1 = NULL;
279 b84da831 Michael Roth
280 b84da831 Michael Roth
        mi = qmp_input_visitor_new(QOBJECT(args));
281 b84da831 Michael Roth
        v = qmp_input_get_visitor(mi);
282 b84da831 Michael Roth
        visit_type_UserDefOne(v, &arg1, "arg1", errp);
283 b84da831 Michael Roth
284 b84da831 Michael Roth
        if (error_is_set(errp)) {
285 b84da831 Michael Roth
            goto out;
286 b84da831 Michael Roth
        }
287 b84da831 Michael Roth
        retval = qmp_my_command(arg1, errp);
288 b84da831 Michael Roth
        qmp_marshal_output_my_command(retval, ret, errp);
289 b84da831 Michael Roth
290 b84da831 Michael Roth
    out:
291 b84da831 Michael Roth
        md = qapi_dealloc_visitor_new();
292 b84da831 Michael Roth
        v = qapi_dealloc_get_visitor(md);
293 b84da831 Michael Roth
        visit_type_UserDefOne(v, &arg1, "arg1", errp);
294 b84da831 Michael Roth
        qapi_dealloc_visitor_cleanup(md);
295 b84da831 Michael Roth
        return;
296 b84da831 Michael Roth
    }
297 b84da831 Michael Roth
298 b84da831 Michael Roth
    static void qmp_init_marshal(void)
299 b84da831 Michael Roth
    {
300 b84da831 Michael Roth
        qmp_register_command("my-command", qmp_marshal_input_my_command);
301 b84da831 Michael Roth
    }
302 b84da831 Michael Roth
303 b84da831 Michael Roth
    qapi_init(qmp_init_marshal);
304 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qmp-commands.h
305 b84da831 Michael Roth
    /* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
306 b84da831 Michael Roth
307 b84da831 Michael Roth
    #ifndef QAPI_GENERATED_EXAMPLE_QMP_COMMANDS
308 b84da831 Michael Roth
    #define QAPI_GENERATED_EXAMPLE_QMP_COMMANDS
309 b84da831 Michael Roth
310 b84da831 Michael Roth
    #include "example-qapi-types.h"
311 b84da831 Michael Roth
    #include "error.h"
312 b84da831 Michael Roth
313 b84da831 Michael Roth
    UserDefOne * qmp_my_command(UserDefOne * arg1, Error **errp);
314 b84da831 Michael Roth
315 b84da831 Michael Roth
    #endif
316 b84da831 Michael Roth
    mdroth@illuin:~/w/qemu2.git$