]>
Commit | Line | Data |
---|---|---|
4b389b5d LC |
1 | = How to write QMP commands using the QAPI framework = |
2 | ||
3 | This document is a step-by-step guide on how to write new QMP commands using | |
4 | the QAPI framework. It also shows how to implement new style HMP commands. | |
5 | ||
6 | This document doesn't discuss QMP protocol level details, nor does it dive | |
7 | into the QAPI framework implementation. | |
8 | ||
9 | For an in-depth introduction to the QAPI framework, please refer to | |
10 | docs/qapi-code-gen.txt. For documentation about the QMP protocol, please | |
11 | check the files in QMP/. | |
12 | ||
13 | == Overview == | |
14 | ||
15 | Generally speaking, the following steps should be taken in order to write a | |
16 | new QMP command. | |
17 | ||
18 | 1. Write the command's and type(s) specification in the QAPI schema file | |
19 | (qapi-schema.json in the root source directory) | |
20 | ||
21 | 2. Write the QMP command itself, which is a regular C function. Preferably, | |
22 | the command should be exported by some QEMU subsystem. But it can also be | |
23 | added to the qmp.c file | |
24 | ||
25 | 3. At this point the command can be tested under the QMP protocol | |
26 | ||
27 | 4. Write the HMP command equivalent. This is not required and should only be | |
28 | done if it does make sense to have the functionality in HMP. The HMP command | |
29 | is implemented in terms of the QMP command | |
30 | ||
31 | The following sections will demonstrate each of the steps above. We will start | |
32 | very simple and get more complex as we progress. | |
33 | ||
34 | === Testing === | |
35 | ||
36 | For all the examples in the next sections, the test setup is the same and is | |
37 | shown here. | |
38 | ||
39 | First, QEMU should be started as: | |
40 | ||
41 | # /path/to/your/source/qemu [...] \ | |
42 | -chardev socket,id=qmp,port=4444,host=localhost,server \ | |
43 | -mon chardev=qmp,mode=control,pretty=on | |
44 | ||
45 | Then, in a different terminal: | |
46 | ||
47 | $ telnet localhost 4444 | |
48 | Trying 127.0.0.1... | |
49 | Connected to localhost. | |
50 | Escape character is '^]'. | |
51 | { | |
52 | "QMP": { | |
53 | "version": { | |
54 | "qemu": { | |
55 | "micro": 50, | |
56 | "minor": 15, | |
57 | "major": 0 | |
58 | }, | |
59 | "package": "" | |
60 | }, | |
61 | "capabilities": [ | |
62 | ] | |
63 | } | |
64 | } | |
65 | ||
66 | The above output is the QMP server saying you're connected. The server is | |
67 | actually in capabilities negotiation mode. To enter in command mode type: | |
68 | ||
69 | { "execute": "qmp_capabilities" } | |
70 | ||
71 | Then the server should respond: | |
72 | ||
73 | { | |
74 | "return": { | |
75 | } | |
76 | } | |
77 | ||
78 | Which is QMP's way of saying "the latest command executed OK and didn't return | |
79 | any data". Now you're ready to enter the QMP example commands as explained in | |
80 | the following sections. | |
81 | ||
82 | == Writing a command that doesn't return data == | |
83 | ||
84 | That's the most simple QMP command that can be written. Usually, this kind of | |
85 | command carries some meaningful action in QEMU but here it will just print | |
86 | "Hello, world" to the standard output. | |
87 | ||
88 | Our command will be called "hello-world". It takes no arguments, nor does it | |
89 | return any data. | |
90 | ||
91 | The first step is to add the following line to the bottom of the | |
92 | qapi-schema.json file: | |
93 | ||
94 | { 'command': 'hello-world' } | |
95 | ||
96 | The "command" keyword defines a new QMP command. It's an JSON object. All | |
97 | schema entries are JSON objects. The line above will instruct the QAPI to | |
98 | generate any prototypes and the necessary code to marshal and unmarshal | |
99 | protocol data. | |
100 | ||
101 | The next step is to write the "hello-world" implementation. As explained | |
102 | earlier, it's preferable for commands to live in QEMU subsystems. But | |
103 | "hello-world" doesn't pertain to any, so we put its implementation in qmp.c: | |
104 | ||
105 | void qmp_hello_world(Error **errp) | |
106 | { | |
107 | printf("Hello, world!\n"); | |
108 | } | |
109 | ||
110 | There are a few things to be noticed: | |
111 | ||
112 | 1. QMP command implementation functions must be prefixed with "qmp_" | |
113 | 2. qmp_hello_world() returns void, this is in accordance with the fact that the | |
114 | command doesn't return any data | |
115 | 3. It takes an "Error **" argument. This is required. Later we will see how to | |
116 | return errors and take additional arguments. The Error argument should not | |
117 | be touched if the command doesn't return errors | |
118 | 4. We won't add the function's prototype. That's automatically done by the QAPI | |
119 | 5. Printing to the terminal is discouraged for QMP commands, we do it here | |
120 | because it's the easiest way to demonstrate a QMP command | |
121 | ||
122 | Now a little hack is needed. As we're still using the old QMP server we need | |
123 | to add the new command to its internal dispatch table. This step won't be | |
124 | required in the near future. Open the qmp-commands.hx file and add the | |
67cc32eb | 125 | following at the bottom: |
4b389b5d LC |
126 | |
127 | { | |
128 | .name = "hello-world", | |
129 | .args_type = "", | |
7fad30f0 | 130 | .mhandler.cmd_new = qmp_marshal_hello_world, |
4b389b5d LC |
131 | }, |
132 | ||
133 | You're done. Now build qemu, run it as suggested in the "Testing" section, | |
134 | and then type the following QMP command: | |
135 | ||
136 | { "execute": "hello-world" } | |
137 | ||
138 | Then check the terminal running qemu and look for the "Hello, world" string. If | |
139 | you don't see it then something went wrong. | |
140 | ||
141 | === Arguments === | |
142 | ||
143 | Let's add an argument called "message" to our "hello-world" command. The new | |
144 | argument will contain the string to be printed to stdout. It's an optional | |
145 | argument, if it's not present we print our default "Hello, World" string. | |
146 | ||
147 | The first change we have to do is to modify the command specification in the | |
148 | schema file to the following: | |
149 | ||
150 | { 'command': 'hello-world', 'data': { '*message': 'str' } } | |
151 | ||
152 | Notice the new 'data' member in the schema. It's an JSON object whose each | |
153 | element is an argument to the command in question. Also notice the asterisk, | |
154 | it's used to mark the argument optional (that means that you shouldn't use it | |
155 | for mandatory arguments). Finally, 'str' is the argument's type, which | |
156 | stands for "string". The QAPI also supports integers, booleans, enumerations | |
157 | and user defined types. | |
158 | ||
159 | Now, let's update our C implementation in qmp.c: | |
160 | ||
161 | void qmp_hello_world(bool has_message, const char *message, Error **errp) | |
162 | { | |
163 | if (has_message) { | |
164 | printf("%s\n", message); | |
165 | } else { | |
166 | printf("Hello, world\n"); | |
167 | } | |
168 | } | |
169 | ||
170 | There are two important details to be noticed: | |
171 | ||
172 | 1. All optional arguments are accompanied by a 'has_' boolean, which is set | |
173 | if the optional argument is present or false otherwise | |
174 | 2. The C implementation signature must follow the schema's argument ordering, | |
175 | which is defined by the "data" member | |
176 | ||
177 | The last step is to update the qmp-commands.hx file: | |
178 | ||
179 | { | |
180 | .name = "hello-world", | |
181 | .args_type = "message:s?", | |
7fad30f0 | 182 | .mhandler.cmd_new = qmp_marshal_hello_world, |
4b389b5d LC |
183 | }, |
184 | ||
185 | Notice that the "args_type" member got our "message" argument. The character | |
186 | "s" stands for "string" and "?" means it's optional. This too must be ordered | |
187 | according to the C implementation and schema file. You can look for more | |
188 | examples in the qmp-commands.hx file if you need to define more arguments. | |
189 | ||
190 | Again, this step won't be required in the future. | |
191 | ||
192 | Time to test our new version of the "hello-world" command. Build qemu, run it as | |
193 | described in the "Testing" section and then send two commands: | |
194 | ||
195 | { "execute": "hello-world" } | |
196 | { | |
197 | "return": { | |
198 | } | |
199 | } | |
200 | ||
201 | { "execute": "hello-world", "arguments": { "message": "We love qemu" } } | |
202 | { | |
203 | "return": { | |
204 | } | |
205 | } | |
206 | ||
207 | You should see "Hello, world" and "we love qemu" in the terminal running qemu, | |
208 | if you don't see these strings, then something went wrong. | |
209 | ||
210 | === Errors === | |
211 | ||
212 | QMP commands should use the error interface exported by the error.h header | |
455b0fde | 213 | file. Basically, most errors are set by calling the error_setg() function. |
4b389b5d LC |
214 | |
215 | Let's say we don't accept the string "message" to contain the word "love". If | |
adb2072e | 216 | it does contain it, we want the "hello-world" command to return an error: |
4b389b5d LC |
217 | |
218 | void qmp_hello_world(bool has_message, const char *message, Error **errp) | |
219 | { | |
220 | if (has_message) { | |
221 | if (strstr(message, "love")) { | |
455b0fde | 222 | error_setg(errp, "the word 'love' is not allowed"); |
4b389b5d LC |
223 | return; |
224 | } | |
225 | printf("%s\n", message); | |
226 | } else { | |
227 | printf("Hello, world\n"); | |
228 | } | |
229 | } | |
230 | ||
455b0fde EB |
231 | The first argument to the error_setg() function is the Error pointer |
232 | to pointer, which is passed to all QMP functions. The next argument is a human | |
adb2072e LC |
233 | description of the error, this is a free-form printf-like string. |
234 | ||
235 | Let's test the example above. Build qemu, run it as defined in the "Testing" | |
236 | section, and then issue the following command: | |
4b389b5d | 237 | |
adb2072e | 238 | { "execute": "hello-world", "arguments": { "message": "all you need is love" } } |
4b389b5d LC |
239 | |
240 | The QMP server's response should be: | |
241 | ||
242 | { | |
243 | "error": { | |
adb2072e LC |
244 | "class": "GenericError", |
245 | "desc": "the word 'love' is not allowed" | |
4b389b5d LC |
246 | } |
247 | } | |
248 | ||
455b0fde EB |
249 | As a general rule, all QMP errors should use ERROR_CLASS_GENERIC_ERROR |
250 | (done by default when using error_setg()). There are two exceptions to | |
251 | this rule: | |
adb2072e LC |
252 | |
253 | 1. A non-generic ErrorClass value exists* for the failure you want to report | |
254 | (eg. DeviceNotFound) | |
255 | ||
256 | 2. Management applications have to take special action on the failure you | |
257 | want to report, hence you have to add a new ErrorClass value so that they | |
258 | can check for it | |
4b389b5d | 259 | |
455b0fde EB |
260 | If the failure you want to report falls into one of the two cases above, |
261 | use error_set() with a second argument of an ErrorClass value. | |
4b389b5d | 262 | |
adb2072e | 263 | * All existing ErrorClass values are defined in the qapi-schema.json file |
4b389b5d LC |
264 | |
265 | === Command Documentation === | |
266 | ||
267 | There's only one step missing to make "hello-world"'s implementation complete, | |
268 | and that's its documentation in the schema file. | |
269 | ||
270 | This is very important. No QMP command will be accepted in QEMU without proper | |
271 | documentation. | |
272 | ||
273 | There are many examples of such documentation in the schema file already, but | |
274 | here goes "hello-world"'s new entry for the qapi-schema.json file: | |
275 | ||
276 | ## | |
277 | # @hello-world | |
278 | # | |
279 | # Print a client provided string to the standard output stream. | |
280 | # | |
281 | # @message: #optional string to be printed | |
282 | # | |
283 | # Returns: Nothing on success. | |
4b389b5d LC |
284 | # |
285 | # Notes: if @message is not provided, the "Hello, world" string will | |
286 | # be printed instead | |
287 | # | |
288 | # Since: <next qemu stable release, eg. 1.0> | |
289 | ## | |
290 | { 'command': 'hello-world', 'data': { '*message': 'str' } } | |
291 | ||
292 | Please, note that the "Returns" clause is optional if a command doesn't return | |
293 | any data nor any errors. | |
294 | ||
295 | === Implementing the HMP command === | |
296 | ||
297 | Now that the QMP command is in place, we can also make it available in the human | |
298 | monitor (HMP). | |
299 | ||
300 | With the introduction of the QAPI, HMP commands make QMP calls. Most of the | |
301 | time HMP commands are simple wrappers. All HMP commands implementation exist in | |
302 | the hmp.c file. | |
303 | ||
304 | Here's the implementation of the "hello-world" HMP command: | |
305 | ||
306 | void hmp_hello_world(Monitor *mon, const QDict *qdict) | |
307 | { | |
308 | const char *message = qdict_get_try_str(qdict, "message"); | |
e940f543 | 309 | Error *err = NULL; |
4b389b5d | 310 | |
e940f543 MA |
311 | qmp_hello_world(!!message, message, &err); |
312 | if (err) { | |
313 | monitor_printf(mon, "%s\n", error_get_pretty(err)); | |
314 | error_free(err); | |
4b389b5d LC |
315 | return; |
316 | } | |
317 | } | |
318 | ||
319 | Also, you have to add the function's prototype to the hmp.h file. | |
320 | ||
321 | There are three important points to be noticed: | |
322 | ||
323 | 1. The "mon" and "qdict" arguments are mandatory for all HMP functions. The | |
324 | former is the monitor object. The latter is how the monitor passes | |
325 | arguments entered by the user to the command implementation | |
326 | 2. hmp_hello_world() performs error checking. In this example we just print | |
327 | the error description to the user, but we could do more, like taking | |
328 | different actions depending on the error qmp_hello_world() returns | |
e940f543 | 329 | 3. The "err" variable must be initialized to NULL before performing the |
4b389b5d LC |
330 | QMP call |
331 | ||
332 | There's one last step to actually make the command available to monitor users, | |
333 | we should add it to the hmp-commands.hx file: | |
334 | ||
335 | { | |
336 | .name = "hello-world", | |
337 | .args_type = "message:s?", | |
338 | .params = "hello-world [message]", | |
339 | .help = "Print message to the standard output", | |
340 | .mhandler.cmd = hmp_hello_world, | |
341 | }, | |
342 | ||
343 | STEXI | |
344 | @item hello_world @var{message} | |
345 | @findex hello_world | |
346 | Print message to the standard output | |
347 | ETEXI | |
348 | ||
349 | To test this you have to open a user monitor and issue the "hello-world" | |
350 | command. It might be instructive to check the command's documentation with | |
351 | HMP's "help" command. | |
352 | ||
353 | Please, check the "-monitor" command-line option to know how to open a user | |
354 | monitor. | |
355 | ||
356 | == Writing a command that returns data == | |
357 | ||
358 | A QMP command is capable of returning any data the QAPI supports like integers, | |
359 | strings, booleans, enumerations and user defined types. | |
360 | ||
361 | In this section we will focus on user defined types. Please, check the QAPI | |
362 | documentation for information about the other types. | |
363 | ||
364 | === User Defined Types === | |
365 | ||
e218052f MA |
366 | FIXME This example needs to be redone after commit 6d32717 |
367 | ||
4b389b5d LC |
368 | For this example we will write the query-alarm-clock command, which returns |
369 | information about QEMU's timer alarm. For more information about it, please | |
370 | check the "-clock" command-line option. | |
371 | ||
372 | We want to return two pieces of information. The first one is the alarm clock's | |
373 | name. The second one is when the next alarm will fire. The former information is | |
374 | returned as a string, the latter is an integer in nanoseconds (which is not | |
375 | very useful in practice, as the timer has probably already fired when the | |
376 | information reaches the client). | |
377 | ||
378 | The best way to return that data is to create a new QAPI type, as shown below: | |
379 | ||
380 | ## | |
381 | # @QemuAlarmClock | |
382 | # | |
383 | # QEMU alarm clock information. | |
384 | # | |
385 | # @clock-name: The alarm clock method's name. | |
386 | # | |
387 | # @next-deadline: #optional The time (in nanoseconds) the next alarm will fire. | |
388 | # | |
389 | # Since: 1.0 | |
390 | ## | |
391 | { 'type': 'QemuAlarmClock', | |
392 | 'data': { 'clock-name': 'str', '*next-deadline': 'int' } } | |
393 | ||
394 | The "type" keyword defines a new QAPI type. Its "data" member contains the | |
395 | type's members. In this example our members are the "clock-name" and the | |
396 | "next-deadline" one, which is optional. | |
397 | ||
398 | Now let's define the query-alarm-clock command: | |
399 | ||
400 | ## | |
401 | # @query-alarm-clock | |
402 | # | |
403 | # Return information about QEMU's alarm clock. | |
404 | # | |
405 | # Returns a @QemuAlarmClock instance describing the alarm clock method | |
406 | # being currently used by QEMU (this is usually set by the '-clock' | |
407 | # command-line option). | |
408 | # | |
409 | # Since: 1.0 | |
410 | ## | |
411 | { 'command': 'query-alarm-clock', 'returns': 'QemuAlarmClock' } | |
412 | ||
413 | Notice the "returns" keyword. As its name suggests, it's used to define the | |
414 | data returned by a command. | |
415 | ||
416 | It's time to implement the qmp_query_alarm_clock() function, you can put it | |
417 | in the qemu-timer.c file: | |
418 | ||
419 | QemuAlarmClock *qmp_query_alarm_clock(Error **errp) | |
420 | { | |
421 | QemuAlarmClock *clock; | |
422 | int64_t deadline; | |
423 | ||
424 | clock = g_malloc0(sizeof(*clock)); | |
425 | ||
426 | deadline = qemu_next_alarm_deadline(); | |
427 | if (deadline > 0) { | |
428 | clock->has_next_deadline = true; | |
429 | clock->next_deadline = deadline; | |
430 | } | |
431 | clock->clock_name = g_strdup(alarm_timer->name); | |
432 | ||
433 | return clock; | |
434 | } | |
435 | ||
436 | There are a number of things to be noticed: | |
437 | ||
438 | 1. The QemuAlarmClock type is automatically generated by the QAPI framework, | |
439 | its members correspond to the type's specification in the schema file | |
440 | 2. As specified in the schema file, the function returns a QemuAlarmClock | |
441 | instance and takes no arguments (besides the "errp" one, which is mandatory | |
442 | for all QMP functions) | |
443 | 3. The "clock" variable (which will point to our QAPI type instance) is | |
444 | allocated by the regular g_malloc0() function. Note that we chose to | |
dabdf394 | 445 | initialize the memory to zero. This is recommended for all QAPI types, as |
4b389b5d LC |
446 | it helps avoiding bad surprises (specially with booleans) |
447 | 4. Remember that "next_deadline" is optional? All optional members have a | |
448 | 'has_TYPE_NAME' member that should be properly set by the implementation, | |
449 | as shown above | |
450 | 5. Even static strings, such as "alarm_timer->name", should be dynamically | |
451 | allocated by the implementation. This is so because the QAPI also generates | |
452 | a function to free its types and it cannot distinguish between dynamically | |
453 | or statically allocated strings | |
454 | 6. You have to include the "qmp-commands.h" header file in qemu-timer.c, | |
455 | otherwise qemu won't build | |
456 | ||
457 | The last step is to add the correspoding entry in the qmp-commands.hx file: | |
458 | ||
459 | { | |
460 | .name = "query-alarm-clock", | |
461 | .args_type = "", | |
7fad30f0 | 462 | .mhandler.cmd_new = qmp_marshal_query_alarm_clock, |
4b389b5d LC |
463 | }, |
464 | ||
465 | Time to test the new command. Build qemu, run it as described in the "Testing" | |
466 | section and try this: | |
467 | ||
468 | { "execute": "query-alarm-clock" } | |
469 | { | |
470 | "return": { | |
471 | "next-deadline": 2368219, | |
472 | "clock-name": "dynticks" | |
473 | } | |
474 | } | |
475 | ||
476 | ==== The HMP command ==== | |
477 | ||
478 | Here's the HMP counterpart of the query-alarm-clock command: | |
479 | ||
480 | void hmp_info_alarm_clock(Monitor *mon) | |
481 | { | |
482 | QemuAlarmClock *clock; | |
e940f543 | 483 | Error *err = NULL; |
4b389b5d | 484 | |
e940f543 MA |
485 | clock = qmp_query_alarm_clock(&err); |
486 | if (err) { | |
4b389b5d | 487 | monitor_printf(mon, "Could not query alarm clock information\n"); |
e940f543 | 488 | error_free(err); |
4b389b5d LC |
489 | return; |
490 | } | |
491 | ||
492 | monitor_printf(mon, "Alarm clock method in use: '%s'\n", clock->clock_name); | |
493 | if (clock->has_next_deadline) { | |
494 | monitor_printf(mon, "Next alarm will fire in %" PRId64 " nanoseconds\n", | |
495 | clock->next_deadline); | |
496 | } | |
497 | ||
498 | qapi_free_QemuAlarmClock(clock); | |
499 | } | |
500 | ||
501 | It's important to notice that hmp_info_alarm_clock() calls | |
502 | qapi_free_QemuAlarmClock() to free the data returned by qmp_query_alarm_clock(). | |
503 | For user defined types, the QAPI will generate a qapi_free_QAPI_TYPE_NAME() | |
504 | function and that's what you have to use to free the types you define and | |
505 | qapi_free_QAPI_TYPE_NAMEList() for list types (explained in the next section). | |
506 | If the QMP call returns a string, then you should g_free() to free it. | |
507 | ||
508 | Also note that hmp_info_alarm_clock() performs error handling. That's not | |
509 | strictly required if you're sure the QMP function doesn't return errors, but | |
510 | it's good practice to always check for errors. | |
511 | ||
512 | Another important detail is that HMP's "info" commands don't go into the | |
513 | hmp-commands.hx. Instead, they go into the info_cmds[] table, which is defined | |
514 | in the monitor.c file. The entry for the "info alarmclock" follows: | |
515 | ||
516 | { | |
517 | .name = "alarmclock", | |
518 | .args_type = "", | |
519 | .params = "", | |
520 | .help = "show information about the alarm clock", | |
521 | .mhandler.info = hmp_info_alarm_clock, | |
522 | }, | |
523 | ||
524 | To test this, run qemu and type "info alarmclock" in the user monitor. | |
525 | ||
526 | === Returning Lists === | |
527 | ||
528 | For this example, we're going to return all available methods for the timer | |
529 | alarm, which is pretty much what the command-line option "-clock ?" does, | |
530 | except that we're also going to inform which method is in use. | |
531 | ||
532 | This first step is to define a new type: | |
533 | ||
534 | ## | |
535 | # @TimerAlarmMethod | |
536 | # | |
537 | # Timer alarm method information. | |
538 | # | |
539 | # @method-name: The method's name. | |
540 | # | |
541 | # @current: true if this alarm method is currently in use, false otherwise | |
542 | # | |
543 | # Since: 1.0 | |
544 | ## | |
545 | { 'type': 'TimerAlarmMethod', | |
546 | 'data': { 'method-name': 'str', 'current': 'bool' } } | |
547 | ||
548 | The command will be called "query-alarm-methods", here is its schema | |
549 | specification: | |
550 | ||
551 | ## | |
552 | # @query-alarm-methods | |
553 | # | |
554 | # Returns information about available alarm methods. | |
555 | # | |
556 | # Returns: a list of @TimerAlarmMethod for each method | |
557 | # | |
558 | # Since: 1.0 | |
559 | ## | |
560 | { 'command': 'query-alarm-methods', 'returns': ['TimerAlarmMethod'] } | |
561 | ||
562 | Notice the syntax for returning lists "'returns': ['TimerAlarmMethod']", this | |
563 | should be read as "returns a list of TimerAlarmMethod instances". | |
564 | ||
565 | The C implementation follows: | |
566 | ||
567 | TimerAlarmMethodList *qmp_query_alarm_methods(Error **errp) | |
568 | { | |
569 | TimerAlarmMethodList *method_list = NULL; | |
570 | const struct qemu_alarm_timer *p; | |
571 | bool current = true; | |
572 | ||
573 | for (p = alarm_timers; p->name; p++) { | |
574 | TimerAlarmMethodList *info = g_malloc0(sizeof(*info)); | |
575 | info->value = g_malloc0(sizeof(*info->value)); | |
576 | info->value->method_name = g_strdup(p->name); | |
577 | info->value->current = current; | |
578 | ||
579 | current = false; | |
580 | ||
581 | info->next = method_list; | |
582 | method_list = info; | |
583 | } | |
584 | ||
585 | return method_list; | |
586 | } | |
587 | ||
588 | The most important difference from the previous examples is the | |
589 | TimerAlarmMethodList type, which is automatically generated by the QAPI from | |
590 | the TimerAlarmMethod type. | |
591 | ||
592 | Each list node is represented by a TimerAlarmMethodList instance. We have to | |
593 | allocate it, and that's done inside the for loop: the "info" pointer points to | |
594 | an allocated node. We also have to allocate the node's contents, which is | |
595 | stored in its "value" member. In our example, the "value" member is a pointer | |
596 | to an TimerAlarmMethod instance. | |
597 | ||
598 | Notice that the "current" variable is used as "true" only in the first | |
5708b2b7 | 599 | iteration of the loop. That's because the alarm timer method in use is the |
4b389b5d LC |
600 | first element of the alarm_timers array. Also notice that QAPI lists are handled |
601 | by hand and we return the head of the list. | |
602 | ||
603 | To test this you have to add the corresponding qmp-commands.hx entry: | |
604 | ||
605 | { | |
606 | .name = "query-alarm-methods", | |
607 | .args_type = "", | |
7fad30f0 | 608 | .mhandler.cmd_new = qmp_marshal_query_alarm_methods, |
4b389b5d LC |
609 | }, |
610 | ||
611 | Now Build qemu, run it as explained in the "Testing" section and try our new | |
612 | command: | |
613 | ||
614 | { "execute": "query-alarm-methods" } | |
615 | { | |
616 | "return": [ | |
617 | { | |
618 | "current": false, | |
619 | "method-name": "unix" | |
620 | }, | |
621 | { | |
622 | "current": true, | |
623 | "method-name": "dynticks" | |
624 | } | |
625 | ] | |
626 | } | |
627 | ||
628 | The HMP counterpart is a bit more complex than previous examples because it | |
629 | has to traverse the list, it's shown below for reference: | |
630 | ||
631 | void hmp_info_alarm_methods(Monitor *mon) | |
632 | { | |
633 | TimerAlarmMethodList *method_list, *method; | |
e940f543 | 634 | Error *err = NULL; |
4b389b5d | 635 | |
e940f543 MA |
636 | method_list = qmp_query_alarm_methods(&err); |
637 | if (err) { | |
4b389b5d | 638 | monitor_printf(mon, "Could not query alarm methods\n"); |
e940f543 | 639 | error_free(err); |
4b389b5d LC |
640 | return; |
641 | } | |
642 | ||
643 | for (method = method_list; method; method = method->next) { | |
644 | monitor_printf(mon, "%c %s\n", method->value->current ? '*' : ' ', | |
645 | method->value->method_name); | |
646 | } | |
647 | ||
648 | qapi_free_TimerAlarmMethodList(method_list); | |
649 | } |