| 1 | How to write monitor commands |
| 2 | ============================= |
| 3 | |
| 4 | This document is a step-by-step guide on how to write new QMP commands using |
| 5 | the QAPI framework and HMP commands. |
| 6 | |
| 7 | This document doesn't discuss QMP protocol level details, nor does it dive |
| 8 | into the QAPI framework implementation. |
| 9 | |
| 10 | For an in-depth introduction to the QAPI framework, please refer to |
| 11 | :doc:`qapi-code-gen`. For the QMP protocol, see the |
| 12 | :doc:`/interop/qmp-spec`. |
| 13 | |
| 14 | New commands may be implemented in QMP only. New HMP commands should be |
| 15 | implemented on top of QMP. The typical HMP command wraps around an |
| 16 | equivalent QMP command, but HMP convenience commands built from QMP |
| 17 | building blocks are also fine. The long term goal is to make all |
| 18 | existing HMP commands conform to this, to fully isolate HMP from the |
| 19 | internals of QEMU. Refer to the `Writing a debugging aid returning |
| 20 | unstructured text`_ section for further guidance on commands that |
| 21 | would have traditionally been HMP only. |
| 22 | |
| 23 | Overview |
| 24 | -------- |
| 25 | |
| 26 | Generally speaking, the following steps should be taken in order to write a |
| 27 | new QMP command. |
| 28 | |
| 29 | 1. Define the command and any types it needs in the appropriate QAPI |
| 30 | schema module. |
| 31 | |
| 32 | 2. Write the QMP command itself, which is a regular C function. Preferably, |
| 33 | the command should be exported by some QEMU subsystem. But it can also be |
| 34 | added to the monitor/qmp-cmds.c file |
| 35 | |
| 36 | 3. At this point the command can be tested under the QMP protocol |
| 37 | |
| 38 | 4. Write the HMP command equivalent. This is not required and should only be |
| 39 | done if it does make sense to have the functionality in HMP. The HMP command |
| 40 | is implemented in terms of the QMP command |
| 41 | |
| 42 | The following sections will demonstrate each of the steps above. We will start |
| 43 | very simple and get more complex as we progress. |
| 44 | |
| 45 | |
| 46 | Testing |
| 47 | ------- |
| 48 | |
| 49 | For all the examples in the next sections, the test setup is the same and is |
| 50 | shown here. |
| 51 | |
| 52 | First, QEMU should be started like this:: |
| 53 | |
| 54 | # qemu-system-TARGET [...] \ |
| 55 | -chardev socket,id=chrqmp0,port=4444,host=localhost,server=on \ |
| 56 | -object monitor-qmp,chardev=chrqmp0,pretty=on,id=qmp0 |
| 57 | |
| 58 | Then, in a different terminal:: |
| 59 | |
| 60 | $ telnet localhost 4444 |
| 61 | Trying 127.0.0.1... |
| 62 | Connected to localhost. |
| 63 | Escape character is '^]'. |
| 64 | { |
| 65 | "QMP": { |
| 66 | "version": { |
| 67 | "qemu": { |
| 68 | "micro": 50, |
| 69 | "minor": 2, |
| 70 | "major": 8 |
| 71 | }, |
| 72 | "package": ... |
| 73 | }, |
| 74 | "capabilities": [ |
| 75 | "oob" |
| 76 | ] |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | The above output is the QMP server saying you're connected. The server is |
| 81 | actually in capabilities negotiation mode. To enter in command mode type:: |
| 82 | |
| 83 | { "execute": "qmp_capabilities" } |
| 84 | |
| 85 | Then the server should respond:: |
| 86 | |
| 87 | { |
| 88 | "return": { |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | Which is QMP's way of saying "the latest command executed OK and didn't return |
| 93 | any data". Now you're ready to enter the QMP example commands as explained in |
| 94 | the following sections. |
| 95 | |
| 96 | |
| 97 | Writing a simple command: hello-world |
| 98 | ------------------------------------- |
| 99 | |
| 100 | That's the most simple QMP command that can be written. Usually, this kind of |
| 101 | command carries some meaningful action in QEMU but here it will just print |
| 102 | "Hello, world" to the standard output. |
| 103 | |
| 104 | Our command will be called "hello-world". It takes no arguments, nor does it |
| 105 | return any data. |
| 106 | |
| 107 | The first step is defining the command in the appropriate QAPI schema |
| 108 | module. We pick module qapi/misc.json, and add the following line at |
| 109 | the bottom:: |
| 110 | |
| 111 | ## |
| 112 | # @hello-world: |
| 113 | # |
| 114 | # Since: 9.0 |
| 115 | ## |
| 116 | { 'command': 'hello-world' } |
| 117 | |
| 118 | The "command" keyword defines a new QMP command. It instructs QAPI to |
| 119 | generate any prototypes and the necessary code to marshal and unmarshal |
| 120 | protocol data. |
| 121 | |
| 122 | The next step is to write the "hello-world" implementation. As explained |
| 123 | earlier, it's preferable for commands to live in QEMU subsystems. But |
| 124 | "hello-world" doesn't pertain to any, so we put its implementation in |
| 125 | monitor/qmp-cmds.c:: |
| 126 | |
| 127 | void qmp_hello_world(Error **errp) |
| 128 | { |
| 129 | printf("Hello, world!\n"); |
| 130 | } |
| 131 | |
| 132 | There are a few things to be noticed: |
| 133 | |
| 134 | 1. QMP command implementation functions must be prefixed with "qmp\_" |
| 135 | 2. qmp_hello_world() returns void, this is in accordance with the fact that the |
| 136 | command doesn't return any data |
| 137 | 3. It takes an "Error \*\*" argument. This is required. Later we will see how to |
| 138 | return errors and take additional arguments. The Error argument should not |
| 139 | be touched if the command doesn't return errors |
| 140 | 4. We won't add the function's prototype. That's automatically done by QAPI |
| 141 | 5. Printing to the terminal is discouraged for QMP commands, we do it here |
| 142 | because it's the easiest way to demonstrate a QMP command |
| 143 | |
| 144 | You're done. Now build QEMU, run it as suggested in the "Testing" section, |
| 145 | and then type the following QMP command:: |
| 146 | |
| 147 | { "execute": "hello-world" } |
| 148 | |
| 149 | Then check the terminal running QEMU and look for the "Hello, world" string. If |
| 150 | you don't see it then something went wrong. |
| 151 | |
| 152 | |
| 153 | Arguments |
| 154 | ~~~~~~~~~ |
| 155 | |
| 156 | Let's add arguments to our "hello-world" command. |
| 157 | |
| 158 | The first change we have to do is to modify the command specification in the |
| 159 | schema file to the following:: |
| 160 | |
| 161 | ## |
| 162 | # @hello-world: |
| 163 | # |
| 164 | # @message: message to be printed (default: "Hello, world!") |
| 165 | # |
| 166 | # @times: how many times to print the message (default: 1) |
| 167 | # |
| 168 | # Since: 9.0 |
| 169 | ## |
| 170 | { 'command': 'hello-world', |
| 171 | 'data': { '*message': 'str', '*times': 'int' } } |
| 172 | |
| 173 | Notice the new 'data' member in the schema. It specifies an argument |
| 174 | 'message' of QAPI type 'str', and an argument 'times' of QAPI type |
| 175 | 'int'. Also notice the asterisk, it's used to mark the argument |
| 176 | optional. |
| 177 | |
| 178 | Now, let's update our C implementation in monitor/qmp-cmds.c:: |
| 179 | |
| 180 | void qmp_hello_world(const char *message, bool has_times, int64_t times, |
| 181 | Error **errp) |
| 182 | { |
| 183 | if (!message) { |
| 184 | message = "Hello, world"; |
| 185 | } |
| 186 | if (!has_times) { |
| 187 | times = 1; |
| 188 | } |
| 189 | |
| 190 | for (int i = 0; i < times; i++) { |
| 191 | printf("%s\n", message); |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | There are two important details to be noticed: |
| 196 | |
| 197 | 1. Optional arguments other than pointers are accompanied by a 'has\_' |
| 198 | boolean, which is set if the optional argument is present or false |
| 199 | otherwise |
| 200 | 2. The C implementation signature must follow the schema's argument ordering, |
| 201 | which is defined by the "data" member |
| 202 | |
| 203 | Time to test our new version of the "hello-world" command. Build QEMU, run it as |
| 204 | described in the "Testing" section and then send two commands:: |
| 205 | |
| 206 | { "execute": "hello-world" } |
| 207 | { |
| 208 | "return": { |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | { "execute": "hello-world", "arguments": { "message": "We love QEMU" } } |
| 213 | { |
| 214 | "return": { |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | You should see "Hello, world" and "We love QEMU" in the terminal running QEMU, |
| 219 | if you don't see these strings, then something went wrong. |
| 220 | |
| 221 | |
| 222 | Errors |
| 223 | ~~~~~~ |
| 224 | |
| 225 | QMP commands should use the error interface exported by the error.h header |
| 226 | file. Basically, most errors are set by calling the error_setg() function. |
| 227 | |
| 228 | Let's say we don't accept the string "message" to contain the word "love". If |
| 229 | it does contain it, we want the "hello-world" command to return an error:: |
| 230 | |
| 231 | void qmp_hello_world(const char *message, Error **errp) |
| 232 | { |
| 233 | if (message) { |
| 234 | if (strstr(message, "love")) { |
| 235 | error_setg(errp, "the word 'love' is not allowed"); |
| 236 | return; |
| 237 | } |
| 238 | printf("%s\n", message); |
| 239 | } else { |
| 240 | printf("Hello, world\n"); |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | The first argument to the error_setg() function is the Error pointer |
| 245 | to pointer, which is passed to all QMP functions. The next argument is a human |
| 246 | description of the error, this is a free-form printf-like string. |
| 247 | |
| 248 | Let's test the example above. Build QEMU, run it as defined in the "Testing" |
| 249 | section, and then issue the following command:: |
| 250 | |
| 251 | { "execute": "hello-world", "arguments": { "message": "all you need is love" } } |
| 252 | |
| 253 | The QMP server's response should be:: |
| 254 | |
| 255 | { |
| 256 | "error": { |
| 257 | "class": "GenericError", |
| 258 | "desc": "the word 'love' is not allowed" |
| 259 | } |
| 260 | } |
| 261 | |
| 262 | Note that error_setg() produces a "GenericError" class. In general, |
| 263 | all QMP errors should have that error class. There are two exceptions |
| 264 | to this rule: |
| 265 | |
| 266 | 1. To support a management application's need to recognize a specific |
| 267 | error for special handling |
| 268 | |
| 269 | 2. Backward compatibility |
| 270 | |
| 271 | If the failure you want to report falls into one of the two cases above, |
| 272 | use error_set() with a second argument of an ErrorClass value. |
| 273 | |
| 274 | |
| 275 | Implementing the HMP command |
| 276 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 277 | |
| 278 | Now that the QMP command is in place, we can also make it available in the human |
| 279 | monitor (HMP). |
| 280 | |
| 281 | With the introduction of QAPI, HMP commands make QMP calls. Most of the |
| 282 | time HMP commands are simple wrappers. |
| 283 | |
| 284 | Here's the implementation of the "hello-world" HMP command:: |
| 285 | |
| 286 | void hmp_hello_world(Monitor *mon, const QDict *qdict) |
| 287 | { |
| 288 | const char *message = qdict_get_try_str(qdict, "message"); |
| 289 | Error *err = NULL; |
| 290 | |
| 291 | qmp_hello_world(!!message, message, &err); |
| 292 | if (hmp_handle_error(mon, err)) { |
| 293 | return; |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | Add it to monitor/hmp-cmds.c. Also, add its prototype to |
| 298 | include/monitor/hmp.h. |
| 299 | |
| 300 | There are four important points to be noticed: |
| 301 | |
| 302 | 1. The "mon" and "qdict" arguments are mandatory for all HMP functions. The |
| 303 | former is the monitor object. The latter is how the monitor passes |
| 304 | arguments entered by the user to the command implementation |
| 305 | 2. We chose not to support the "times" argument in HMP |
| 306 | 3. hmp_hello_world() performs error checking. In this example we just call |
| 307 | hmp_handle_error() which prints a message to the user, but we could do |
| 308 | more, like taking different actions depending on the error |
| 309 | qmp_hello_world() returns |
| 310 | 4. The "err" variable must be initialized to NULL before performing the |
| 311 | QMP call |
| 312 | |
| 313 | There's one last step to actually make the command available to monitor users, |
| 314 | we should add it to the hmp-commands.hx file:: |
| 315 | |
| 316 | { |
| 317 | .name = "hello-world", |
| 318 | .args_type = "message:s?", |
| 319 | .params = "hello-world [message]", |
| 320 | .help = "Print message to the standard output", |
| 321 | .cmd = hmp_hello_world, |
| 322 | }, |
| 323 | |
| 324 | SRST |
| 325 | ``hello_world`` *message* |
| 326 | Print message to the standard output |
| 327 | ERST |
| 328 | |
| 329 | To test this you have to open a user monitor and issue the "hello-world" |
| 330 | command. It might be instructive to check the command's documentation with |
| 331 | HMP's "help" command. |
| 332 | |
| 333 | Please check the "-monitor" command-line option to know how to open a user |
| 334 | monitor. |
| 335 | |
| 336 | |
| 337 | Writing more complex commands |
| 338 | ----------------------------- |
| 339 | |
| 340 | A QMP command is capable of returning any data QAPI supports like integers, |
| 341 | strings, booleans, enumerations and user defined types. |
| 342 | |
| 343 | In this section we will focus on user defined types. Please check the QAPI |
| 344 | documentation for information about the other types. |
| 345 | |
| 346 | |
| 347 | Modelling data in QAPI |
| 348 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 349 | |
| 350 | For a QMP command that to be considered stable and supported long term, |
| 351 | there is a requirement returned data should be explicitly modelled |
| 352 | using fine-grained QAPI types. As a general guide, a caller of the QMP |
| 353 | command should never need to parse individual returned data fields. If |
| 354 | a field appears to need parsing, then it should be split into separate |
| 355 | fields corresponding to each distinct data item. This should be the |
| 356 | common case for any new QMP command that is intended to be used by |
| 357 | machines, as opposed to exclusively human operators. |
| 358 | |
| 359 | Some QMP commands, however, are only intended as ad hoc debugging aids |
| 360 | for human operators. While they may return large amounts of formatted |
| 361 | data, it is not expected that machines will need to parse the result. |
| 362 | The overhead of defining a fine grained QAPI type for the data may not |
| 363 | be justified by the potential benefit. In such cases, it is permitted |
| 364 | to have a command return a simple string that contains formatted data, |
| 365 | however, it is mandatory for the command to be marked unstable. |
| 366 | This indicates that the command is not guaranteed to be long term |
| 367 | stable / liable to change in future and is not following QAPI design |
| 368 | best practices. An example where this approach is taken is the QMP |
| 369 | command "x-query-registers". This returns a formatted dump of the |
| 370 | architecture specific CPU state. The way the data is formatted varies |
| 371 | across QEMU targets, is liable to change over time, and is only |
| 372 | intended to be consumed as an opaque string by machines. Refer to the |
| 373 | `Writing a debugging aid returning unstructured text`_ section for |
| 374 | an illustration. |
| 375 | |
| 376 | User Defined Types |
| 377 | ~~~~~~~~~~~~~~~~~~ |
| 378 | |
| 379 | For this example we will write the query-option-roms command, which |
| 380 | returns information about ROMs loaded into the option ROM space. For |
| 381 | more information about it, please check the "-option-rom" command-line |
| 382 | option. |
| 383 | |
| 384 | For each option ROM, we want to return two pieces of information: the |
| 385 | ROM image's file name, and its bootindex, if any. We need to create a |
| 386 | new QAPI type for that, as shown below:: |
| 387 | |
| 388 | ## |
| 389 | # @OptionRomInfo: |
| 390 | # |
| 391 | # @filename: option ROM image file name |
| 392 | # |
| 393 | # @bootindex: option ROM's bootindex |
| 394 | # |
| 395 | # Since: 9.0 |
| 396 | ## |
| 397 | { 'struct': 'OptionRomInfo', |
| 398 | 'data': { 'filename': 'str', '*bootindex': 'int' } } |
| 399 | |
| 400 | The "struct" keyword defines a new QAPI type. Its "data" member |
| 401 | contains the type's members. In this example our members are |
| 402 | "filename" and "bootindex". The latter is optional. |
| 403 | |
| 404 | Now let's define the query-option-roms command:: |
| 405 | |
| 406 | ## |
| 407 | # @query-option-roms: |
| 408 | # |
| 409 | # Query information on ROMs loaded into the option ROM space. |
| 410 | # |
| 411 | # Returns: OptionRomInfo |
| 412 | # |
| 413 | # Since: 9.0 |
| 414 | ## |
| 415 | { 'command': 'query-option-roms', |
| 416 | 'returns': ['OptionRomInfo'] } |
| 417 | |
| 418 | Notice the "returns" keyword. As its name suggests, it's used to define the |
| 419 | data returned by a command. |
| 420 | |
| 421 | Notice the syntax ['OptionRomInfo']". This should be read as "returns |
| 422 | a list of OptionRomInfo". |
| 423 | |
| 424 | It's time to implement the qmp_query_option_roms() function. Add to |
| 425 | monitor/qmp-cmds.c:: |
| 426 | |
| 427 | OptionRomInfoList *qmp_query_option_roms(Error **errp) |
| 428 | { |
| 429 | OptionRomInfoList *info_list = NULL; |
| 430 | OptionRomInfoList **tailp = &info_list; |
| 431 | OptionRomInfo *info; |
| 432 | |
| 433 | for (int i = 0; i < nb_option_roms; i++) { |
| 434 | info = g_malloc0(sizeof(*info)); |
| 435 | info->filename = g_strdup(option_rom[i].name); |
| 436 | info->has_bootindex = option_rom[i].bootindex >= 0; |
| 437 | if (info->has_bootindex) { |
| 438 | info->bootindex = option_rom[i].bootindex; |
| 439 | } |
| 440 | QAPI_LIST_APPEND(tailp, info); |
| 441 | } |
| 442 | |
| 443 | return info_list; |
| 444 | } |
| 445 | |
| 446 | There are a number of things to be noticed: |
| 447 | |
| 448 | 1. Type OptionRomInfo is automatically generated by the QAPI framework, |
| 449 | its members correspond to the type's specification in the schema |
| 450 | file |
| 451 | 2. Type OptionRomInfoList is also generated. It's a singly linked |
| 452 | list. |
| 453 | 3. As specified in the schema file, the function returns a |
| 454 | OptionRomInfoList, and takes no arguments (besides the "errp" one, |
| 455 | which is mandatory for all QMP functions) |
| 456 | 4. The returned object is dynamically allocated |
| 457 | 5. All strings are dynamically allocated. This is so because QAPI also |
| 458 | generates a function to free its types and it cannot distinguish |
| 459 | between dynamically or statically allocated strings |
| 460 | 6. Remember that "bootindex" is optional? As a non-pointer optional |
| 461 | member, it comes with a 'has_bootindex' member that needs to be set |
| 462 | by the implementation, as shown above |
| 463 | |
| 464 | Time to test the new command. Build QEMU, run it as described in the "Testing" |
| 465 | section and try this:: |
| 466 | |
| 467 | { "execute": "query-option-rom" } |
| 468 | { |
| 469 | "return": [ |
| 470 | { |
| 471 | "filename": "kvmvapic.bin" |
| 472 | } |
| 473 | ] |
| 474 | } |
| 475 | |
| 476 | |
| 477 | The HMP command |
| 478 | ~~~~~~~~~~~~~~~ |
| 479 | |
| 480 | Here's the HMP counterpart of the query-option-roms command:: |
| 481 | |
| 482 | void hmp_info_option_roms(MonitorHMP *mon, const QDict *qdict) |
| 483 | { |
| 484 | Error *err = NULL; |
| 485 | OptionRomInfoList *info_list, *tail; |
| 486 | OptionRomInfo *info; |
| 487 | |
| 488 | info_list = qmp_query_option_roms(&err); |
| 489 | if (hmp_handle_error(mon, err)) { |
| 490 | return; |
| 491 | } |
| 492 | |
| 493 | for (tail = info_list; tail; tail = tail->next) { |
| 494 | info = tail->value; |
| 495 | monitor_hmp_printf(mon, "%s", info->filename); |
| 496 | if (info->has_bootindex) { |
| 497 | monitor_hmp_printf(mon, " %" PRId64, info->bootindex); |
| 498 | } |
| 499 | monitor_hmp_printf(mon, "\n"); |
| 500 | } |
| 501 | |
| 502 | qapi_free_OptionRomInfoList(info_list); |
| 503 | } |
| 504 | |
| 505 | It's important to notice that hmp_info_option_roms() calls |
| 506 | qapi_free_OptionRomInfoList() to free the data returned by |
| 507 | qmp_query_option_roms(). For user defined types, QAPI will generate a |
| 508 | qapi_free_QAPI_TYPE_NAME() function, and that's what you have to use to |
| 509 | free the types you define and qapi_free_QAPI_TYPE_NAMEList() for list |
| 510 | types (explained in the next section). If the QMP function returns a |
| 511 | string, then you should g_free() to free it. |
| 512 | |
| 513 | Also note that hmp_info_option_roms() performs error handling. That's |
| 514 | not strictly required when you're sure the QMP function doesn't return |
| 515 | errors; you could instead pass it &error_abort then. |
| 516 | |
| 517 | Another important detail is that HMP's "info" commands go into |
| 518 | hmp-commands-info.hx, not hmp-commands.hx. The entry for the "info |
| 519 | option-roms" follows:: |
| 520 | |
| 521 | { |
| 522 | .name = "option-roms", |
| 523 | .args_type = "", |
| 524 | .params = "", |
| 525 | .help = "show roms", |
| 526 | .cmd = hmp_info_option_roms, |
| 527 | }, |
| 528 | SRST |
| 529 | ``info option-roms`` |
| 530 | Show the option ROMs. |
| 531 | ERST |
| 532 | |
| 533 | To test this, run QEMU and type "info option-roms" in the user monitor. |
| 534 | |
| 535 | |
| 536 | Writing a debugging aid returning unstructured text |
| 537 | --------------------------------------------------- |
| 538 | |
| 539 | As discussed in section `Modelling data in QAPI`_, it is required that |
| 540 | commands expecting machine usage be using fine-grained QAPI data types. |
| 541 | The exception to this rule applies when the command is solely intended |
| 542 | as a debugging aid and allows for returning unstructured text, such as |
| 543 | a query command that report aspects of QEMU's internal state that are |
| 544 | useful only to human operators. |
| 545 | |
| 546 | In this example we will consider the existing QMP command |
| 547 | ``x-query-roms`` in qapi/machine.json. It has no parameters and |
| 548 | returns a ``HumanReadableText``:: |
| 549 | |
| 550 | ## |
| 551 | # @x-query-roms: |
| 552 | # |
| 553 | # Query information on the registered ROMS |
| 554 | # |
| 555 | # Features: |
| 556 | # |
| 557 | # @unstable: This command is meant for debugging. |
| 558 | # |
| 559 | # Returns: registered ROMs |
| 560 | # |
| 561 | # Since: 6.2 |
| 562 | ## |
| 563 | { 'command': 'x-query-roms', |
| 564 | 'returns': 'HumanReadableText', |
| 565 | 'features': [ 'unstable' ] } |
| 566 | |
| 567 | The ``HumanReadableText`` struct is defined in qapi/common.json as a |
| 568 | struct with a string member. It is intended to be used for all |
| 569 | commands that are returning unstructured text targeted at |
| 570 | humans. These should all have feature 'unstable'. Note that the |
| 571 | feature's documentation states why the command is unstable. We |
| 572 | commonly use a ``x-`` command name prefix to make lack of stability |
| 573 | obvious to human users. |
| 574 | |
| 575 | Implementing the QMP command |
| 576 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 577 | |
| 578 | The QMP implementation will typically involve creating a ``GString`` |
| 579 | object and printing formatted data into it, like this:: |
| 580 | |
| 581 | HumanReadableText *qmp_x_query_roms(Error **errp) |
| 582 | { |
| 583 | g_autoptr(GString) buf = g_string_new(""); |
| 584 | Rom *rom; |
| 585 | |
| 586 | QTAILQ_FOREACH(rom, &roms, next) { |
| 587 | g_string_append_printf("%s size=0x%06zx name=\"%s\"\n", |
| 588 | memory_region_name(rom->mr), |
| 589 | rom->romsize, |
| 590 | rom->name); |
| 591 | } |
| 592 | |
| 593 | return human_readable_text_from_str(buf); |
| 594 | } |
| 595 | |
| 596 | The actual implementation emits more information. You can find it in |
| 597 | hw/core/loader.c. |
| 598 | |
| 599 | |
| 600 | Implementing the HMP command |
| 601 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 602 | |
| 603 | Now that the QMP command is in place, we can also make it available in |
| 604 | the human monitor (HMP) as shown in previous examples. The HMP |
| 605 | implementations will all look fairly similar, as all they need do is |
| 606 | invoke the QMP command and then print the resulting text or error |
| 607 | message. Here's an implementation of the "info roms" HMP command:: |
| 608 | |
| 609 | void hmp_info_roms(Monitor *mon, const QDict *qdict) |
| 610 | { |
| 611 | Error err = NULL; |
| 612 | g_autoptr(HumanReadableText) info = qmp_x_query_roms(&err); |
| 613 | |
| 614 | if (hmp_handle_error(mon, err)) { |
| 615 | return; |
| 616 | } |
| 617 | monitor_puts(mon, info->human_readable_text); |
| 618 | } |
| 619 | |
| 620 | Also, you have to add the function's prototype to the hmp.h file. |
| 621 | |
| 622 | There's one last step to actually make the command available to |
| 623 | monitor users, we should add it to the hmp-commands-info.hx file:: |
| 624 | |
| 625 | { |
| 626 | .name = "roms", |
| 627 | .args_type = "", |
| 628 | .params = "", |
| 629 | .help = "show roms", |
| 630 | .cmd = hmp_info_roms, |
| 631 | }, |
| 632 | |
| 633 | The case of writing a HMP info handler that calls a no-parameter QMP query |
| 634 | command is quite common. To simplify the implementation there is a general |
| 635 | purpose HMP info handler for this scenario. All that is required to expose |
| 636 | a no-parameter QMP query command via HMP is to declare it using the |
| 637 | '.cmd_info_hrt' field to point to the QMP handler, and leave the '.cmd' |
| 638 | field NULL:: |
| 639 | |
| 640 | { |
| 641 | .name = "roms", |
| 642 | .args_type = "", |
| 643 | .params = "", |
| 644 | .help = "show roms", |
| 645 | .cmd_info_hrt = qmp_x_query_roms, |
| 646 | }, |
| 647 | |
| 648 | This is how the actual HMP command is done. |