|  | How to write monitor commands | 
|  | ============================= | 
|  |  | 
|  | This document is a step-by-step guide on how to write new QMP commands using | 
|  | the QAPI framework and HMP commands. | 
|  |  | 
|  | This document doesn't discuss QMP protocol level details, nor does it dive | 
|  | into the QAPI framework implementation. | 
|  |  | 
|  | For an in-depth introduction to the QAPI framework, please refer to | 
|  | :doc:`qapi-code-gen`.  For the QMP protocol, see the | 
|  | :doc:`/interop/qmp-spec`. | 
|  |  | 
|  | New commands may be implemented in QMP only.  New HMP commands should be | 
|  | implemented on top of QMP.  The typical HMP command wraps around an | 
|  | equivalent QMP command, but HMP convenience commands built from QMP | 
|  | building blocks are also fine.  The long term goal is to make all | 
|  | existing HMP commands conform to this, to fully isolate HMP from the | 
|  | internals of QEMU. Refer to the `Writing a debugging aid returning | 
|  | unstructured text`_ section for further guidance on commands that | 
|  | would have traditionally been HMP only. | 
|  |  | 
|  | Overview | 
|  | -------- | 
|  |  | 
|  | Generally speaking, the following steps should be taken in order to write a | 
|  | new QMP command. | 
|  |  | 
|  | 1. Define the command and any types it needs in the appropriate QAPI | 
|  | schema module. | 
|  |  | 
|  | 2. Write the QMP command itself, which is a regular C function. Preferably, | 
|  | the command should be exported by some QEMU subsystem. But it can also be | 
|  | added to the monitor/qmp-cmds.c file | 
|  |  | 
|  | 3. At this point the command can be tested under the QMP protocol | 
|  |  | 
|  | 4. Write the HMP command equivalent. This is not required and should only be | 
|  | done if it does make sense to have the functionality in HMP. The HMP command | 
|  | is implemented in terms of the QMP command | 
|  |  | 
|  | The following sections will demonstrate each of the steps above. We will start | 
|  | very simple and get more complex as we progress. | 
|  |  | 
|  |  | 
|  | Testing | 
|  | ------- | 
|  |  | 
|  | For all the examples in the next sections, the test setup is the same and is | 
|  | shown here. | 
|  |  | 
|  | First, QEMU should be started like this:: | 
|  |  | 
|  | # qemu-system-TARGET [...] \ | 
|  | -chardev socket,id=qmp,port=4444,host=localhost,server=on \ | 
|  | -mon chardev=qmp,mode=control,pretty=on | 
|  |  | 
|  | Then, in a different terminal:: | 
|  |  | 
|  | $ telnet localhost 4444 | 
|  | Trying 127.0.0.1... | 
|  | Connected to localhost. | 
|  | Escape character is '^]'. | 
|  | { | 
|  | "QMP": { | 
|  | "version": { | 
|  | "qemu": { | 
|  | "micro": 50, | 
|  | "minor": 2, | 
|  | "major": 8 | 
|  | }, | 
|  | "package": ... | 
|  | }, | 
|  | "capabilities": [ | 
|  | "oob" | 
|  | ] | 
|  | } | 
|  | } | 
|  |  | 
|  | The above output is the QMP server saying you're connected. The server is | 
|  | actually in capabilities negotiation mode. To enter in command mode type:: | 
|  |  | 
|  | { "execute": "qmp_capabilities" } | 
|  |  | 
|  | Then the server should respond:: | 
|  |  | 
|  | { | 
|  | "return": { | 
|  | } | 
|  | } | 
|  |  | 
|  | Which is QMP's way of saying "the latest command executed OK and didn't return | 
|  | any data". Now you're ready to enter the QMP example commands as explained in | 
|  | the following sections. | 
|  |  | 
|  |  | 
|  | Writing a simple command: hello-world | 
|  | ------------------------------------- | 
|  |  | 
|  | That's the most simple QMP command that can be written. Usually, this kind of | 
|  | command carries some meaningful action in QEMU but here it will just print | 
|  | "Hello, world" to the standard output. | 
|  |  | 
|  | Our command will be called "hello-world". It takes no arguments, nor does it | 
|  | return any data. | 
|  |  | 
|  | The first step is defining the command in the appropriate QAPI schema | 
|  | module.  We pick module qapi/misc.json, and add the following line at | 
|  | the bottom:: | 
|  |  | 
|  | ## | 
|  | # @hello-world: | 
|  | # | 
|  | # Since: 9.0 | 
|  | ## | 
|  | { 'command': 'hello-world' } | 
|  |  | 
|  | The "command" keyword defines a new QMP command. It instructs QAPI to | 
|  | generate any prototypes and the necessary code to marshal and unmarshal | 
|  | protocol data. | 
|  |  | 
|  | The next step is to write the "hello-world" implementation. As explained | 
|  | earlier, it's preferable for commands to live in QEMU subsystems. But | 
|  | "hello-world" doesn't pertain to any, so we put its implementation in | 
|  | monitor/qmp-cmds.c:: | 
|  |  | 
|  | void qmp_hello_world(Error **errp) | 
|  | { | 
|  | printf("Hello, world!\n"); | 
|  | } | 
|  |  | 
|  | There are a few things to be noticed: | 
|  |  | 
|  | 1. QMP command implementation functions must be prefixed with "qmp\_" | 
|  | 2. qmp_hello_world() returns void, this is in accordance with the fact that the | 
|  | command doesn't return any data | 
|  | 3. It takes an "Error \*\*" argument. This is required. Later we will see how to | 
|  | return errors and take additional arguments. The Error argument should not | 
|  | be touched if the command doesn't return errors | 
|  | 4. We won't add the function's prototype. That's automatically done by QAPI | 
|  | 5. Printing to the terminal is discouraged for QMP commands, we do it here | 
|  | because it's the easiest way to demonstrate a QMP command | 
|  |  | 
|  | You're done. Now build QEMU, run it as suggested in the "Testing" section, | 
|  | and then type the following QMP command:: | 
|  |  | 
|  | { "execute": "hello-world" } | 
|  |  | 
|  | Then check the terminal running QEMU and look for the "Hello, world" string. If | 
|  | you don't see it then something went wrong. | 
|  |  | 
|  |  | 
|  | Arguments | 
|  | ~~~~~~~~~ | 
|  |  | 
|  | Let's add arguments to our "hello-world" command. | 
|  |  | 
|  | The first change we have to do is to modify the command specification in the | 
|  | schema file to the following:: | 
|  |  | 
|  | ## | 
|  | # @hello-world: | 
|  | # | 
|  | # @message: message to be printed (default: "Hello, world!") | 
|  | # | 
|  | # @times: how many times to print the message (default: 1) | 
|  | # | 
|  | # Since: 9.0 | 
|  | ## | 
|  | { 'command': 'hello-world', | 
|  | 'data': { '*message': 'str', '*times': 'int' } } | 
|  |  | 
|  | Notice the new 'data' member in the schema. It specifies an argument | 
|  | 'message' of QAPI type 'str', and an argument 'times' of QAPI type | 
|  | 'int'.  Also notice the asterisk, it's used to mark the argument | 
|  | optional. | 
|  |  | 
|  | Now, let's update our C implementation in monitor/qmp-cmds.c:: | 
|  |  | 
|  | void qmp_hello_world(const char *message, bool has_times, int64_t times, | 
|  | Error **errp) | 
|  | { | 
|  | if (!message) { | 
|  | message = "Hello, world"; | 
|  | } | 
|  | if (!has_times) { | 
|  | times = 1; | 
|  | } | 
|  |  | 
|  | for (int i = 0; i < times; i++) { | 
|  | printf("%s\n", message); | 
|  | } | 
|  | } | 
|  |  | 
|  | There are two important details to be noticed: | 
|  |  | 
|  | 1. Optional arguments other than pointers are accompanied by a 'has\_' | 
|  | boolean, which is set if the optional argument is present or false | 
|  | otherwise | 
|  | 2. The C implementation signature must follow the schema's argument ordering, | 
|  | which is defined by the "data" member | 
|  |  | 
|  | Time to test our new version of the "hello-world" command. Build QEMU, run it as | 
|  | described in the "Testing" section and then send two commands:: | 
|  |  | 
|  | { "execute": "hello-world" } | 
|  | { | 
|  | "return": { | 
|  | } | 
|  | } | 
|  |  | 
|  | { "execute": "hello-world", "arguments": { "message": "We love QEMU" } } | 
|  | { | 
|  | "return": { | 
|  | } | 
|  | } | 
|  |  | 
|  | You should see "Hello, world" and "We love QEMU" in the terminal running QEMU, | 
|  | if you don't see these strings, then something went wrong. | 
|  |  | 
|  |  | 
|  | Errors | 
|  | ~~~~~~ | 
|  |  | 
|  | QMP commands should use the error interface exported by the error.h header | 
|  | file. Basically, most errors are set by calling the error_setg() function. | 
|  |  | 
|  | Let's say we don't accept the string "message" to contain the word "love". If | 
|  | it does contain it, we want the "hello-world" command to return an error:: | 
|  |  | 
|  | void qmp_hello_world(const char *message, Error **errp) | 
|  | { | 
|  | if (message) { | 
|  | if (strstr(message, "love")) { | 
|  | error_setg(errp, "the word 'love' is not allowed"); | 
|  | return; | 
|  | } | 
|  | printf("%s\n", message); | 
|  | } else { | 
|  | printf("Hello, world\n"); | 
|  | } | 
|  | } | 
|  |  | 
|  | The first argument to the error_setg() function is the Error pointer | 
|  | to pointer, which is passed to all QMP functions. The next argument is a human | 
|  | description of the error, this is a free-form printf-like string. | 
|  |  | 
|  | Let's test the example above. Build QEMU, run it as defined in the "Testing" | 
|  | section, and then issue the following command:: | 
|  |  | 
|  | { "execute": "hello-world", "arguments": { "message": "all you need is love" } } | 
|  |  | 
|  | The QMP server's response should be:: | 
|  |  | 
|  | { | 
|  | "error": { | 
|  | "class": "GenericError", | 
|  | "desc": "the word 'love' is not allowed" | 
|  | } | 
|  | } | 
|  |  | 
|  | Note that error_setg() produces a "GenericError" class.  In general, | 
|  | all QMP errors should have that error class.  There are two exceptions | 
|  | to this rule: | 
|  |  | 
|  | 1. To support a management application's need to recognize a specific | 
|  | error for special handling | 
|  |  | 
|  | 2. Backward compatibility | 
|  |  | 
|  | If the failure you want to report falls into one of the two cases above, | 
|  | use error_set() with a second argument of an ErrorClass value. | 
|  |  | 
|  |  | 
|  | Implementing the HMP command | 
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  |  | 
|  | Now that the QMP command is in place, we can also make it available in the human | 
|  | monitor (HMP). | 
|  |  | 
|  | With the introduction of QAPI, HMP commands make QMP calls. Most of the | 
|  | time HMP commands are simple wrappers. | 
|  |  | 
|  | Here's the implementation of the "hello-world" HMP command:: | 
|  |  | 
|  | void hmp_hello_world(Monitor *mon, const QDict *qdict) | 
|  | { | 
|  | const char *message = qdict_get_try_str(qdict, "message"); | 
|  | Error *err = NULL; | 
|  |  | 
|  | qmp_hello_world(!!message, message, &err); | 
|  | if (hmp_handle_error(mon, err)) { | 
|  | return; | 
|  | } | 
|  | } | 
|  |  | 
|  | Add it to monitor/hmp-cmds.c.  Also, add its prototype to | 
|  | include/monitor/hmp.h. | 
|  |  | 
|  | There are four important points to be noticed: | 
|  |  | 
|  | 1. The "mon" and "qdict" arguments are mandatory for all HMP functions. The | 
|  | former is the monitor object. The latter is how the monitor passes | 
|  | arguments entered by the user to the command implementation | 
|  | 2. We chose not to support the "times" argument in HMP | 
|  | 3. hmp_hello_world() performs error checking. In this example we just call | 
|  | hmp_handle_error() which prints a message to the user, but we could do | 
|  | more, like taking different actions depending on the error | 
|  | qmp_hello_world() returns | 
|  | 4. The "err" variable must be initialized to NULL before performing the | 
|  | QMP call | 
|  |  | 
|  | There's one last step to actually make the command available to monitor users, | 
|  | we should add it to the hmp-commands.hx file:: | 
|  |  | 
|  | { | 
|  | .name       = "hello-world", | 
|  | .args_type  = "message:s?", | 
|  | .params     = "hello-world [message]", | 
|  | .help       = "Print message to the standard output", | 
|  | .cmd        = hmp_hello_world, | 
|  | }, | 
|  |  | 
|  | SRST | 
|  | ``hello_world`` *message* | 
|  | Print message to the standard output | 
|  | ERST | 
|  |  | 
|  | To test this you have to open a user monitor and issue the "hello-world" | 
|  | command. It might be instructive to check the command's documentation with | 
|  | HMP's "help" command. | 
|  |  | 
|  | Please check the "-monitor" command-line option to know how to open a user | 
|  | monitor. | 
|  |  | 
|  |  | 
|  | Writing more complex commands | 
|  | ----------------------------- | 
|  |  | 
|  | A QMP command is capable of returning any data QAPI supports like integers, | 
|  | strings, booleans, enumerations and user defined types. | 
|  |  | 
|  | In this section we will focus on user defined types. Please check the QAPI | 
|  | documentation for information about the other types. | 
|  |  | 
|  |  | 
|  | Modelling data in QAPI | 
|  | ~~~~~~~~~~~~~~~~~~~~~~ | 
|  |  | 
|  | For a QMP command that to be considered stable and supported long term, | 
|  | there is a requirement returned data should be explicitly modelled | 
|  | using fine-grained QAPI types. As a general guide, a caller of the QMP | 
|  | command should never need to parse individual returned data fields. If | 
|  | a field appears to need parsing, then it should be split into separate | 
|  | fields corresponding to each distinct data item. This should be the | 
|  | common case for any new QMP command that is intended to be used by | 
|  | machines, as opposed to exclusively human operators. | 
|  |  | 
|  | Some QMP commands, however, are only intended as ad hoc debugging aids | 
|  | for human operators. While they may return large amounts of formatted | 
|  | data, it is not expected that machines will need to parse the result. | 
|  | The overhead of defining a fine grained QAPI type for the data may not | 
|  | be justified by the potential benefit. In such cases, it is permitted | 
|  | to have a command return a simple string that contains formatted data, | 
|  | however, it is mandatory for the command to be marked unstable. | 
|  | This indicates that the command is not guaranteed to be long term | 
|  | stable / liable to change in future and is not following QAPI design | 
|  | best practices. An example where this approach is taken is the QMP | 
|  | command "x-query-registers". This returns a formatted dump of the | 
|  | architecture specific CPU state. The way the data is formatted varies | 
|  | across QEMU targets, is liable to change over time, and is only | 
|  | intended to be consumed as an opaque string by machines. Refer to the | 
|  | `Writing a debugging aid returning unstructured text`_ section for | 
|  | an illustration. | 
|  |  | 
|  | User Defined Types | 
|  | ~~~~~~~~~~~~~~~~~~ | 
|  |  | 
|  | For this example we will write the query-option-roms command, which | 
|  | returns information about ROMs loaded into the option ROM space. For | 
|  | more information about it, please check the "-option-rom" command-line | 
|  | option. | 
|  |  | 
|  | For each option ROM, we want to return two pieces of information: the | 
|  | ROM image's file name, and its bootindex, if any.  We need to create a | 
|  | new QAPI type for that, as shown below:: | 
|  |  | 
|  | ## | 
|  | # @OptionRomInfo: | 
|  | # | 
|  | # @filename: option ROM image file name | 
|  | # | 
|  | # @bootindex: option ROM's bootindex | 
|  | # | 
|  | # Since: 9.0 | 
|  | ## | 
|  | { 'struct': 'OptionRomInfo', | 
|  | 'data': { 'filename': 'str', '*bootindex': 'int' } } | 
|  |  | 
|  | The "struct" keyword defines a new QAPI type. Its "data" member | 
|  | contains the type's members. In this example our members are | 
|  | "filename" and "bootindex". The latter is optional. | 
|  |  | 
|  | Now let's define the query-option-roms command:: | 
|  |  | 
|  | ## | 
|  | # @query-option-roms: | 
|  | # | 
|  | # Query information on ROMs loaded into the option ROM space. | 
|  | # | 
|  | # Returns: OptionRomInfo | 
|  | # | 
|  | # Since: 9.0 | 
|  | ## | 
|  | { 'command': 'query-option-roms', | 
|  | 'returns': ['OptionRomInfo'] } | 
|  |  | 
|  | Notice the "returns" keyword. As its name suggests, it's used to define the | 
|  | data returned by a command. | 
|  |  | 
|  | Notice the syntax ['OptionRomInfo']". This should be read as "returns | 
|  | a list of OptionRomInfo". | 
|  |  | 
|  | It's time to implement the qmp_query_option_roms() function.  Add to | 
|  | monitor/qmp-cmds.c:: | 
|  |  | 
|  | OptionRomInfoList *qmp_query_option_roms(Error **errp) | 
|  | { | 
|  | OptionRomInfoList *info_list = NULL; | 
|  | OptionRomInfoList **tailp = &info_list; | 
|  | OptionRomInfo *info; | 
|  |  | 
|  | for (int i = 0; i < nb_option_roms; i++) { | 
|  | info = g_malloc0(sizeof(*info)); | 
|  | info->filename = g_strdup(option_rom[i].name); | 
|  | info->has_bootindex = option_rom[i].bootindex >= 0; | 
|  | if (info->has_bootindex) { | 
|  | info->bootindex = option_rom[i].bootindex; | 
|  | } | 
|  | QAPI_LIST_APPEND(tailp, info); | 
|  | } | 
|  |  | 
|  | return info_list; | 
|  | } | 
|  |  | 
|  | There are a number of things to be noticed: | 
|  |  | 
|  | 1. Type OptionRomInfo is automatically generated by the QAPI framework, | 
|  | its members correspond to the type's specification in the schema | 
|  | file | 
|  | 2. Type OptionRomInfoList is also generated.  It's a singly linked | 
|  | list. | 
|  | 3. As specified in the schema file, the function returns a | 
|  | OptionRomInfoList, and takes no arguments (besides the "errp" one, | 
|  | which is mandatory for all QMP functions) | 
|  | 4. The returned object is dynamically allocated | 
|  | 5. All strings are dynamically allocated. This is so because QAPI also | 
|  | generates a function to free its types and it cannot distinguish | 
|  | between dynamically or statically allocated strings | 
|  | 6. Remember that "bootindex" is optional? As a non-pointer optional | 
|  | member, it comes with a 'has_bootindex' member that needs to be set | 
|  | by the implementation, as shown above | 
|  |  | 
|  | Time to test the new command. Build QEMU, run it as described in the "Testing" | 
|  | section and try this:: | 
|  |  | 
|  | { "execute": "query-option-rom" } | 
|  | { | 
|  | "return": [ | 
|  | { | 
|  | "filename": "kvmvapic.bin" | 
|  | } | 
|  | ] | 
|  | } | 
|  |  | 
|  |  | 
|  | The HMP command | 
|  | ~~~~~~~~~~~~~~~ | 
|  |  | 
|  | Here's the HMP counterpart of the query-option-roms command:: | 
|  |  | 
|  | void hmp_info_option_roms(Monitor *mon, const QDict *qdict) | 
|  | { | 
|  | Error *err = NULL; | 
|  | OptionRomInfoList *info_list, *tail; | 
|  | OptionRomInfo *info; | 
|  |  | 
|  | info_list = qmp_query_option_roms(&err); | 
|  | if (hmp_handle_error(mon, err)) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | for (tail = info_list; tail; tail = tail->next) { | 
|  | info = tail->value; | 
|  | monitor_printf(mon, "%s", info->filename); | 
|  | if (info->has_bootindex) { | 
|  | monitor_printf(mon, " %" PRId64, info->bootindex); | 
|  | } | 
|  | monitor_printf(mon, "\n"); | 
|  | } | 
|  |  | 
|  | qapi_free_OptionRomInfoList(info_list); | 
|  | } | 
|  |  | 
|  | It's important to notice that hmp_info_option_roms() calls | 
|  | qapi_free_OptionRomInfoList() to free the data returned by | 
|  | qmp_query_option_roms().  For user defined types, QAPI will generate a | 
|  | qapi_free_QAPI_TYPE_NAME() function, and that's what you have to use to | 
|  | free the types you define and qapi_free_QAPI_TYPE_NAMEList() for list | 
|  | types (explained in the next section). If the QMP function returns a | 
|  | string, then you should g_free() to free it. | 
|  |  | 
|  | Also note that hmp_info_option_roms() performs error handling. That's | 
|  | not strictly required when you're sure the QMP function doesn't return | 
|  | errors; you could instead pass it &error_abort then. | 
|  |  | 
|  | Another important detail is that HMP's "info" commands go into | 
|  | hmp-commands-info.hx, not hmp-commands.hx. The entry for the "info | 
|  | option-roms" follows:: | 
|  |  | 
|  | { | 
|  | .name       = "option-roms", | 
|  | .args_type  = "", | 
|  | .params     = "", | 
|  | .help       = "show roms", | 
|  | .cmd        = hmp_info_option_roms, | 
|  | }, | 
|  | SRST | 
|  | ``info option-roms`` | 
|  | Show the option ROMs. | 
|  | ERST | 
|  |  | 
|  | To test this, run QEMU and type "info option-roms" in the user monitor. | 
|  |  | 
|  |  | 
|  | Writing a debugging aid returning unstructured text | 
|  | --------------------------------------------------- | 
|  |  | 
|  | As discussed in section `Modelling data in QAPI`_, it is required that | 
|  | commands expecting machine usage be using fine-grained QAPI data types. | 
|  | The exception to this rule applies when the command is solely intended | 
|  | as a debugging aid and allows for returning unstructured text, such as | 
|  | a query command that report aspects of QEMU's internal state that are | 
|  | useful only to human operators. | 
|  |  | 
|  | In this example we will consider the existing QMP command | 
|  | ``x-query-roms`` in qapi/machine.json.  It has no parameters and | 
|  | returns a ``HumanReadableText``:: | 
|  |  | 
|  | ## | 
|  | # @x-query-roms: | 
|  | # | 
|  | # Query information on the registered ROMS | 
|  | # | 
|  | # Features: | 
|  | # | 
|  | # @unstable: This command is meant for debugging. | 
|  | # | 
|  | # Returns: registered ROMs | 
|  | # | 
|  | # Since: 6.2 | 
|  | ## | 
|  | { 'command': 'x-query-roms', | 
|  | 'returns': 'HumanReadableText', | 
|  | 'features': [ 'unstable' ] } | 
|  |  | 
|  | The ``HumanReadableText`` struct is defined in qapi/common.json as a | 
|  | struct with a string member. It is intended to be used for all | 
|  | commands that are returning unstructured text targeted at | 
|  | humans. These should all have feature 'unstable'.  Note that the | 
|  | feature's documentation states why the command is unstable.  We | 
|  | commonly use a ``x-`` command name prefix to make lack of stability | 
|  | obvious to human users. | 
|  |  | 
|  | Implementing the QMP command | 
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  |  | 
|  | The QMP implementation will typically involve creating a ``GString`` | 
|  | object and printing formatted data into it, like this:: | 
|  |  | 
|  | HumanReadableText *qmp_x_query_roms(Error **errp) | 
|  | { | 
|  | g_autoptr(GString) buf = g_string_new(""); | 
|  | Rom *rom; | 
|  |  | 
|  | QTAILQ_FOREACH(rom, &roms, next) { | 
|  | g_string_append_printf("%s size=0x%06zx name=\"%s\"\n", | 
|  | memory_region_name(rom->mr), | 
|  | rom->romsize, | 
|  | rom->name); | 
|  | } | 
|  |  | 
|  | return human_readable_text_from_str(buf); | 
|  | } | 
|  |  | 
|  | The actual implementation emits more information.  You can find it in | 
|  | hw/core/loader.c. | 
|  |  | 
|  |  | 
|  | Implementing the HMP command | 
|  | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 
|  |  | 
|  | Now that the QMP command is in place, we can also make it available in | 
|  | the human monitor (HMP) as shown in previous examples. The HMP | 
|  | implementations will all look fairly similar, as all they need do is | 
|  | invoke the QMP command and then print the resulting text or error | 
|  | message. Here's an implementation of the "info roms" HMP command:: | 
|  |  | 
|  | void hmp_info_roms(Monitor *mon, const QDict *qdict) | 
|  | { | 
|  | Error err = NULL; | 
|  | g_autoptr(HumanReadableText) info = qmp_x_query_roms(&err); | 
|  |  | 
|  | if (hmp_handle_error(mon, err)) { | 
|  | return; | 
|  | } | 
|  | monitor_puts(mon, info->human_readable_text); | 
|  | } | 
|  |  | 
|  | Also, you have to add the function's prototype to the hmp.h file. | 
|  |  | 
|  | There's one last step to actually make the command available to | 
|  | monitor users, we should add it to the hmp-commands-info.hx file:: | 
|  |  | 
|  | { | 
|  | .name       = "roms", | 
|  | .args_type  = "", | 
|  | .params     = "", | 
|  | .help       = "show roms", | 
|  | .cmd        = hmp_info_roms, | 
|  | }, | 
|  |  | 
|  | The case of writing a HMP info handler that calls a no-parameter QMP query | 
|  | command is quite common. To simplify the implementation there is a general | 
|  | purpose HMP info handler for this scenario. All that is required to expose | 
|  | a no-parameter QMP query command via HMP is to declare it using the | 
|  | '.cmd_info_hrt' field to point to the QMP handler, and leave the '.cmd' | 
|  | field NULL:: | 
|  |  | 
|  | { | 
|  | .name         = "roms", | 
|  | .args_type    = "", | 
|  | .params       = "", | 
|  | .help         = "show roms", | 
|  | .cmd_info_hrt = qmp_x_query_roms, | 
|  | }, | 
|  |  | 
|  | This is how the actual HMP command is done. |