root / docs / writing-qmp-commands.txt @ c08ba66f
History | View | Annotate | Download (21 kB)
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 |
125 |
following in the botton: |
126 |
|
127 |
{ |
128 |
.name = "hello-world", |
129 |
.args_type = "", |
130 |
.mhandler.cmd_new = qmp_marshal_input_hello_world, |
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?", |
182 |
.mhandler.cmd_new = qmp_marshal_input_hello_world, |
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 |
213 |
file. Basically, errors are set by calling the error_set() function. |
214 |
|
215 |
Let's say we don't accept the string "message" to contain the word "love". If |
216 |
it does contain it, we want the "hello-world" command to return an error: |
217 |
|
218 |
void qmp_hello_world(bool has_message, const char *message, Error **errp) |
219 |
{ |
220 |
if (has_message) { |
221 |
if (strstr(message, "love")) { |
222 |
error_set(errp, ERROR_CLASS_GENERIC_ERROR, |
223 |
"the word 'love' is not allowed"); |
224 |
return; |
225 |
} |
226 |
printf("%s\n", message); |
227 |
} else { |
228 |
printf("Hello, world\n"); |
229 |
} |
230 |
} |
231 |
|
232 |
The first argument to the error_set() function is the Error pointer to pointer, |
233 |
which is passed to all QMP functions. The second argument is a ErrorClass |
234 |
value, which should be ERROR_CLASS_GENERIC_ERROR most of the time (more |
235 |
details about error classes are given below). The third argument is a human |
236 |
description of the error, this is a free-form printf-like string. |
237 |
|
238 |
Let's test the example above. Build qemu, run it as defined in the "Testing" |
239 |
section, and then issue the following command: |
240 |
|
241 |
{ "execute": "hello-world", "arguments": { "message": "all you need is love" } } |
242 |
|
243 |
The QMP server's response should be: |
244 |
|
245 |
{ |
246 |
"error": { |
247 |
"class": "GenericError", |
248 |
"desc": "the word 'love' is not allowed" |
249 |
} |
250 |
} |
251 |
|
252 |
As a general rule, all QMP errors should use ERROR_CLASS_GENERIC_ERROR. There |
253 |
are two exceptions to this rule: |
254 |
|
255 |
1. A non-generic ErrorClass value exists* for the failure you want to report |
256 |
(eg. DeviceNotFound) |
257 |
|
258 |
2. Management applications have to take special action on the failure you |
259 |
want to report, hence you have to add a new ErrorClass value so that they |
260 |
can check for it |
261 |
|
262 |
If the failure you want to report doesn't fall in one of the two cases above, |
263 |
just report ERROR_CLASS_GENERIC_ERROR. |
264 |
|
265 |
* All existing ErrorClass values are defined in the qapi-schema.json file |
266 |
|
267 |
=== Command Documentation === |
268 |
|
269 |
There's only one step missing to make "hello-world"'s implementation complete, |
270 |
and that's its documentation in the schema file. |
271 |
|
272 |
This is very important. No QMP command will be accepted in QEMU without proper |
273 |
documentation. |
274 |
|
275 |
There are many examples of such documentation in the schema file already, but |
276 |
here goes "hello-world"'s new entry for the qapi-schema.json file: |
277 |
|
278 |
## |
279 |
# @hello-world |
280 |
# |
281 |
# Print a client provided string to the standard output stream. |
282 |
# |
283 |
# @message: #optional string to be printed |
284 |
# |
285 |
# Returns: Nothing on success. |
286 |
# |
287 |
# Notes: if @message is not provided, the "Hello, world" string will |
288 |
# be printed instead |
289 |
# |
290 |
# Since: <next qemu stable release, eg. 1.0> |
291 |
## |
292 |
{ 'command': 'hello-world', 'data': { '*message': 'str' } } |
293 |
|
294 |
Please, note that the "Returns" clause is optional if a command doesn't return |
295 |
any data nor any errors. |
296 |
|
297 |
=== Implementing the HMP command === |
298 |
|
299 |
Now that the QMP command is in place, we can also make it available in the human |
300 |
monitor (HMP). |
301 |
|
302 |
With the introduction of the QAPI, HMP commands make QMP calls. Most of the |
303 |
time HMP commands are simple wrappers. All HMP commands implementation exist in |
304 |
the hmp.c file. |
305 |
|
306 |
Here's the implementation of the "hello-world" HMP command: |
307 |
|
308 |
void hmp_hello_world(Monitor *mon, const QDict *qdict) |
309 |
{ |
310 |
const char *message = qdict_get_try_str(qdict, "message"); |
311 |
Error *errp = NULL; |
312 |
|
313 |
qmp_hello_world(!!message, message, &errp); |
314 |
if (error_is_set(&errp)) { |
315 |
monitor_printf(mon, "%s\n", error_get_pretty(errp)); |
316 |
error_free(errp); |
317 |
return; |
318 |
} |
319 |
} |
320 |
|
321 |
Also, you have to add the function's prototype to the hmp.h file. |
322 |
|
323 |
There are three important points to be noticed: |
324 |
|
325 |
1. The "mon" and "qdict" arguments are mandatory for all HMP functions. The |
326 |
former is the monitor object. The latter is how the monitor passes |
327 |
arguments entered by the user to the command implementation |
328 |
2. hmp_hello_world() performs error checking. In this example we just print |
329 |
the error description to the user, but we could do more, like taking |
330 |
different actions depending on the error qmp_hello_world() returns |
331 |
3. The "errp" variable must be initialized to NULL before performing the |
332 |
QMP call |
333 |
|
334 |
There's one last step to actually make the command available to monitor users, |
335 |
we should add it to the hmp-commands.hx file: |
336 |
|
337 |
{ |
338 |
.name = "hello-world", |
339 |
.args_type = "message:s?", |
340 |
.params = "hello-world [message]", |
341 |
.help = "Print message to the standard output", |
342 |
.mhandler.cmd = hmp_hello_world, |
343 |
}, |
344 |
|
345 |
STEXI |
346 |
@item hello_world @var{message} |
347 |
@findex hello_world |
348 |
Print message to the standard output |
349 |
ETEXI |
350 |
|
351 |
To test this you have to open a user monitor and issue the "hello-world" |
352 |
command. It might be instructive to check the command's documentation with |
353 |
HMP's "help" command. |
354 |
|
355 |
Please, check the "-monitor" command-line option to know how to open a user |
356 |
monitor. |
357 |
|
358 |
== Writing a command that returns data == |
359 |
|
360 |
A QMP command is capable of returning any data the QAPI supports like integers, |
361 |
strings, booleans, enumerations and user defined types. |
362 |
|
363 |
In this section we will focus on user defined types. Please, check the QAPI |
364 |
documentation for information about the other types. |
365 |
|
366 |
=== User Defined Types === |
367 |
|
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 |
445 |
initialize the memory to zero. This is recommended for all QAPI types, as |
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 = "", |
462 |
.mhandler.cmd_new = qmp_marshal_input_query_alarm_clock, |
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; |
483 |
Error *errp = NULL; |
484 |
|
485 |
clock = qmp_query_alarm_clock(&errp); |
486 |
if (error_is_set(&errp)) { |
487 |
monitor_printf(mon, "Could not query alarm clock information\n"); |
488 |
error_free(errp); |
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 |
599 |
interation of the loop. That's because the alarm timer method in use is the |
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 = "", |
608 |
.mhandler.cmd_new = qmp_marshal_input_query_alarm_methods, |
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; |
634 |
Error *errp = NULL; |
635 |
|
636 |
method_list = qmp_query_alarm_methods(&errp); |
637 |
if (error_is_set(&errp)) { |
638 |
monitor_printf(mon, "Could not query alarm methods\n"); |
639 |
error_free(errp); |
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 |
} |