mirror of https://github.com/xemu-project/xemu.git
QAPI patches patches for 2024-03-04
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmXlaSISHGFybWJydUBy ZWRoYXQuY29tAAoJEDhwtADrkYZTdZ8P/iMgqLoAFkCCjwfkUc/rqZUezK52Ynr7 LYwOPI/xcYD7EnVogdRgFgjWFNoivQLP5yKsU/eRTk29pwdDzTscFm/0ztTQX/Gb ypWV+GBcu5J8mKbp1KF5w68aDD8Bat4WRfEgDQ1DV7v6CoMiUzTiF3CGXkYzqK5Y kYNq97vdEkBFvFdOl/7scs/XXN2jG27egDhMp68RTxnPHlXZiAO9/2Bul3uVe3x0 fzQ2ViYv0qLnjE/PwENDqqE3Thv3Sxp5iEeQQ6GWi07EVh07UtHpOM3RYyrTU0Sb VrTApSrg0oxlkOuR0CBd9Fi+timtbokBL0DWyUpXNTfIEZfLtA9H+8riUg3EOcDp r7a4SI/27VdPxX6Kc6zA3bi+/j1o7CLTW2LGEwuZs52nmixoo1HTWPIFdyh13g/V QjNbun0fViHb0FVLiyDlXF/7Y+EWUWIyqwwGqbvve1DyUHQmo3CUQAKGOpkeKSBe 4eGciVDgpBoKhtw9Kv6LCDj2cwZKC8DxBMibf7GHkOnAsX2mnyuHcey7HvYNCoF+ yYz7oIEXdlL2eWqg7CfBZK7lniCDln50RI4Ll1v+J4r1v1kRZGMLesTYXCdNc4ku yb4kpU4t22/RODffLE7K+fc3Onwze3fcfxlZMN66F+wFtk4KdPR2aQBE66bB8J99 vuSKlTbT4cGL =s9AR -----END PGP SIGNATURE----- Merge tag 'pull-qapi-2024-03-04' of https://repo.or.cz/qemu/armbru into staging QAPI patches patches for 2024-03-04 # -----BEGIN PGP SIGNATURE----- # # iQJGBAABCAAwFiEENUvIs9frKmtoZ05fOHC0AOuRhlMFAmXlaSISHGFybWJydUBy # ZWRoYXQuY29tAAoJEDhwtADrkYZTdZ8P/iMgqLoAFkCCjwfkUc/rqZUezK52Ynr7 # LYwOPI/xcYD7EnVogdRgFgjWFNoivQLP5yKsU/eRTk29pwdDzTscFm/0ztTQX/Gb # ypWV+GBcu5J8mKbp1KF5w68aDD8Bat4WRfEgDQ1DV7v6CoMiUzTiF3CGXkYzqK5Y # kYNq97vdEkBFvFdOl/7scs/XXN2jG27egDhMp68RTxnPHlXZiAO9/2Bul3uVe3x0 # fzQ2ViYv0qLnjE/PwENDqqE3Thv3Sxp5iEeQQ6GWi07EVh07UtHpOM3RYyrTU0Sb # VrTApSrg0oxlkOuR0CBd9Fi+timtbokBL0DWyUpXNTfIEZfLtA9H+8riUg3EOcDp # r7a4SI/27VdPxX6Kc6zA3bi+/j1o7CLTW2LGEwuZs52nmixoo1HTWPIFdyh13g/V # QjNbun0fViHb0FVLiyDlXF/7Y+EWUWIyqwwGqbvve1DyUHQmo3CUQAKGOpkeKSBe # 4eGciVDgpBoKhtw9Kv6LCDj2cwZKC8DxBMibf7GHkOnAsX2mnyuHcey7HvYNCoF+ # yYz7oIEXdlL2eWqg7CfBZK7lniCDln50RI4Ll1v+J4r1v1kRZGMLesTYXCdNc4ku # yb4kpU4t22/RODffLE7K+fc3Onwze3fcfxlZMN66F+wFtk4KdPR2aQBE66bB8J99 # vuSKlTbT4cGL # =s9AR # -----END PGP SIGNATURE----- # gpg: Signature made Mon 04 Mar 2024 06:24:34 GMT # gpg: using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653 # gpg: issuer "armbru@redhat.com" # gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full] # gpg: aka "Markus Armbruster <armbru@pond.sub.org>" [full] # Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867 4E5F 3870 B400 EB91 8653 * tag 'pull-qapi-2024-03-04' of https://repo.or.cz/qemu/armbru: migration: simplify exec migration functions qapi: New strv_from_str_list() qapi: New QAPI_LIST_LENGTH() docs/devel/writing-monitor-commands: Minor improvements docs/devel/writing-monitor-commands: Repair a decade of rot qapi: Reject "Returns" section when command doesn't return anything qga/qapi-schema: Fix guest-set-memory-blocks documentation qga/qapi-schema: Tweak documentation of fsfreeze commands qga/qapi-schema: Clean up "Returns" sections qga/qapi-schema: Delete useless "Returns" sections qga/qapi-schema: Move error documentation to new "Errors" sections qapi/yank: Tweak @yank's error description for consistency qapi: Clean up "Returns" sections qapi: Delete useless "Returns" sections qapi: Move error documentation to new "Errors" sections qapi: New documentation section tag "Errors" qapi: Slightly clearer error message for invalid "Returns" section qapi: Memorize since & returns sections Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7d4e29ef80
|
@ -996,7 +996,8 @@ line "Features:", like this::
|
||||||
|
|
||||||
A tagged section begins with a paragraph that starts with one of the
|
A tagged section begins with a paragraph that starts with one of the
|
||||||
following words: "Note:"/"Notes:", "Since:", "Example:"/"Examples:",
|
following words: "Note:"/"Notes:", "Since:", "Example:"/"Examples:",
|
||||||
"Returns:", "TODO:". It ends with the start of a new section.
|
"Returns:", "Errors:", "TODO:". It ends with the start of a new
|
||||||
|
section.
|
||||||
|
|
||||||
The second and subsequent lines of tagged sections must be indented
|
The second and subsequent lines of tagged sections must be indented
|
||||||
like this::
|
like this::
|
||||||
|
@ -1007,6 +1008,9 @@ like this::
|
||||||
# Duis aute irure dolor in reprehenderit in voluptate velit esse
|
# Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||||
# cillum dolore eu fugiat nulla pariatur.
|
# cillum dolore eu fugiat nulla pariatur.
|
||||||
|
|
||||||
|
"Returns" and "Errors" sections are only valid for commands. They
|
||||||
|
document the success and the error response, respectively.
|
||||||
|
|
||||||
A "Since: x.y.z" tagged section lists the release that introduced the
|
A "Since: x.y.z" tagged section lists the release that introduced the
|
||||||
definition.
|
definition.
|
||||||
|
|
||||||
|
|
|
@ -66,12 +66,13 @@ Then, in a different terminal::
|
||||||
"version": {
|
"version": {
|
||||||
"qemu": {
|
"qemu": {
|
||||||
"micro": 50,
|
"micro": 50,
|
||||||
"minor": 15,
|
"minor": 2,
|
||||||
"major": 0
|
"major": 8
|
||||||
},
|
},
|
||||||
"package": ""
|
"package": ...
|
||||||
},
|
},
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
|
"oob"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,10 +108,14 @@ 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
|
module. We pick module qapi/misc.json, and add the following line at
|
||||||
the bottom::
|
the bottom::
|
||||||
|
|
||||||
|
##
|
||||||
|
# @hello-world:
|
||||||
|
#
|
||||||
|
# Since: 9.0
|
||||||
|
##
|
||||||
{ 'command': 'hello-world' }
|
{ 'command': 'hello-world' }
|
||||||
|
|
||||||
The "command" keyword defines a new QMP command. It's an JSON object. All
|
The "command" keyword defines a new QMP command. It instructs QAPI to
|
||||||
schema entries are JSON objects. The line above will instruct the QAPI to
|
|
||||||
generate any prototypes and the necessary code to marshal and unmarshal
|
generate any prototypes and the necessary code to marshal and unmarshal
|
||||||
protocol data.
|
protocol data.
|
||||||
|
|
||||||
|
@ -132,57 +137,70 @@ There are a few things to be noticed:
|
||||||
3. It takes an "Error \*\*" argument. This is required. Later we will see how to
|
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
|
return errors and take additional arguments. The Error argument should not
|
||||||
be touched if the command doesn't return errors
|
be touched if the command doesn't return errors
|
||||||
4. We won't add the function's prototype. That's automatically done by the QAPI
|
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
|
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
|
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,
|
You're done. Now build QEMU, run it as suggested in the "Testing" section,
|
||||||
and then type the following QMP command::
|
and then type the following QMP command::
|
||||||
|
|
||||||
{ "execute": "hello-world" }
|
{ "execute": "hello-world" }
|
||||||
|
|
||||||
Then check the terminal running qemu and look for the "Hello, world" string. If
|
Then check the terminal running QEMU and look for the "Hello, world" string. If
|
||||||
you don't see it then something went wrong.
|
you don't see it then something went wrong.
|
||||||
|
|
||||||
|
|
||||||
Arguments
|
Arguments
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
Let's add an argument called "message" to our "hello-world" command. The new
|
Let's add arguments to our "hello-world" command.
|
||||||
argument will contain the string to be printed to stdout. It's an optional
|
|
||||||
argument, if it's not present we print our default "Hello, World" string.
|
|
||||||
|
|
||||||
The first change we have to do is to modify the command specification in the
|
The first change we have to do is to modify the command specification in the
|
||||||
schema file to the following::
|
schema file to the following::
|
||||||
|
|
||||||
{ 'command': 'hello-world', 'data': { '*message': 'str' } }
|
##
|
||||||
|
# @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's an JSON object whose each
|
Notice the new 'data' member in the schema. It specifies an argument
|
||||||
element is an argument to the command in question. Also notice the asterisk,
|
'message' of QAPI type 'str', and an argument 'times' of QAPI type
|
||||||
it's used to mark the argument optional (that means that you shouldn't use it
|
'int'. Also notice the asterisk, it's used to mark the argument
|
||||||
for mandatory arguments). Finally, 'str' is the argument's type, which
|
optional.
|
||||||
stands for "string". The QAPI also supports integers, booleans, enumerations
|
|
||||||
and user defined types.
|
|
||||||
|
|
||||||
Now, let's update our C implementation in monitor/qmp-cmds.c::
|
Now, let's update our C implementation in monitor/qmp-cmds.c::
|
||||||
|
|
||||||
void qmp_hello_world(const char *message, Error **errp)
|
void qmp_hello_world(const char *message, bool has_times, int64_t times,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
if (message) {
|
if (!message) {
|
||||||
|
message = "Hello, world";
|
||||||
|
}
|
||||||
|
if (!has_times) {
|
||||||
|
times = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < times; i++) {
|
||||||
printf("%s\n", message);
|
printf("%s\n", message);
|
||||||
} else {
|
|
||||||
printf("Hello, world\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
There are two important details to be noticed:
|
There are two important details to be noticed:
|
||||||
|
|
||||||
1. All optional arguments are accompanied by a 'has\_' boolean, which is set
|
1. Optional arguments other than pointers are accompanied by a 'has\_'
|
||||||
if the optional argument is present or false otherwise
|
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,
|
2. The C implementation signature must follow the schema's argument ordering,
|
||||||
which is defined by the "data" member
|
which is defined by the "data" member
|
||||||
|
|
||||||
Time to test our new version of the "hello-world" command. Build qemu, run it as
|
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::
|
described in the "Testing" section and then send two commands::
|
||||||
|
|
||||||
{ "execute": "hello-world" }
|
{ "execute": "hello-world" }
|
||||||
|
@ -191,13 +209,13 @@ described in the "Testing" section and then send two commands::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{ "execute": "hello-world", "arguments": { "message": "We love qemu" } }
|
{ "execute": "hello-world", "arguments": { "message": "We love QEMU" } }
|
||||||
{
|
{
|
||||||
"return": {
|
"return": {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
You should see "Hello, world" and "We love qemu" in the terminal running qemu,
|
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.
|
if you don't see these strings, then something went wrong.
|
||||||
|
|
||||||
|
|
||||||
|
@ -227,7 +245,7 @@ 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
|
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.
|
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"
|
Let's test the example above. Build QEMU, run it as defined in the "Testing"
|
||||||
section, and then issue the following command::
|
section, and then issue the following command::
|
||||||
|
|
||||||
{ "execute": "hello-world", "arguments": { "message": "all you need is love" } }
|
{ "execute": "hello-world", "arguments": { "message": "all you need is love" } }
|
||||||
|
@ -254,44 +272,14 @@ 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.
|
use error_set() with a second argument of an ErrorClass value.
|
||||||
|
|
||||||
|
|
||||||
Command Documentation
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
There's only one step missing to make "hello-world"'s implementation complete,
|
|
||||||
and that's its documentation in the schema file.
|
|
||||||
|
|
||||||
There are many examples of such documentation in the schema file already, but
|
|
||||||
here goes "hello-world"'s new entry for qapi/misc.json::
|
|
||||||
|
|
||||||
##
|
|
||||||
# @hello-world:
|
|
||||||
#
|
|
||||||
# Print a client provided string to the standard output stream.
|
|
||||||
#
|
|
||||||
# @message: string to be printed
|
|
||||||
#
|
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Notes: if @message is not provided, the "Hello, world" string will
|
|
||||||
# be printed instead
|
|
||||||
#
|
|
||||||
# Since: <next qemu stable release, eg. 1.0>
|
|
||||||
##
|
|
||||||
{ 'command': 'hello-world', 'data': { '*message': 'str' } }
|
|
||||||
|
|
||||||
Please, note that the "Returns" clause is optional if a command doesn't return
|
|
||||||
any data nor any errors.
|
|
||||||
|
|
||||||
|
|
||||||
Implementing the HMP command
|
Implementing the HMP command
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Now that the QMP command is in place, we can also make it available in the human
|
Now that the QMP command is in place, we can also make it available in the human
|
||||||
monitor (HMP).
|
monitor (HMP).
|
||||||
|
|
||||||
With the introduction of the QAPI, HMP commands make QMP calls. Most of the
|
With the introduction of QAPI, HMP commands make QMP calls. Most of the
|
||||||
time HMP commands are simple wrappers. All HMP commands implementation exist in
|
time HMP commands are simple wrappers.
|
||||||
the monitor/hmp-cmds.c file.
|
|
||||||
|
|
||||||
Here's the implementation of the "hello-world" HMP command::
|
Here's the implementation of the "hello-world" HMP command::
|
||||||
|
|
||||||
|
@ -306,18 +294,20 @@ Here's the implementation of the "hello-world" HMP command::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Also, you have to add the function's prototype to the hmp.h file.
|
Add it to monitor/hmp-cmds.c. Also, add its prototype to
|
||||||
|
include/monitor/hmp.h.
|
||||||
|
|
||||||
There are three important points to be noticed:
|
There are four important points to be noticed:
|
||||||
|
|
||||||
1. The "mon" and "qdict" arguments are mandatory for all HMP functions. The
|
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
|
former is the monitor object. The latter is how the monitor passes
|
||||||
arguments entered by the user to the command implementation
|
arguments entered by the user to the command implementation
|
||||||
2. hmp_hello_world() performs error checking. In this example we just call
|
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
|
hmp_handle_error() which prints a message to the user, but we could do
|
||||||
more, like taking different actions depending on the error
|
more, like taking different actions depending on the error
|
||||||
qmp_hello_world() returns
|
qmp_hello_world() returns
|
||||||
3. The "err" variable must be initialized to NULL before performing the
|
4. The "err" variable must be initialized to NULL before performing the
|
||||||
QMP call
|
QMP call
|
||||||
|
|
||||||
There's one last step to actually make the command available to monitor users,
|
There's one last step to actually make the command available to monitor users,
|
||||||
|
@ -340,17 +330,17 @@ 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
|
command. It might be instructive to check the command's documentation with
|
||||||
HMP's "help" command.
|
HMP's "help" command.
|
||||||
|
|
||||||
Please, check the "-monitor" command-line option to know how to open a user
|
Please check the "-monitor" command-line option to know how to open a user
|
||||||
monitor.
|
monitor.
|
||||||
|
|
||||||
|
|
||||||
Writing more complex commands
|
Writing more complex commands
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
A QMP command is capable of returning any data the QAPI supports like integers,
|
A QMP command is capable of returning any data QAPI supports like integers,
|
||||||
strings, booleans, enumerations and user defined types.
|
strings, booleans, enumerations and user defined types.
|
||||||
|
|
||||||
In this section we will focus on user defined types. Please, check the QAPI
|
In this section we will focus on user defined types. Please check the QAPI
|
||||||
documentation for information about the other types.
|
documentation for information about the other types.
|
||||||
|
|
||||||
|
|
||||||
|
@ -372,7 +362,7 @@ 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
|
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
|
be justified by the potential benefit. In such cases, it is permitted
|
||||||
to have a command return a simple string that contains formatted data,
|
to have a command return a simple string that contains formatted data,
|
||||||
however, it is mandatory for the command to use the 'x-' name prefix.
|
however, it is mandatory for the command to be marked unstable.
|
||||||
This indicates that the command is not guaranteed to be long term
|
This indicates that the command is not guaranteed to be long term
|
||||||
stable / liable to change in future and is not following QAPI design
|
stable / liable to change in future and is not following QAPI design
|
||||||
best practices. An example where this approach is taken is the QMP
|
best practices. An example where this approach is taken is the QMP
|
||||||
|
@ -386,302 +376,207 @@ an illustration.
|
||||||
User Defined Types
|
User Defined Types
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
FIXME This example needs to be redone after commit 6d32717
|
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 this example we will write the query-alarm-clock command, which returns
|
For each option ROM, we want to return two pieces of information: the
|
||||||
information about QEMU's timer alarm. For more information about it, please
|
ROM image's file name, and its bootindex, if any. We need to create a
|
||||||
check the "-clock" command-line option.
|
new QAPI type for that, as shown below::
|
||||||
|
|
||||||
We want to return two pieces of information. The first one is the alarm clock's
|
|
||||||
name. The second one is when the next alarm will fire. The former information is
|
|
||||||
returned as a string, the latter is an integer in nanoseconds (which is not
|
|
||||||
very useful in practice, as the timer has probably already fired when the
|
|
||||||
information reaches the client).
|
|
||||||
|
|
||||||
The best way to return that data is to create a new QAPI type, as shown below::
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# @QemuAlarmClock
|
# @OptionRomInfo:
|
||||||
#
|
#
|
||||||
# QEMU alarm clock information.
|
# @filename: option ROM image file name
|
||||||
#
|
#
|
||||||
# @clock-name: The alarm clock method's name.
|
# @bootindex: option ROM's bootindex
|
||||||
#
|
#
|
||||||
# @next-deadline: The time (in nanoseconds) the next alarm will fire.
|
# Since: 9.0
|
||||||
#
|
|
||||||
# Since: 1.0
|
|
||||||
##
|
##
|
||||||
{ 'type': 'QemuAlarmClock',
|
{ 'struct': 'OptionRomInfo',
|
||||||
'data': { 'clock-name': 'str', '*next-deadline': 'int' } }
|
'data': { 'filename': 'str', '*bootindex': 'int' } }
|
||||||
|
|
||||||
The "type" keyword defines a new QAPI type. Its "data" member contains the
|
The "struct" keyword defines a new QAPI type. Its "data" member
|
||||||
type's members. In this example our members are the "clock-name" and the
|
contains the type's members. In this example our members are
|
||||||
"next-deadline" one, which is optional.
|
"filename" and "bootindex". The latter is optional.
|
||||||
|
|
||||||
Now let's define the query-alarm-clock command::
|
Now let's define the query-option-roms command::
|
||||||
|
|
||||||
##
|
##
|
||||||
# @query-alarm-clock
|
# @query-option-roms:
|
||||||
#
|
#
|
||||||
# Return information about QEMU's alarm clock.
|
# Query information on ROMs loaded into the option ROM space.
|
||||||
#
|
#
|
||||||
# Returns a @QemuAlarmClock instance describing the alarm clock method
|
# Returns: OptionRomInfo
|
||||||
# being currently used by QEMU (this is usually set by the '-clock'
|
|
||||||
# command-line option).
|
|
||||||
#
|
#
|
||||||
# Since: 1.0
|
# Since: 9.0
|
||||||
##
|
##
|
||||||
{ 'command': 'query-alarm-clock', 'returns': 'QemuAlarmClock' }
|
{ 'command': 'query-option-roms',
|
||||||
|
'returns': ['OptionRomInfo'] }
|
||||||
|
|
||||||
Notice the "returns" keyword. As its name suggests, it's used to define the
|
Notice the "returns" keyword. As its name suggests, it's used to define the
|
||||||
data returned by a command.
|
data returned by a command.
|
||||||
|
|
||||||
It's time to implement the qmp_query_alarm_clock() function, you can put it
|
Notice the syntax ['OptionRomInfo']". This should be read as "returns
|
||||||
in the qemu-timer.c file::
|
a list of OptionRomInfo".
|
||||||
|
|
||||||
QemuAlarmClock *qmp_query_alarm_clock(Error **errp)
|
It's time to implement the qmp_query_option_roms() function. Add to
|
||||||
|
monitor/qmp-cmds.c::
|
||||||
|
|
||||||
|
OptionRomInfoList *qmp_query_option_roms(Error **errp)
|
||||||
{
|
{
|
||||||
QemuAlarmClock *clock;
|
OptionRomInfoList *info_list = NULL;
|
||||||
int64_t deadline;
|
OptionRomInfoList **tailp = &info_list;
|
||||||
|
OptionRomInfo *info;
|
||||||
|
|
||||||
clock = g_malloc0(sizeof(*clock));
|
for (int i = 0; i < nb_option_roms; i++) {
|
||||||
|
info = g_malloc0(sizeof(*info));
|
||||||
deadline = qemu_next_alarm_deadline();
|
info->filename = g_strdup(option_rom[i].name);
|
||||||
if (deadline > 0) {
|
info->has_bootindex = option_rom[i].bootindex >= 0;
|
||||||
clock->has_next_deadline = true;
|
if (info->has_bootindex) {
|
||||||
clock->next_deadline = deadline;
|
info->bootindex = option_rom[i].bootindex;
|
||||||
|
}
|
||||||
|
QAPI_LIST_APPEND(tailp, info);
|
||||||
}
|
}
|
||||||
clock->clock_name = g_strdup(alarm_timer->name);
|
|
||||||
|
|
||||||
return clock;
|
return info_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
There are a number of things to be noticed:
|
There are a number of things to be noticed:
|
||||||
|
|
||||||
1. The QemuAlarmClock type is automatically generated by the QAPI framework,
|
1. Type OptionRomInfo is automatically generated by the QAPI framework,
|
||||||
its members correspond to the type's specification in the schema file
|
its members correspond to the type's specification in the schema
|
||||||
2. As specified in the schema file, the function returns a QemuAlarmClock
|
file
|
||||||
instance and takes no arguments (besides the "errp" one, which is mandatory
|
2. Type OptionRomInfoList is also generated. It's a singly linked
|
||||||
for all QMP functions)
|
list.
|
||||||
3. The "clock" variable (which will point to our QAPI type instance) is
|
3. As specified in the schema file, the function returns a
|
||||||
allocated by the regular g_malloc0() function. Note that we chose to
|
OptionRomInfoList, and takes no arguments (besides the "errp" one,
|
||||||
initialize the memory to zero. This is recommended for all QAPI types, as
|
which is mandatory for all QMP functions)
|
||||||
it helps avoiding bad surprises (specially with booleans)
|
4. The returned object is dynamically allocated
|
||||||
4. Remember that "next_deadline" is optional? Non-pointer optional
|
5. All strings are dynamically allocated. This is so because QAPI also
|
||||||
members have a 'has_TYPE_NAME' member that should be properly set
|
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
|
by the implementation, as shown above
|
||||||
5. Even static strings, such as "alarm_timer->name", should be dynamically
|
|
||||||
allocated by the implementation. This is so because the QAPI also generates
|
|
||||||
a function to free its types and it cannot distinguish between dynamically
|
|
||||||
or statically allocated strings
|
|
||||||
6. You have to include "qapi/qapi-commands-misc.h" in qemu-timer.c
|
|
||||||
|
|
||||||
Time to test the new command. Build qemu, run it as described in the "Testing"
|
Time to test the new command. Build QEMU, run it as described in the "Testing"
|
||||||
section and try this::
|
section and try this::
|
||||||
|
|
||||||
{ "execute": "query-alarm-clock" }
|
{ "execute": "query-option-rom" }
|
||||||
{
|
{
|
||||||
"return": {
|
"return": [
|
||||||
"next-deadline": 2368219,
|
{
|
||||||
"clock-name": "dynticks"
|
"filename": "kvmvapic.bin"
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
The HMP command
|
The HMP command
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Here's the HMP counterpart of the query-alarm-clock command::
|
Here's the HMP counterpart of the query-option-roms command::
|
||||||
|
|
||||||
void hmp_info_alarm_clock(Monitor *mon)
|
void hmp_info_option_roms(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
QemuAlarmClock *clock;
|
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
OptionRomInfoList *info_list, *tail;
|
||||||
|
OptionRomInfo *info;
|
||||||
|
|
||||||
clock = qmp_query_alarm_clock(&err);
|
info_list = qmp_query_option_roms(&err);
|
||||||
if (hmp_handle_error(mon, err)) {
|
if (hmp_handle_error(mon, err)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
monitor_printf(mon, "Alarm clock method in use: '%s'\n", clock->clock_name);
|
for (tail = info_list; tail; tail = tail->next) {
|
||||||
if (clock->has_next_deadline) {
|
info = tail->value;
|
||||||
monitor_printf(mon, "Next alarm will fire in %" PRId64 " nanoseconds\n",
|
monitor_printf(mon, "%s", info->filename);
|
||||||
clock->next_deadline);
|
if (info->has_bootindex) {
|
||||||
}
|
monitor_printf(mon, " %" PRId64, info->bootindex);
|
||||||
|
|
||||||
qapi_free_QemuAlarmClock(clock);
|
|
||||||
}
|
|
||||||
|
|
||||||
It's important to notice that hmp_info_alarm_clock() calls
|
|
||||||
qapi_free_QemuAlarmClock() to free the data returned by qmp_query_alarm_clock().
|
|
||||||
For user defined types, the 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 call returns a string, then you should g_free() to free it.
|
|
||||||
|
|
||||||
Also note that hmp_info_alarm_clock() performs error handling. That's not
|
|
||||||
strictly required if you're sure the QMP function doesn't return errors, but
|
|
||||||
it's good practice to always check for errors.
|
|
||||||
|
|
||||||
Another important detail is that HMP's "info" commands don't go into the
|
|
||||||
hmp-commands.hx. Instead, they go into the info_cmds[] table, which is defined
|
|
||||||
in the monitor/misc.c file. The entry for the "info alarmclock" follows::
|
|
||||||
|
|
||||||
{
|
|
||||||
.name = "alarmclock",
|
|
||||||
.args_type = "",
|
|
||||||
.params = "",
|
|
||||||
.help = "show information about the alarm clock",
|
|
||||||
.cmd = hmp_info_alarm_clock,
|
|
||||||
},
|
|
||||||
|
|
||||||
To test this, run qemu and type "info alarmclock" in the user monitor.
|
|
||||||
|
|
||||||
|
|
||||||
Returning Lists
|
|
||||||
~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
For this example, we're going to return all available methods for the timer
|
|
||||||
alarm, which is pretty much what the command-line option "-clock ?" does,
|
|
||||||
except that we're also going to inform which method is in use.
|
|
||||||
|
|
||||||
This first step is to define a new type::
|
|
||||||
|
|
||||||
##
|
|
||||||
# @TimerAlarmMethod
|
|
||||||
#
|
|
||||||
# Timer alarm method information.
|
|
||||||
#
|
|
||||||
# @method-name: The method's name.
|
|
||||||
#
|
|
||||||
# @current: true if this alarm method is currently in use, false otherwise
|
|
||||||
#
|
|
||||||
# Since: 1.0
|
|
||||||
##
|
|
||||||
{ 'type': 'TimerAlarmMethod',
|
|
||||||
'data': { 'method-name': 'str', 'current': 'bool' } }
|
|
||||||
|
|
||||||
The command will be called "query-alarm-methods", here is its schema
|
|
||||||
specification::
|
|
||||||
|
|
||||||
##
|
|
||||||
# @query-alarm-methods
|
|
||||||
#
|
|
||||||
# Returns information about available alarm methods.
|
|
||||||
#
|
|
||||||
# Returns: a list of @TimerAlarmMethod for each method
|
|
||||||
#
|
|
||||||
# Since: 1.0
|
|
||||||
##
|
|
||||||
{ 'command': 'query-alarm-methods', 'returns': ['TimerAlarmMethod'] }
|
|
||||||
|
|
||||||
Notice the syntax for returning lists "'returns': ['TimerAlarmMethod']", this
|
|
||||||
should be read as "returns a list of TimerAlarmMethod instances".
|
|
||||||
|
|
||||||
The C implementation follows::
|
|
||||||
|
|
||||||
TimerAlarmMethodList *qmp_query_alarm_methods(Error **errp)
|
|
||||||
{
|
|
||||||
TimerAlarmMethodList *method_list = NULL;
|
|
||||||
const struct qemu_alarm_timer *p;
|
|
||||||
bool current = true;
|
|
||||||
|
|
||||||
for (p = alarm_timers; p->name; p++) {
|
|
||||||
TimerAlarmMethod *value = g_malloc0(*value);
|
|
||||||
value->method_name = g_strdup(p->name);
|
|
||||||
value->current = current;
|
|
||||||
QAPI_LIST_PREPEND(method_list, value);
|
|
||||||
current = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return method_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
The most important difference from the previous examples is the
|
|
||||||
TimerAlarmMethodList type, which is automatically generated by the QAPI from
|
|
||||||
the TimerAlarmMethod type.
|
|
||||||
|
|
||||||
Each list node is represented by a TimerAlarmMethodList instance. We have to
|
|
||||||
allocate it, and that's done inside the for loop: the "info" pointer points to
|
|
||||||
an allocated node. We also have to allocate the node's contents, which is
|
|
||||||
stored in its "value" member. In our example, the "value" member is a pointer
|
|
||||||
to an TimerAlarmMethod instance.
|
|
||||||
|
|
||||||
Notice that the "current" variable is used as "true" only in the first
|
|
||||||
iteration of the loop. That's because the alarm timer method in use is the
|
|
||||||
first element of the alarm_timers array. Also notice that QAPI lists are handled
|
|
||||||
by hand and we return the head of the list.
|
|
||||||
|
|
||||||
Now Build qemu, run it as explained in the "Testing" section and try our new
|
|
||||||
command::
|
|
||||||
|
|
||||||
{ "execute": "query-alarm-methods" }
|
|
||||||
{
|
|
||||||
"return": [
|
|
||||||
{
|
|
||||||
"current": false,
|
|
||||||
"method-name": "unix"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"current": true,
|
|
||||||
"method-name": "dynticks"
|
|
||||||
}
|
}
|
||||||
]
|
monitor_printf(mon, "\n");
|
||||||
}
|
|
||||||
|
|
||||||
The HMP counterpart is a bit more complex than previous examples because it
|
|
||||||
has to traverse the list, it's shown below for reference::
|
|
||||||
|
|
||||||
void hmp_info_alarm_methods(Monitor *mon)
|
|
||||||
{
|
|
||||||
TimerAlarmMethodList *method_list, *method;
|
|
||||||
Error *err = NULL;
|
|
||||||
|
|
||||||
method_list = qmp_query_alarm_methods(&err);
|
|
||||||
if (hmp_handle_error(mon, err)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (method = method_list; method; method = method->next) {
|
qapi_free_OptionRomInfoList(info_list);
|
||||||
monitor_printf(mon, "%c %s\n", method->value->current ? '*' : ' ',
|
|
||||||
method->value->method_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
qapi_free_TimerAlarmMethodList(method_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
|
Writing a debugging aid returning unstructured text
|
||||||
---------------------------------------------------
|
---------------------------------------------------
|
||||||
|
|
||||||
As discussed in section `Modelling data in QAPI`_, it is required that
|
As discussed in section `Modelling data in QAPI`_, it is required that
|
||||||
commands expecting machine usage be using fine-grained QAPI data types.
|
commands expecting machine usage be using fine-grained QAPI data types.
|
||||||
The exception to this rule applies when the command is solely intended
|
The exception to this rule applies when the command is solely intended
|
||||||
as a debugging aid and allows for returning unstructured text. This is
|
as a debugging aid and allows for returning unstructured text, such as
|
||||||
commonly needed for query commands that report aspects of QEMU's
|
a query command that report aspects of QEMU's internal state that are
|
||||||
internal state that are useful to human operators.
|
useful only to human operators.
|
||||||
|
|
||||||
In this example we will consider a simplified variant of the HMP
|
In this example we will consider the existing QMP command
|
||||||
command ``info roms``. Following the earlier rules, this command will
|
``x-query-roms`` in qapi/machine.json. It has no parameters and
|
||||||
need to live under the ``x-`` name prefix, so its QMP implementation
|
returns a ``HumanReadableText``::
|
||||||
will be called ``x-query-roms``. It will have no parameters and will
|
|
||||||
return a single text string::
|
|
||||||
|
|
||||||
{ 'struct': 'HumanReadableText',
|
|
||||||
'data': { 'human-readable-text': 'str' } }
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# @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',
|
{ 'command': 'x-query-roms',
|
||||||
'returns': 'HumanReadableText' }
|
'returns': 'HumanReadableText',
|
||||||
|
'features': [ 'unstable' ] }
|
||||||
|
|
||||||
The ``HumanReadableText`` struct is intended to be used for all
|
The ``HumanReadableText`` struct is defined in qapi/common.json as a
|
||||||
commands, under the ``x-`` name prefix that are returning unstructured
|
struct with a string member. It is intended to be used for all
|
||||||
text targeted at humans. It should never be used for commands outside
|
commands that are returning unstructured text targeted at
|
||||||
the ``x-`` name prefix, as those should be using structured QAPI types.
|
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
|
Implementing the QMP command
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The QMP implementation will typically involve creating a ``GString``
|
The QMP implementation will typically involve creating a ``GString``
|
||||||
object and printing formatted data into it::
|
object and printing formatted data into it, like this::
|
||||||
|
|
||||||
HumanReadableText *qmp_x_query_roms(Error **errp)
|
HumanReadableText *qmp_x_query_roms(Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -698,6 +593,9 @@ object and printing formatted data into it::
|
||||||
return human_readable_text_from_str(buf);
|
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
|
Implementing the HMP command
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -706,7 +604,7 @@ 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
|
the human monitor (HMP) as shown in previous examples. The HMP
|
||||||
implementations will all look fairly similar, as all they need do is
|
implementations will all look fairly similar, as all they need do is
|
||||||
invoke the QMP command and then print the resulting text or error
|
invoke the QMP command and then print the resulting text or error
|
||||||
message. Here's the implementation of the "info roms" HMP command::
|
message. Here's an implementation of the "info roms" HMP command::
|
||||||
|
|
||||||
void hmp_info_roms(Monitor *mon, const QDict *qdict)
|
void hmp_info_roms(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
|
@ -746,3 +644,5 @@ field NULL::
|
||||||
.help = "show roms",
|
.help = "show roms",
|
||||||
.cmd_info_hrt = qmp_x_query_roms,
|
.cmd_info_hrt = qmp_x_query_roms,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
This is how the actual HMP command is done.
|
||||||
|
|
|
@ -12,3 +12,11 @@
|
||||||
#include "qapi/qapi-types-common.h"
|
#include "qapi/qapi-types-common.h"
|
||||||
|
|
||||||
HumanReadableText *human_readable_text_from_str(GString *str);
|
HumanReadableText *human_readable_text_from_str(GString *str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Produce and return a NULL-terminated array of strings from @list.
|
||||||
|
* The result is g_malloc()'d and all strings are g_strdup()'d. It
|
||||||
|
* can be freed with g_strfreev(), or by g_auto(GStrv) automatic
|
||||||
|
* cleanup.
|
||||||
|
*/
|
||||||
|
char **strv_from_str_list(const strList *list);
|
||||||
|
|
|
@ -56,4 +56,17 @@ int parse_qapi_name(const char *name, bool complete);
|
||||||
(tail) = &(*(tail))->next; \
|
(tail) = &(*(tail))->next; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For any GenericList @list, return its length.
|
||||||
|
*/
|
||||||
|
#define QAPI_LIST_LENGTH(list) \
|
||||||
|
({ \
|
||||||
|
size_t _len = 0; \
|
||||||
|
typeof(list) _tail; \
|
||||||
|
for (_tail = list; _tail != NULL; _tail = _tail->next) { \
|
||||||
|
_len++; \
|
||||||
|
} \
|
||||||
|
_len; \
|
||||||
|
})
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qapi/type-helpers.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
#include "exec.h"
|
#include "exec.h"
|
||||||
|
@ -39,51 +40,16 @@ const char *exec_get_cmd_path(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* provides the length of strList */
|
|
||||||
static int
|
|
||||||
str_list_length(strList *list)
|
|
||||||
{
|
|
||||||
int len = 0;
|
|
||||||
strList *elem;
|
|
||||||
|
|
||||||
for (elem = list; elem != NULL; elem = elem->next) {
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
init_exec_array(strList *command, char **argv, Error **errp)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
strList *lst;
|
|
||||||
|
|
||||||
for (lst = command; lst; lst = lst->next) {
|
|
||||||
argv[i++] = lst->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv[i] = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void exec_start_outgoing_migration(MigrationState *s, strList *command,
|
void exec_start_outgoing_migration(MigrationState *s, strList *command,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
QIOChannel *ioc;
|
QIOChannel *ioc = NULL;
|
||||||
|
g_auto(GStrv) argv = strv_from_str_list(command);
|
||||||
int length = str_list_length(command);
|
const char * const *args = (const char * const *) argv;
|
||||||
g_auto(GStrv) argv = (char **) g_new0(const char *, length + 1);
|
|
||||||
|
|
||||||
init_exec_array(command, argv, errp);
|
|
||||||
g_autofree char *new_command = g_strjoinv(" ", (char **)argv);
|
g_autofree char *new_command = g_strjoinv(" ", (char **)argv);
|
||||||
|
|
||||||
trace_migration_exec_outgoing(new_command);
|
trace_migration_exec_outgoing(new_command);
|
||||||
ioc = QIO_CHANNEL(
|
ioc = QIO_CHANNEL(qio_channel_command_new_spawn(args, O_RDWR, errp));
|
||||||
qio_channel_command_new_spawn(
|
|
||||||
(const char * const *) g_steal_pointer(&argv),
|
|
||||||
O_RDWR,
|
|
||||||
errp));
|
|
||||||
if (!ioc) {
|
if (!ioc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -105,19 +71,12 @@ static gboolean exec_accept_incoming_migration(QIOChannel *ioc,
|
||||||
void exec_start_incoming_migration(strList *command, Error **errp)
|
void exec_start_incoming_migration(strList *command, Error **errp)
|
||||||
{
|
{
|
||||||
QIOChannel *ioc;
|
QIOChannel *ioc;
|
||||||
|
g_auto(GStrv) argv = strv_from_str_list(command);
|
||||||
int length = str_list_length(command);
|
const char * const *args = (const char * const *) argv;
|
||||||
g_auto(GStrv) argv = (char **) g_new0(const char *, length + 1);
|
|
||||||
|
|
||||||
init_exec_array(command, argv, errp);
|
|
||||||
g_autofree char *new_command = g_strjoinv(" ", (char **)argv);
|
g_autofree char *new_command = g_strjoinv(" ", (char **)argv);
|
||||||
|
|
||||||
trace_migration_exec_incoming(new_command);
|
trace_migration_exec_incoming(new_command);
|
||||||
ioc = QIO_CHANNEL(
|
ioc = QIO_CHANNEL(qio_channel_command_new_spawn(args, O_RDWR, errp));
|
||||||
qio_channel_command_new_spawn(
|
|
||||||
(const char * const *) g_steal_pointer(&argv),
|
|
||||||
O_RDWR,
|
|
||||||
errp));
|
|
||||||
if (!ioc) {
|
if (!ioc) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1456,8 +1456,7 @@
|
||||||
#
|
#
|
||||||
# @size: new image size in bytes
|
# @size: new image size in bytes
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @device is not a valid block device, DeviceNotFound
|
# - If @device is not a valid block device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
|
@ -1674,8 +1673,7 @@
|
||||||
#
|
#
|
||||||
# For the arguments, see the documentation of BlockdevSnapshotSync.
|
# For the arguments, see the documentation of BlockdevSnapshotSync.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @device is not a valid block device, DeviceNotFound
|
# - If @device is not a valid block device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
|
@ -1754,8 +1752,7 @@
|
||||||
# is not validated, so care should be taken when specifying the
|
# is not validated, so care should be taken when specifying the
|
||||||
# string or the image chain may not be able to be reopened again.
|
# string or the image chain may not be able to be reopened again.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If "device" does not exist or cannot be determined,
|
# - If "device" does not exist or cannot be determined,
|
||||||
# DeviceNotFound
|
# DeviceNotFound
|
||||||
#
|
#
|
||||||
|
@ -1854,8 +1851,7 @@
|
||||||
# @deprecated: Members @base and @top are deprecated. Use @base-node
|
# @deprecated: Members @base and @top are deprecated. Use @base-node
|
||||||
# and @top-node instead.
|
# and @top-node instead.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @device does not exist, DeviceNotFound
|
# - If @device does not exist, DeviceNotFound
|
||||||
# - Any other error returns a GenericError.
|
# - Any other error returns a GenericError.
|
||||||
#
|
#
|
||||||
|
@ -1894,8 +1890,7 @@
|
||||||
# @deprecated: This command is deprecated. Use @blockdev-backup
|
# @deprecated: This command is deprecated. Use @blockdev-backup
|
||||||
# instead.
|
# instead.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @device is not a valid block device, GenericError
|
# - If @device is not a valid block device, GenericError
|
||||||
#
|
#
|
||||||
# Since: 1.6
|
# Since: 1.6
|
||||||
|
@ -1921,8 +1916,7 @@
|
||||||
# 'backup'. The operation can be stopped before it has completed using
|
# 'backup'. The operation can be stopped before it has completed using
|
||||||
# the block-job-cancel command.
|
# the block-job-cancel command.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @device is not a valid block device, DeviceNotFound
|
# - If @device is not a valid block device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 2.3
|
# Since: 2.3
|
||||||
|
@ -2127,8 +2121,7 @@
|
||||||
# specifies the format of the mirror image, default is to probe if
|
# specifies the format of the mirror image, default is to probe if
|
||||||
# mode='existing', else the format of the source.
|
# mode='existing', else the format of the source.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @device is not a valid block device, GenericError
|
# - If @device is not a valid block device, GenericError
|
||||||
#
|
#
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
|
@ -2304,8 +2297,7 @@
|
||||||
# Create a dirty bitmap with a name on the node, and start tracking
|
# Create a dirty bitmap with a name on the node, and start tracking
|
||||||
# the writes.
|
# the writes.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @node is not a valid block device or node, DeviceNotFound
|
# - If @node is not a valid block device or node, DeviceNotFound
|
||||||
# - If @name is already taken, GenericError with an explanation
|
# - If @name is already taken, GenericError with an explanation
|
||||||
#
|
#
|
||||||
|
@ -2328,8 +2320,7 @@
|
||||||
# with block-dirty-bitmap-add. If the bitmap is persistent, remove it
|
# with block-dirty-bitmap-add. If the bitmap is persistent, remove it
|
||||||
# from its storage too.
|
# from its storage too.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @node is not a valid block device or node, DeviceNotFound
|
# - If @node is not a valid block device or node, DeviceNotFound
|
||||||
# - If @name is not found, GenericError with an explanation
|
# - If @name is not found, GenericError with an explanation
|
||||||
# - if @name is frozen by an operation, GenericError
|
# - if @name is frozen by an operation, GenericError
|
||||||
|
@ -2353,8 +2344,7 @@
|
||||||
# backup from this point in time forward will only backup clusters
|
# backup from this point in time forward will only backup clusters
|
||||||
# modified after this clear operation.
|
# modified after this clear operation.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @node is not a valid block device, DeviceNotFound
|
# - If @node is not a valid block device, DeviceNotFound
|
||||||
# - If @name is not found, GenericError with an explanation
|
# - If @name is not found, GenericError with an explanation
|
||||||
#
|
#
|
||||||
|
@ -2375,8 +2365,7 @@
|
||||||
#
|
#
|
||||||
# Enables a dirty bitmap so that it will begin tracking disk changes.
|
# Enables a dirty bitmap so that it will begin tracking disk changes.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @node is not a valid block device, DeviceNotFound
|
# - If @node is not a valid block device, DeviceNotFound
|
||||||
# - If @name is not found, GenericError with an explanation
|
# - If @name is not found, GenericError with an explanation
|
||||||
#
|
#
|
||||||
|
@ -2397,8 +2386,7 @@
|
||||||
#
|
#
|
||||||
# Disables a dirty bitmap so that it will stop tracking disk changes.
|
# Disables a dirty bitmap so that it will stop tracking disk changes.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @node is not a valid block device, DeviceNotFound
|
# - If @node is not a valid block device, DeviceNotFound
|
||||||
# - If @name is not found, GenericError with an explanation
|
# - If @name is not found, GenericError with an explanation
|
||||||
#
|
#
|
||||||
|
@ -2427,8 +2415,7 @@
|
||||||
# dirty in any of the source bitmaps. This can be used to achieve
|
# dirty in any of the source bitmaps. This can be used to achieve
|
||||||
# backup checkpoints, or in simpler usages, to copy bitmaps.
|
# backup checkpoints, or in simpler usages, to copy bitmaps.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @node is not a valid block device, DeviceNotFound
|
# - If @node is not a valid block device, DeviceNotFound
|
||||||
# - If any bitmap in @bitmaps or @target is not found,
|
# - If any bitmap in @bitmaps or @target is not found,
|
||||||
# GenericError
|
# GenericError
|
||||||
|
@ -2470,7 +2457,9 @@
|
||||||
# @unstable: This command is meant for debugging.
|
# @unstable: This command is meant for debugging.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Returns:
|
||||||
# - BlockDirtyBitmapSha256 on success
|
# BlockDirtyBitmapSha256
|
||||||
|
#
|
||||||
|
# Errors:
|
||||||
# - If @node is not a valid block device, DeviceNotFound
|
# - If @node is not a valid block device, DeviceNotFound
|
||||||
# - If @name is not found or if hashing has failed, GenericError
|
# - If @name is not found or if hashing has failed, GenericError
|
||||||
# with an explanation
|
# with an explanation
|
||||||
|
@ -2542,8 +2531,6 @@
|
||||||
# disappear from the query list without user intervention.
|
# disappear from the query list without user intervention.
|
||||||
# Defaults to true. (Since 3.1)
|
# Defaults to true. (Since 3.1)
|
||||||
#
|
#
|
||||||
# Returns: nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 2.6
|
# Since: 2.6
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -2866,8 +2853,7 @@
|
||||||
# disappear from the query list without user intervention.
|
# disappear from the query list without user intervention.
|
||||||
# Defaults to true. (Since 3.1)
|
# Defaults to true. (Since 3.1)
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success.
|
|
||||||
# - If @device does not exist, DeviceNotFound.
|
# - If @device does not exist, DeviceNotFound.
|
||||||
#
|
#
|
||||||
# Since: 1.1
|
# Since: 1.1
|
||||||
|
@ -2905,8 +2891,7 @@
|
||||||
# @speed: the maximum speed, in bytes per second, or 0 for unlimited.
|
# @speed: the maximum speed, in bytes per second, or 0 for unlimited.
|
||||||
# Defaults to 0.
|
# Defaults to 0.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If no background operation is active on this device,
|
# - If no background operation is active on this device,
|
||||||
# DeviceNotActive
|
# DeviceNotActive
|
||||||
#
|
#
|
||||||
|
@ -2950,8 +2935,7 @@
|
||||||
# paused) instead of waiting for the destination to complete its
|
# paused) instead of waiting for the destination to complete its
|
||||||
# final synchronization (since 1.3)
|
# final synchronization (since 1.3)
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If no background operation is active on this device,
|
# - If no background operation is active on this device,
|
||||||
# DeviceNotActive
|
# DeviceNotActive
|
||||||
#
|
#
|
||||||
|
@ -2977,8 +2961,7 @@
|
||||||
# the name of the parameter), but since QEMU 2.7 it can have other
|
# the name of the parameter), but since QEMU 2.7 it can have other
|
||||||
# values.
|
# values.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If no background operation is active on this device,
|
# - If no background operation is active on this device,
|
||||||
# DeviceNotActive
|
# DeviceNotActive
|
||||||
#
|
#
|
||||||
|
@ -3002,8 +2985,7 @@
|
||||||
# the name of the parameter), but since QEMU 2.7 it can have other
|
# the name of the parameter), but since QEMU 2.7 it can have other
|
||||||
# values.
|
# values.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If no background operation is active on this device,
|
# - If no background operation is active on this device,
|
||||||
# DeviceNotActive
|
# DeviceNotActive
|
||||||
#
|
#
|
||||||
|
@ -3034,8 +3016,7 @@
|
||||||
# the name of the parameter), but since QEMU 2.7 it can have other
|
# the name of the parameter), but since QEMU 2.7 it can have other
|
||||||
# values.
|
# values.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If no background operation is active on this device,
|
# - If no background operation is active on this device,
|
||||||
# DeviceNotActive
|
# DeviceNotActive
|
||||||
#
|
#
|
||||||
|
@ -3059,8 +3040,6 @@
|
||||||
#
|
#
|
||||||
# @id: The job identifier.
|
# @id: The job identifier.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 2.12
|
# Since: 2.12
|
||||||
##
|
##
|
||||||
{ 'command': 'block-job-dismiss', 'data': { 'id': 'str' },
|
{ 'command': 'block-job-dismiss', 'data': { 'id': 'str' },
|
||||||
|
@ -3078,8 +3057,6 @@
|
||||||
#
|
#
|
||||||
# @id: The job identifier.
|
# @id: The job identifier.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 2.12
|
# Since: 2.12
|
||||||
##
|
##
|
||||||
{ 'command': 'block-job-finalize', 'data': { 'id': 'str' },
|
{ 'command': 'block-job-finalize', 'data': { 'id': 'str' },
|
||||||
|
@ -6070,8 +6047,7 @@
|
||||||
# For the arguments, see the documentation of
|
# For the arguments, see the documentation of
|
||||||
# BlockdevSnapshotInternal.
|
# BlockdevSnapshotInternal.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - nothing on success
|
|
||||||
# - If @device is not a valid block device, GenericError
|
# - If @device is not a valid block device, GenericError
|
||||||
# - If any snapshot matching @name exists, or @name is empty,
|
# - If any snapshot matching @name exists, or @name is empty,
|
||||||
# GenericError
|
# GenericError
|
||||||
|
@ -6108,7 +6084,9 @@
|
||||||
# @name: optional the snapshot's name to be deleted
|
# @name: optional the snapshot's name to be deleted
|
||||||
#
|
#
|
||||||
# Returns:
|
# Returns:
|
||||||
# - SnapshotInfo on success
|
# SnapshotInfo
|
||||||
|
#
|
||||||
|
# Errors:
|
||||||
# - If @device is not a valid block device, GenericError
|
# - If @device is not a valid block device, GenericError
|
||||||
# - If snapshot not found, GenericError
|
# - If snapshot not found, GenericError
|
||||||
# - If the format of the image used does not support it,
|
# - If the format of the image used does not support it,
|
||||||
|
|
|
@ -65,7 +65,8 @@
|
||||||
# server from advertising multiple client support (since 5.2;
|
# server from advertising multiple client support (since 5.2;
|
||||||
# default: 0).
|
# default: 0).
|
||||||
#
|
#
|
||||||
# Returns: error if the server is already running.
|
# Errors:
|
||||||
|
# - if the server is already running
|
||||||
#
|
#
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
##
|
##
|
||||||
|
@ -247,8 +248,9 @@
|
||||||
# @deprecated: This command is deprecated. Use @block-export-add
|
# @deprecated: This command is deprecated. Use @block-export-add
|
||||||
# instead.
|
# instead.
|
||||||
#
|
#
|
||||||
# Returns: error if the server is not running, or export with the same
|
# Errors:
|
||||||
# name already exists.
|
# - if the server is not running
|
||||||
|
# - if an export with the same name already exists
|
||||||
#
|
#
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
##
|
##
|
||||||
|
@ -294,11 +296,10 @@
|
||||||
# @deprecated: This command is deprecated. Use @block-export-del
|
# @deprecated: This command is deprecated. Use @block-export-del
|
||||||
# instead.
|
# instead.
|
||||||
#
|
#
|
||||||
# Returns: error if
|
# Errors:
|
||||||
#
|
# - if the server is not running
|
||||||
# - the server is not running
|
# - if export is not found
|
||||||
# - export is not found
|
# - if mode is 'safe' and there are existing connections
|
||||||
# - mode is 'safe' and there are existing connections
|
|
||||||
#
|
#
|
||||||
# Since: 2.12
|
# Since: 2.12
|
||||||
##
|
##
|
||||||
|
@ -415,8 +416,10 @@
|
||||||
# @mode: Mode of command operation. See @BlockExportRemoveMode
|
# @mode: Mode of command operation. See @BlockExportRemoveMode
|
||||||
# description. Default is 'safe'.
|
# description. Default is 'safe'.
|
||||||
#
|
#
|
||||||
# Returns: Error if the export is not found or @mode is 'safe' and the
|
# Errors:
|
||||||
# export is still in use (e.g. by existing client connections)
|
# - if the export is not found
|
||||||
|
# - if @mode is 'safe' and the export is still in use (e.g. by
|
||||||
|
# existing client connections)
|
||||||
#
|
#
|
||||||
# Since: 5.2
|
# Since: 5.2
|
||||||
##
|
##
|
||||||
|
|
|
@ -110,8 +110,7 @@
|
||||||
#
|
#
|
||||||
# @deprecated: Member @device is deprecated. Use @id instead.
|
# @deprecated: Member @device is deprecated. Use @id instead.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @device is not a valid block device, DeviceNotFound
|
# - If @device is not a valid block device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Notes: Ejecting a device with no media results in success
|
# Notes: Ejecting a device with no media results in success
|
||||||
|
@ -459,8 +458,7 @@
|
||||||
# the device will be removed from its group and the rest of its
|
# the device will be removed from its group and the rest of its
|
||||||
# members will not be affected. The 'group' parameter is ignored.
|
# members will not be affected. The 'group' parameter is ignored.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @device is not a valid block device, DeviceNotFound
|
# - If @device is not a valid block device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 1.1
|
# Since: 1.1
|
||||||
|
@ -540,8 +538,8 @@
|
||||||
# @boundaries-flush: list of interval boundary values for flush
|
# @boundaries-flush: list of interval boundary values for flush
|
||||||
# latency histogram.
|
# latency histogram.
|
||||||
#
|
#
|
||||||
# Returns: error if device is not found or any boundary arrays are
|
# Errors:
|
||||||
# invalid.
|
# - if device is not found or any boundary arrays are invalid.
|
||||||
#
|
#
|
||||||
# Since: 4.0
|
# Since: 4.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -139,8 +139,6 @@
|
||||||
# - data itself is always Unicode regardless of format, like any
|
# - data itself is always Unicode regardless of format, like any
|
||||||
# other string.
|
# other string.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 1.4
|
# Since: 1.4
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -772,8 +770,6 @@
|
||||||
#
|
#
|
||||||
# @id: the chardev's ID, must exist and not be in use
|
# @id: the chardev's ID, must exist and not be in use
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 1.4
|
# Since: 1.4
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -791,8 +787,6 @@
|
||||||
#
|
#
|
||||||
# @id: the chardev's ID, must exist
|
# @id: the chardev's ID, must exist
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 2.10
|
# Since: 2.10
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -92,8 +92,6 @@
|
||||||
#
|
#
|
||||||
# Note: All boolean arguments default to false
|
# Note: All boolean arguments default to false
|
||||||
#
|
#
|
||||||
# Returns: nothing on success
|
|
||||||
#
|
|
||||||
# Since: 1.2
|
# Since: 1.2
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -154,10 +154,13 @@
|
||||||
# Some architectures may not support comparing CPU models. s390x
|
# Some architectures may not support comparing CPU models. s390x
|
||||||
# supports comparing CPU models.
|
# supports comparing CPU models.
|
||||||
#
|
#
|
||||||
# Returns: a CpuModelBaselineInfo. Returns an error if comparing CPU
|
# Returns: a CpuModelBaselineInfo
|
||||||
# models is not supported, if a model cannot be used, if a model
|
#
|
||||||
# contains an unknown cpu definition name, unknown properties or
|
# Errors:
|
||||||
# properties with wrong types.
|
# - if comparing CPU models is not supported
|
||||||
|
# - if a model cannot be used
|
||||||
|
# - if a model contains an unknown cpu definition name, unknown
|
||||||
|
# properties or properties with wrong types.
|
||||||
#
|
#
|
||||||
# Note: this command isn't specific to s390x, but is only implemented
|
# Note: this command isn't specific to s390x, but is only implemented
|
||||||
# on this architecture currently.
|
# on this architecture currently.
|
||||||
|
@ -201,10 +204,13 @@
|
||||||
# Some architectures may not support baselining CPU models. s390x
|
# Some architectures may not support baselining CPU models. s390x
|
||||||
# supports baselining CPU models.
|
# supports baselining CPU models.
|
||||||
#
|
#
|
||||||
# Returns: a CpuModelBaselineInfo. Returns an error if baselining CPU
|
# Returns: a CpuModelBaselineInfo
|
||||||
# models is not supported, if a model cannot be used, if a model
|
#
|
||||||
# contains an unknown cpu definition name, unknown properties or
|
# Errors:
|
||||||
# properties with wrong types.
|
# - if baselining CPU models is not supported
|
||||||
|
# - if a model cannot be used
|
||||||
|
# - if a model contains an unknown cpu definition name, unknown
|
||||||
|
# properties or properties with wrong types.
|
||||||
#
|
#
|
||||||
# Note: this command isn't specific to s390x, but is only implemented
|
# Note: this command isn't specific to s390x, but is only implemented
|
||||||
# on this architecture currently.
|
# on this architecture currently.
|
||||||
|
@ -263,11 +269,14 @@
|
||||||
# Some architectures may not support all expansion types. s390x
|
# Some architectures may not support all expansion types. s390x
|
||||||
# supports "full" and "static". Arm only supports "full".
|
# supports "full" and "static". Arm only supports "full".
|
||||||
#
|
#
|
||||||
# Returns: a CpuModelExpansionInfo. Returns an error if expanding CPU
|
# Returns: a CpuModelExpansionInfo
|
||||||
# models is not supported, if the model cannot be expanded, if the
|
#
|
||||||
# model contains an unknown CPU definition name, unknown
|
# Errors:
|
||||||
# properties or properties with a wrong type. Also returns an
|
# - if expanding CPU models is not supported
|
||||||
# error if an expansion type is not supported.
|
# - if the model cannot be expanded
|
||||||
|
# - if the model contains an unknown CPU definition name, unknown
|
||||||
|
# properties or properties with a wrong type
|
||||||
|
# - if an expansion type is not supported
|
||||||
#
|
#
|
||||||
# Since: 2.8
|
# Since: 2.8
|
||||||
##
|
##
|
||||||
|
@ -405,8 +414,6 @@
|
||||||
#
|
#
|
||||||
# @unstable: This command is experimental.
|
# @unstable: This command is experimental.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 8.2
|
# Since: 8.2
|
||||||
##
|
##
|
||||||
{ 'command': 'set-cpu-topology',
|
{ 'command': 'set-cpu-topology',
|
||||||
|
|
|
@ -326,8 +326,6 @@
|
||||||
#
|
#
|
||||||
# Since: 1.1
|
# Since: 1.1
|
||||||
#
|
#
|
||||||
# Returns: nothing.
|
|
||||||
#
|
|
||||||
# Note: prior to 4.0, this command does nothing in case the guest
|
# Note: prior to 4.0, this command does nothing in case the guest
|
||||||
# isn't suspended.
|
# isn't suspended.
|
||||||
#
|
#
|
||||||
|
@ -377,8 +375,6 @@
|
||||||
# all CPUs (ppc64). The command fails when the guest doesn't support
|
# all CPUs (ppc64). The command fails when the guest doesn't support
|
||||||
# injecting.
|
# injecting.
|
||||||
#
|
#
|
||||||
# Returns: If successful, nothing
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Note: prior to 2.1, this command was only supported for x86 and s390
|
# Note: prior to 2.1, this command was only supported for x86 and s390
|
||||||
|
@ -778,8 +774,6 @@
|
||||||
# @cpu-index: the index of the virtual CPU to use for translating the
|
# @cpu-index: the index of the virtual CPU to use for translating the
|
||||||
# virtual address (defaults to CPU 0)
|
# virtual address (defaults to CPU 0)
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Notes: Errors were not reliably returned until 1.1
|
# Notes: Errors were not reliably returned until 1.1
|
||||||
|
@ -806,8 +800,6 @@
|
||||||
#
|
#
|
||||||
# @filename: the file to save the memory to as binary data
|
# @filename: the file to save the memory to as binary data
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Notes: Errors were not reliably returned until 1.1
|
# Notes: Errors were not reliably returned until 1.1
|
||||||
|
@ -1060,8 +1052,7 @@
|
||||||
#
|
#
|
||||||
# From it we have: balloon_size = vm_ram_size - @value
|
# From it we have: balloon_size = vm_ram_size - @value
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If the balloon driver is enabled but not functional because
|
# - If the balloon driver is enabled but not functional because
|
||||||
# the KVM kernel module cannot support it, KVMMissingCap
|
# the KVM kernel module cannot support it, KVMMissingCap
|
||||||
# - If no balloon device is present, DeviceNotActive
|
# - If no balloon device is present, DeviceNotActive
|
||||||
|
@ -1099,7 +1090,9 @@
|
||||||
# Return information about the balloon device.
|
# Return information about the balloon device.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Returns:
|
||||||
# - @BalloonInfo on success
|
# @BalloonInfo
|
||||||
|
#
|
||||||
|
# Errors:
|
||||||
# - If the balloon driver is enabled but not functional because
|
# - If the balloon driver is enabled but not functional because
|
||||||
# the KVM kernel module cannot support it, KVMMissingCap
|
# the KVM kernel module cannot support it, KVMMissingCap
|
||||||
# - If no balloon device is present, DeviceNotActive
|
# - If no balloon device is present, DeviceNotActive
|
||||||
|
@ -1163,7 +1156,9 @@
|
||||||
# message from the guest.
|
# message from the guest.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Returns:
|
||||||
# - @HvBalloonInfo on success
|
# @HvBalloonInfo
|
||||||
|
#
|
||||||
|
# Errors:
|
||||||
# - If no hv-balloon device is present, guest memory status
|
# - If no hv-balloon device is present, guest memory status
|
||||||
# reporting is not enabled or no guest memory status report
|
# reporting is not enabled or no guest memory status report
|
||||||
# received yet, GenericError
|
# received yet, GenericError
|
||||||
|
|
|
@ -1572,8 +1572,6 @@
|
||||||
#
|
#
|
||||||
# Cancel the current executing migration process.
|
# Cancel the current executing migration process.
|
||||||
#
|
#
|
||||||
# Returns: nothing on success
|
|
||||||
#
|
|
||||||
# Notes: This command succeeds even if there is no migration process
|
# Notes: This command succeeds even if there is no migration process
|
||||||
# running.
|
# running.
|
||||||
#
|
#
|
||||||
|
@ -1593,8 +1591,6 @@
|
||||||
#
|
#
|
||||||
# @state: The state the migration is currently expected to be in
|
# @state: The state the migration is currently expected to be in
|
||||||
#
|
#
|
||||||
# Returns: nothing on success
|
|
||||||
#
|
|
||||||
# Since: 2.11
|
# Since: 2.11
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -1716,8 +1712,6 @@
|
||||||
# @deprecated: Members @inc and @blk are deprecated. Use
|
# @deprecated: Members @inc and @blk are deprecated. Use
|
||||||
# blockdev-mirror with NBD instead.
|
# blockdev-mirror with NBD instead.
|
||||||
#
|
#
|
||||||
# Returns: nothing on success
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
|
@ -1799,8 +1793,6 @@
|
||||||
# @channels: list of migration stream channels with each stream in the
|
# @channels: list of migration stream channels with each stream in the
|
||||||
# list connected to a destination interface endpoint.
|
# list connected to a destination interface endpoint.
|
||||||
#
|
#
|
||||||
# Returns: nothing on success
|
|
||||||
#
|
|
||||||
# Since: 2.3
|
# Since: 2.3
|
||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
|
@ -1868,8 +1860,6 @@
|
||||||
# @live: Optional argument to ask QEMU to treat this command as part
|
# @live: Optional argument to ask QEMU to treat this command as part
|
||||||
# of a live migration. Default to true. (since 2.11)
|
# of a live migration. Default to true. (since 2.11)
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 1.1
|
# Since: 1.1
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -1888,8 +1878,6 @@
|
||||||
#
|
#
|
||||||
# @enable: true to enable, false to disable.
|
# @enable: true to enable, false to disable.
|
||||||
#
|
#
|
||||||
# Returns: nothing
|
|
||||||
#
|
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -1932,8 +1920,6 @@
|
||||||
# @failover: true to do failover, false to stop. but cannot be
|
# @failover: true to do failover, false to stop. but cannot be
|
||||||
# specified if 'enable' is true. default value is false.
|
# specified if 'enable' is true. default value is false.
|
||||||
#
|
#
|
||||||
# Returns: nothing.
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "xen-set-replication",
|
# -> { "execute": "xen-set-replication",
|
||||||
|
@ -1985,8 +1971,6 @@
|
||||||
#
|
#
|
||||||
# Xen uses this command to notify replication to trigger a checkpoint.
|
# Xen uses this command to notify replication to trigger a checkpoint.
|
||||||
#
|
#
|
||||||
# Returns: nothing.
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "xen-colo-do-checkpoint" }
|
# -> { "execute": "xen-colo-do-checkpoint" }
|
||||||
|
@ -2043,8 +2027,6 @@
|
||||||
#
|
#
|
||||||
# @uri: the URI to be used for the recovery of migration stream.
|
# @uri: the URI to be used for the recovery of migration stream.
|
||||||
#
|
#
|
||||||
# Returns: nothing.
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "migrate-recover",
|
# -> { "execute": "migrate-recover",
|
||||||
|
@ -2062,8 +2044,6 @@
|
||||||
#
|
#
|
||||||
# Pause a migration. Currently it only supports postcopy.
|
# Pause a migration. Currently it only supports postcopy.
|
||||||
#
|
#
|
||||||
# Returns: nothing.
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "migrate-pause" }
|
# -> { "execute": "migrate-pause" }
|
||||||
|
@ -2432,8 +2412,6 @@
|
||||||
#
|
#
|
||||||
# If @tag already exists, an error will be reported
|
# If @tag already exists, an error will be reported
|
||||||
#
|
#
|
||||||
# Returns: nothing
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "snapshot-save",
|
# -> { "execute": "snapshot-save",
|
||||||
|
@ -2504,8 +2482,6 @@
|
||||||
# device nodes that can have changed since the original @snapshot-save
|
# device nodes that can have changed since the original @snapshot-save
|
||||||
# command execution.
|
# command execution.
|
||||||
#
|
#
|
||||||
# Returns: nothing
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "snapshot-load",
|
# -> { "execute": "snapshot-load",
|
||||||
|
@ -2567,8 +2543,6 @@
|
||||||
# to determine completion and to fetch details of any errors that
|
# to determine completion and to fetch details of any errors that
|
||||||
# arise.
|
# arise.
|
||||||
#
|
#
|
||||||
# Returns: nothing
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "snapshot-delete",
|
# -> { "execute": "snapshot-delete",
|
||||||
|
|
|
@ -472,9 +472,6 @@
|
||||||
#
|
#
|
||||||
# @port: The port number
|
# @port: The port number
|
||||||
#
|
#
|
||||||
# Returns:
|
|
||||||
# - Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 8.0
|
# Since: 8.0
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#
|
#
|
||||||
# @tls: whether to perform TLS. Only applies to the "spice" protocol
|
# @tls: whether to perform TLS. Only applies to the "spice" protocol
|
||||||
#
|
#
|
||||||
# Returns: nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -160,8 +158,6 @@
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Returns: If successful, nothing
|
|
||||||
#
|
|
||||||
# Notes: This command will succeed if the guest is currently running.
|
# Notes: This command will succeed if the guest is currently running.
|
||||||
# It will also succeed if the guest is in the "inmigrate" state;
|
# It will also succeed if the guest is in the "inmigrate" state;
|
||||||
# in this case, the effect of the command is to make sure the
|
# in this case, the effect of the command is to make sure the
|
||||||
|
@ -196,8 +192,6 @@
|
||||||
#
|
#
|
||||||
# Since: 3.0
|
# Since: 3.0
|
||||||
#
|
#
|
||||||
# Returns: nothing
|
|
||||||
#
|
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
# -> { "execute": "x-exit-preconfig" }
|
# -> { "execute": "x-exit-preconfig" }
|
||||||
|
@ -256,8 +250,6 @@
|
||||||
#
|
#
|
||||||
# @fdname: file descriptor name
|
# @fdname: file descriptor name
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Notes: If @fdname already exists, the file descriptor assigned to it
|
# Notes: If @fdname already exists, the file descriptor assigned to it
|
||||||
|
@ -285,8 +277,6 @@
|
||||||
#
|
#
|
||||||
# @fdname: file descriptor name
|
# @fdname: file descriptor name
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 8.0
|
# Since: 8.0
|
||||||
#
|
#
|
||||||
# Notes: If @fdname already exists, the file descriptor assigned to it
|
# Notes: If @fdname already exists, the file descriptor assigned to it
|
||||||
|
@ -309,8 +299,6 @@
|
||||||
#
|
#
|
||||||
# @fdname: file descriptor name
|
# @fdname: file descriptor name
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -344,7 +332,9 @@
|
||||||
# @opaque: A free-form string that can be used to describe the fd.
|
# @opaque: A free-form string that can be used to describe the fd.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Returns:
|
||||||
# - @AddfdInfo on success
|
# @AddfdInfo
|
||||||
|
#
|
||||||
|
# Errors:
|
||||||
# - If file descriptor was not received, GenericError
|
# - If file descriptor was not received, GenericError
|
||||||
# - If @fdset-id is a negative value, GenericError
|
# - If @fdset-id is a negative value, GenericError
|
||||||
#
|
#
|
||||||
|
@ -374,8 +364,7 @@
|
||||||
#
|
#
|
||||||
# @fd: The file descriptor that is to be removed.
|
# @fd: The file descriptor that is to be removed.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @fdset-id or @fd is not found, GenericError
|
# - If @fdset-id or @fd is not found, GenericError
|
||||||
#
|
#
|
||||||
# Since: 1.2
|
# Since: 1.2
|
||||||
|
@ -528,8 +517,10 @@
|
||||||
# @option: option name
|
# @option: option name
|
||||||
#
|
#
|
||||||
# Returns: list of @CommandLineOptionInfo for all options (or for the
|
# Returns: list of @CommandLineOptionInfo for all options (or for the
|
||||||
# given @option). Returns an error if the given @option doesn't
|
# given @option).
|
||||||
# exist.
|
#
|
||||||
|
# Errors:
|
||||||
|
# - if the given @option doesn't exist
|
||||||
#
|
#
|
||||||
# Since: 1.5
|
# Since: 1.5
|
||||||
#
|
#
|
||||||
|
|
|
@ -17,8 +17,7 @@
|
||||||
#
|
#
|
||||||
# @up: true to set the link status to be up
|
# @up: true to set the link status to be up
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @name is not a valid network device, DeviceNotFound
|
# - If @name is not a valid network device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
|
@ -44,8 +43,7 @@
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @type is not a valid network backend, DeviceNotFound
|
# - If @type is not a valid network backend, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -65,8 +63,7 @@
|
||||||
#
|
#
|
||||||
# @id: the name of the network backend to remove
|
# @id: the name of the network backend to remove
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @id is not a valid network backend, DeviceNotFound
|
# - If @id is not a valid network backend, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
|
@ -828,9 +825,11 @@
|
||||||
# @name: net client name
|
# @name: net client name
|
||||||
#
|
#
|
||||||
# Returns: list of @RxFilterInfo for all NICs (or for the given NIC).
|
# Returns: list of @RxFilterInfo for all NICs (or for the given NIC).
|
||||||
# Returns an error if the given @name doesn't exist, or given NIC
|
#
|
||||||
# doesn't support rx-filter querying, or given net client isn't a
|
# Errors:
|
||||||
# NIC.
|
# - if the given @name doesn't exist
|
||||||
|
# - if the given NIC doesn't support rx-filter querying
|
||||||
|
# - if the given net client isn't a NIC
|
||||||
#
|
#
|
||||||
# Since: 1.6
|
# Since: 1.6
|
||||||
#
|
#
|
||||||
|
|
|
@ -21,3 +21,17 @@ HumanReadableText *human_readable_text_from_str(GString *str)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char **strv_from_str_list(const strList *list)
|
||||||
|
{
|
||||||
|
const strList *tail;
|
||||||
|
int i = 0;
|
||||||
|
char **strv = g_new(char *, QAPI_LIST_LENGTH(list) + 1);
|
||||||
|
|
||||||
|
for (tail = list; tail != NULL; tail = tail->next) {
|
||||||
|
strv[i++] = g_strdup(tail->value);
|
||||||
|
}
|
||||||
|
strv[i] = NULL;
|
||||||
|
|
||||||
|
return strv;
|
||||||
|
}
|
||||||
|
|
|
@ -89,8 +89,7 @@
|
||||||
#
|
#
|
||||||
# @id: the device's ID or QOM path
|
# @id: the device's ID or QOM path
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @id is not a valid device, DeviceNotFound
|
# - If @id is not a valid device, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Notes: When this command completes, the device may not be removed
|
# Notes: When this command completes, the device may not be removed
|
||||||
|
|
|
@ -1056,8 +1056,7 @@
|
||||||
#
|
#
|
||||||
# Create a QOM object.
|
# Create a QOM object.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - Error if @qom-type is not a valid class name
|
# - Error if @qom-type is not a valid class name
|
||||||
#
|
#
|
||||||
# Since: 2.0
|
# Since: 2.0
|
||||||
|
@ -1079,8 +1078,7 @@
|
||||||
#
|
#
|
||||||
# @id: the name of the QOM object to remove
|
# @id: the name of the QOM object to remove
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - Error if @id is not a valid id for a QOM object
|
# - Error if @id is not a valid id for a QOM object
|
||||||
#
|
#
|
||||||
# Since: 2.0
|
# Since: 2.0
|
||||||
|
|
|
@ -395,10 +395,7 @@
|
||||||
#
|
#
|
||||||
# @panic: @PanicAction action taken on guest panic.
|
# @panic: @PanicAction action taken on guest panic.
|
||||||
#
|
#
|
||||||
# @watchdog: @WatchdogAction action taken when watchdog timer expires
|
# @watchdog: @WatchdogAction action taken when watchdog timer expires.
|
||||||
# .
|
|
||||||
#
|
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
#
|
||||||
# Since: 6.0
|
# Since: 6.0
|
||||||
#
|
#
|
||||||
|
|
|
@ -166,8 +166,6 @@
|
||||||
#
|
#
|
||||||
# Return information about the TPM device
|
# Return information about the TPM device
|
||||||
#
|
#
|
||||||
# Returns: @TPMInfo on success
|
|
||||||
#
|
|
||||||
# Since: 1.5
|
# Since: 1.5
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -234,9 +234,8 @@
|
||||||
# execution of the transaction. See @TransactionProperties for
|
# execution of the transaction. See @TransactionProperties for
|
||||||
# additional detail.
|
# additional detail.
|
||||||
#
|
#
|
||||||
# Returns: nothing on success
|
# Errors:
|
||||||
#
|
# Any errors from commands in the transaction
|
||||||
# Errors depend on the operations of the transaction
|
|
||||||
#
|
#
|
||||||
# Note: The transaction aborts on the first failure. Therefore, there
|
# Note: The transaction aborts on the first failure. Therefore, there
|
||||||
# will be information on only one failed operation returned in an
|
# will be information on only one failed operation returned in an
|
||||||
|
|
17
qapi/ui.json
17
qapi/ui.json
|
@ -78,8 +78,7 @@
|
||||||
#
|
#
|
||||||
# Set the password of a remote display server.
|
# Set the password of a remote display server.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If Spice is not enabled, DeviceNotFound
|
# - If Spice is not enabled, DeviceNotFound
|
||||||
#
|
#
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
|
@ -140,8 +139,7 @@
|
||||||
#
|
#
|
||||||
# Expire the password of a remote display server.
|
# Expire the password of a remote display server.
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If @protocol is 'spice' and Spice is not active,
|
# - If @protocol is 'spice' and Spice is not active,
|
||||||
# DeviceNotFound
|
# DeviceNotFound
|
||||||
#
|
#
|
||||||
|
@ -187,8 +185,6 @@
|
||||||
#
|
#
|
||||||
# @format: image format for screendump. (default: ppm) (Since 7.1)
|
# @format: image format for screendump. (default: ppm) (Since 7.1)
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success
|
|
||||||
#
|
|
||||||
# Since: 0.14
|
# Since: 0.14
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -1036,8 +1032,7 @@
|
||||||
# @hold-time: time to delay key up events, milliseconds. Defaults to
|
# @hold-time: time to delay key up events, milliseconds. Defaults to
|
||||||
# 100
|
# 100
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
|
||||||
# - If key is unknown or redundant, GenericError
|
# - If key is unknown or redundant, GenericError
|
||||||
#
|
#
|
||||||
# Since: 1.3
|
# Since: 1.3
|
||||||
|
@ -1259,8 +1254,6 @@
|
||||||
#
|
#
|
||||||
# @events: List of InputEvent union.
|
# @events: List of InputEvent union.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 2.6
|
# Since: 2.6
|
||||||
#
|
#
|
||||||
# Note: The consoles are visible in the qom tree, under
|
# Note: The consoles are visible in the qom tree, under
|
||||||
|
@ -1605,8 +1598,6 @@
|
||||||
#
|
#
|
||||||
# Reload display configuration.
|
# Reload display configuration.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 6.0
|
# Since: 6.0
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
@ -1664,8 +1655,6 @@
|
||||||
#
|
#
|
||||||
# Update display configuration.
|
# Update display configuration.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 7.1
|
# Since: 7.1
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
|
|
|
@ -78,9 +78,8 @@
|
||||||
#
|
#
|
||||||
# @instances: the instances to be yanked
|
# @instances: the instances to be yanked
|
||||||
#
|
#
|
||||||
# Returns:
|
# Errors:
|
||||||
# - Nothing on success
|
# - If any of the YankInstances doesn't exist, DeviceNotFound
|
||||||
# - @DeviceNotFound error, if any of the YankInstances doesn't exist
|
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
#
|
#
|
||||||
|
|
|
@ -153,8 +153,6 @@
|
||||||
# @time: time of nanoseconds, relative to the Epoch of 1970-01-01 in
|
# @time: time of nanoseconds, relative to the Epoch of 1970-01-01 in
|
||||||
# UTC.
|
# UTC.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 1.5
|
# Since: 1.5
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-set-time',
|
{ 'command': 'guest-set-time',
|
||||||
|
@ -230,7 +228,7 @@
|
||||||
#
|
#
|
||||||
# @mode: open mode, as per fopen(), "r" is the default.
|
# @mode: open mode, as per fopen(), "r" is the default.
|
||||||
#
|
#
|
||||||
# Returns: Guest file handle on success.
|
# Returns: Guest file handle
|
||||||
#
|
#
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
|
@ -245,8 +243,6 @@
|
||||||
#
|
#
|
||||||
# @handle: filehandle returned by guest-file-open
|
# @handle: filehandle returned by guest-file-open
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-file-close',
|
{ 'command': 'guest-file-close',
|
||||||
|
@ -281,7 +277,7 @@
|
||||||
# @count: maximum number of bytes to read (default is 4KB, maximum is
|
# @count: maximum number of bytes to read (default is 4KB, maximum is
|
||||||
# 48MB)
|
# 48MB)
|
||||||
#
|
#
|
||||||
# Returns: @GuestFileRead on success.
|
# Returns: @GuestFileRead
|
||||||
#
|
#
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
|
@ -316,7 +312,7 @@
|
||||||
# @count: bytes to write (actual bytes, after base64-decode), default
|
# @count: bytes to write (actual bytes, after base64-decode), default
|
||||||
# is all content in buf-b64 buffer after base64 decoding
|
# is all content in buf-b64 buffer after base64 decoding
|
||||||
#
|
#
|
||||||
# Returns: @GuestFileWrite on success.
|
# Returns: @GuestFileWrite
|
||||||
#
|
#
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
|
@ -383,7 +379,7 @@
|
||||||
#
|
#
|
||||||
# @whence: Symbolic or numeric code for interpreting offset
|
# @whence: Symbolic or numeric code for interpreting offset
|
||||||
#
|
#
|
||||||
# Returns: @GuestFileSeek on success.
|
# Returns: @GuestFileSeek
|
||||||
#
|
#
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
|
@ -399,8 +395,6 @@
|
||||||
#
|
#
|
||||||
# @handle: filehandle returned by guest-file-open
|
# @handle: filehandle returned by guest-file-open
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-file-flush',
|
{ 'command': 'guest-file-flush',
|
||||||
|
@ -443,15 +437,16 @@
|
||||||
# command succeeded, you may call @guest-fsfreeze-thaw later to
|
# command succeeded, you may call @guest-fsfreeze-thaw later to
|
||||||
# unfreeze.
|
# unfreeze.
|
||||||
#
|
#
|
||||||
|
# On error, all filesystems will be thawed. If no filesystems are
|
||||||
|
# frozen as a result of this call, then @guest-fsfreeze-status will
|
||||||
|
# remain "thawed" and calling @guest-fsfreeze-thaw is not necessary.
|
||||||
|
#
|
||||||
|
# Returns: Number of file systems currently frozen.
|
||||||
|
#
|
||||||
# Note: On Windows, the command is implemented with the help of a
|
# Note: On Windows, the command is implemented with the help of a
|
||||||
# Volume Shadow-copy Service DLL helper. The frozen state is
|
# Volume Shadow-copy Service DLL helper. The frozen state is
|
||||||
# limited for up to 10 seconds by VSS.
|
# limited for up to 10 seconds by VSS.
|
||||||
#
|
#
|
||||||
# Returns: Number of file systems currently frozen. On error, all
|
|
||||||
# filesystems will be thawed. If no filesystems are frozen as a
|
|
||||||
# result of this call, then @guest-fsfreeze-status will remain
|
|
||||||
# "thawed" and calling @guest-fsfreeze-thaw is not necessary.
|
|
||||||
#
|
|
||||||
# Since: 0.15.0
|
# Since: 0.15.0
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-fsfreeze-freeze',
|
{ 'command': 'guest-fsfreeze-freeze',
|
||||||
|
@ -463,12 +458,13 @@
|
||||||
# Sync and freeze specified guest filesystems. See also
|
# Sync and freeze specified guest filesystems. See also
|
||||||
# @guest-fsfreeze-freeze.
|
# @guest-fsfreeze-freeze.
|
||||||
#
|
#
|
||||||
|
# On error, all filesystems will be thawed.
|
||||||
|
#
|
||||||
# @mountpoints: an array of mountpoints of filesystems to be frozen.
|
# @mountpoints: an array of mountpoints of filesystems to be frozen.
|
||||||
# If omitted, every mounted filesystem is frozen. Invalid mount
|
# If omitted, every mounted filesystem is frozen. Invalid mount
|
||||||
# points are ignored.
|
# points are ignored.
|
||||||
#
|
#
|
||||||
# Returns: Number of file systems currently frozen. On error, all
|
# Returns: Number of file systems currently frozen.
|
||||||
# filesystems will be thawed.
|
|
||||||
#
|
#
|
||||||
# Since: 2.2
|
# Since: 2.2
|
||||||
##
|
##
|
||||||
|
@ -561,9 +557,8 @@
|
||||||
# could also exit (or set its status to "shutdown") due to other
|
# could also exit (or set its status to "shutdown") due to other
|
||||||
# reasons.
|
# reasons.
|
||||||
#
|
#
|
||||||
# The following errors may be returned:
|
# Errors:
|
||||||
#
|
# - If suspend to disk is not supported, Unsupported
|
||||||
# - If suspend to disk is not supported, Unsupported
|
|
||||||
#
|
#
|
||||||
# Notes: It's strongly recommended to issue the guest-sync command
|
# Notes: It's strongly recommended to issue the guest-sync command
|
||||||
# before sending commands when the guest resumes
|
# before sending commands when the guest resumes
|
||||||
|
@ -598,9 +593,8 @@
|
||||||
# 2. Issue the query-status QMP command to confirm the VM status is
|
# 2. Issue the query-status QMP command to confirm the VM status is
|
||||||
# "suspended"
|
# "suspended"
|
||||||
#
|
#
|
||||||
# The following errors may be returned:
|
# Errors:
|
||||||
#
|
# - If suspend to ram is not supported, Unsupported
|
||||||
# - If suspend to ram is not supported, Unsupported
|
|
||||||
#
|
#
|
||||||
# Notes: It's strongly recommended to issue the guest-sync command
|
# Notes: It's strongly recommended to issue the guest-sync command
|
||||||
# before sending commands when the guest resumes
|
# before sending commands when the guest resumes
|
||||||
|
@ -634,9 +628,8 @@
|
||||||
# 2. Issue the query-status QMP command to confirm the VM status is
|
# 2. Issue the query-status QMP command to confirm the VM status is
|
||||||
# "suspended"
|
# "suspended"
|
||||||
#
|
#
|
||||||
# The following errors may be returned:
|
# Errors:
|
||||||
#
|
# - If hybrid suspend is not supported, Unsupported
|
||||||
# - If hybrid suspend is not supported, Unsupported
|
|
||||||
#
|
#
|
||||||
# Notes: It's strongly recommended to issue the guest-sync command
|
# Notes: It's strongly recommended to issue the guest-sync command
|
||||||
# before sending commands when the guest resumes
|
# before sending commands when the guest resumes
|
||||||
|
@ -732,7 +725,7 @@
|
||||||
#
|
#
|
||||||
# Get list of guest IP addresses, MAC addresses and netmasks.
|
# Get list of guest IP addresses, MAC addresses and netmasks.
|
||||||
#
|
#
|
||||||
# Returns: List of GuestNetworkInterface on success.
|
# Returns: List of GuestNetworkInterface
|
||||||
#
|
#
|
||||||
# Since: 1.1
|
# Since: 1.1
|
||||||
##
|
##
|
||||||
|
@ -796,9 +789,6 @@
|
||||||
# - 0:
|
# - 0:
|
||||||
# if the @vcpus list was empty on input. Guest state has not
|
# if the @vcpus list was empty on input. Guest state has not
|
||||||
# been changed. Otherwise,
|
# been changed. Otherwise,
|
||||||
# - Error:
|
|
||||||
# processing the first node of @vcpus failed for the reason
|
|
||||||
# returned. Guest state has not been changed. Otherwise,
|
|
||||||
# - < length(@vcpus):
|
# - < length(@vcpus):
|
||||||
# more than zero initial nodes have been processed, but not the
|
# more than zero initial nodes have been processed, but not the
|
||||||
# entire @vcpus list. Guest state has changed accordingly. To
|
# entire @vcpus list. Guest state has changed accordingly. To
|
||||||
|
@ -808,6 +798,10 @@
|
||||||
# - length(@vcpus):
|
# - length(@vcpus):
|
||||||
# call successful.
|
# call successful.
|
||||||
#
|
#
|
||||||
|
# Errors:
|
||||||
|
# - If the reconfiguration of the first node in @vcpus failed.
|
||||||
|
# Guest state has not been changed.
|
||||||
|
#
|
||||||
# Since: 1.5
|
# Since: 1.5
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-set-vcpus',
|
{ 'command': 'guest-set-vcpus',
|
||||||
|
@ -1079,8 +1073,6 @@
|
||||||
# transmission, even if already crypt()d, to ensure it is 8-bit safe
|
# transmission, even if already crypt()d, to ensure it is 8-bit safe
|
||||||
# when passed as JSON.
|
# when passed as JSON.
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 2.3
|
# Since: 2.3
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-set-user-password',
|
{ 'command': 'guest-set-user-password',
|
||||||
|
@ -1184,9 +1176,9 @@
|
||||||
# @GuestMemoryBlockResponse, which is corresponding to the input
|
# @GuestMemoryBlockResponse, which is corresponding to the input
|
||||||
# list.
|
# list.
|
||||||
#
|
#
|
||||||
# Note: it will return NULL if the @mem-blks list was empty on
|
# Note: it will return an empty list if the @mem-blks list was
|
||||||
# input, or there is an error, and in this case, guest state will
|
# empty on input, or there is an error, and in this case, guest
|
||||||
# not be changed.
|
# state will not be changed.
|
||||||
#
|
#
|
||||||
# Since: 2.3
|
# Since: 2.3
|
||||||
##
|
##
|
||||||
|
@ -1257,7 +1249,7 @@
|
||||||
#
|
#
|
||||||
# @pid: pid returned from guest-exec
|
# @pid: pid returned from guest-exec
|
||||||
#
|
#
|
||||||
# Returns: GuestExecStatus on success.
|
# Returns: GuestExecStatus
|
||||||
#
|
#
|
||||||
# Since: 2.5
|
# Since: 2.5
|
||||||
##
|
##
|
||||||
|
@ -1325,7 +1317,7 @@
|
||||||
# @capture-output: bool flag to enable capture of stdout/stderr of
|
# @capture-output: bool flag to enable capture of stdout/stderr of
|
||||||
# running process. defaults to false.
|
# running process. defaults to false.
|
||||||
#
|
#
|
||||||
# Returns: PID on success.
|
# Returns: PID
|
||||||
#
|
#
|
||||||
# Since: 2.5
|
# Since: 2.5
|
||||||
##
|
##
|
||||||
|
@ -1354,7 +1346,7 @@
|
||||||
# or even present in DNS or some other name service at all. It need
|
# or even present in DNS or some other name service at all. It need
|
||||||
# not even be unique on your local network or site, but usually it is.
|
# not even be unique on your local network or site, but usually it is.
|
||||||
#
|
#
|
||||||
# Returns: the host name of the machine on success
|
# Returns: the host name of the machine
|
||||||
#
|
#
|
||||||
# Since: 2.10
|
# Since: 2.10
|
||||||
##
|
##
|
||||||
|
@ -1604,8 +1596,6 @@
|
||||||
#
|
#
|
||||||
# @reset: ignore the existing content, set it with the given keys only
|
# @reset: ignore the existing content, set it with the given keys only
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 5.2
|
# Since: 5.2
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-ssh-add-authorized-keys',
|
{ 'command': 'guest-ssh-add-authorized-keys',
|
||||||
|
@ -1624,8 +1614,6 @@
|
||||||
# @keys: the public keys to remove (in OpenSSH/sshd(8) authorized_keys
|
# @keys: the public keys to remove (in OpenSSH/sshd(8) authorized_keys
|
||||||
# format)
|
# format)
|
||||||
#
|
#
|
||||||
# Returns: Nothing on success.
|
|
||||||
#
|
|
||||||
# Since: 5.2
|
# Since: 5.2
|
||||||
##
|
##
|
||||||
{ 'command': 'guest-ssh-remove-authorized-keys',
|
{ 'command': 'guest-ssh-remove-authorized-keys',
|
||||||
|
|
|
@ -543,7 +543,7 @@ class QAPISchemaParser:
|
||||||
line = self.get_doc_indented(doc)
|
line = self.get_doc_indented(doc)
|
||||||
no_more_args = True
|
no_more_args = True
|
||||||
elif match := re.match(
|
elif match := re.match(
|
||||||
r'(Returns|Since|Notes?|Examples?|TODO): *',
|
r'(Returns|Errors|Since|Notes?|Examples?|TODO): *',
|
||||||
line):
|
line):
|
||||||
# tagged section
|
# tagged section
|
||||||
doc.new_tagged_section(self.info, match.group(1))
|
doc.new_tagged_section(self.info, match.group(1))
|
||||||
|
@ -639,6 +639,11 @@ class QAPIDoc:
|
||||||
# dicts mapping parameter/feature names to their description
|
# dicts mapping parameter/feature names to their description
|
||||||
self.args: Dict[str, QAPIDoc.ArgSection] = {}
|
self.args: Dict[str, QAPIDoc.ArgSection] = {}
|
||||||
self.features: Dict[str, QAPIDoc.ArgSection] = {}
|
self.features: Dict[str, QAPIDoc.ArgSection] = {}
|
||||||
|
# a command's "Returns" and "Errors" section
|
||||||
|
self.returns: Optional[QAPIDoc.Section] = None
|
||||||
|
self.errors: Optional[QAPIDoc.Section] = None
|
||||||
|
# "Since" section
|
||||||
|
self.since: Optional[QAPIDoc.Section] = None
|
||||||
# sections other than .body, .args, .features
|
# sections other than .body, .args, .features
|
||||||
self.sections: List[QAPIDoc.Section] = []
|
self.sections: List[QAPIDoc.Section] = []
|
||||||
|
|
||||||
|
@ -660,14 +665,22 @@ class QAPIDoc:
|
||||||
self.all_sections.append(section)
|
self.all_sections.append(section)
|
||||||
|
|
||||||
def new_tagged_section(self, info: QAPISourceInfo, tag: str) -> None:
|
def new_tagged_section(self, info: QAPISourceInfo, tag: str) -> None:
|
||||||
if tag in ('Returns', 'Since'):
|
|
||||||
for section in self.all_sections:
|
|
||||||
if isinstance(section, self.ArgSection):
|
|
||||||
continue
|
|
||||||
if section.tag == tag:
|
|
||||||
raise QAPISemError(
|
|
||||||
info, "duplicated '%s' section" % tag)
|
|
||||||
section = self.Section(info, tag)
|
section = self.Section(info, tag)
|
||||||
|
if tag == 'Returns':
|
||||||
|
if self.returns:
|
||||||
|
raise QAPISemError(
|
||||||
|
info, "duplicated '%s' section" % tag)
|
||||||
|
self.returns = section
|
||||||
|
elif tag == 'Errors':
|
||||||
|
if self.errors:
|
||||||
|
raise QAPISemError(
|
||||||
|
info, "duplicated '%s' section" % tag)
|
||||||
|
self.errors = section
|
||||||
|
elif tag == 'Since':
|
||||||
|
if self.since:
|
||||||
|
raise QAPISemError(
|
||||||
|
info, "duplicated '%s' section" % tag)
|
||||||
|
self.since = section
|
||||||
self.sections.append(section)
|
self.sections.append(section)
|
||||||
self.all_sections.append(section)
|
self.all_sections.append(section)
|
||||||
|
|
||||||
|
@ -708,13 +721,20 @@ class QAPIDoc:
|
||||||
self.features[feature.name].connect(feature)
|
self.features[feature.name].connect(feature)
|
||||||
|
|
||||||
def check_expr(self, expr: QAPIExpression) -> None:
|
def check_expr(self, expr: QAPIExpression) -> None:
|
||||||
if 'command' not in expr:
|
if 'command' in expr:
|
||||||
sec = next((sec for sec in self.sections
|
if self.returns and 'returns' not in expr:
|
||||||
if sec.tag == 'Returns'),
|
raise QAPISemError(
|
||||||
None)
|
self.returns.info,
|
||||||
if sec:
|
"'Returns' section, but command doesn't return anything")
|
||||||
raise QAPISemError(sec.info,
|
else:
|
||||||
"'Returns:' is only valid for commands")
|
if self.returns:
|
||||||
|
raise QAPISemError(
|
||||||
|
self.returns.info,
|
||||||
|
"'Returns' section is only valid for commands")
|
||||||
|
if self.errors:
|
||||||
|
raise QAPISemError(
|
||||||
|
self.returns.info,
|
||||||
|
"'Errors' section is only valid for commands")
|
||||||
|
|
||||||
def check(self) -> None:
|
def check(self) -> None:
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,8 @@
|
||||||
#
|
#
|
||||||
# Returns: @Object
|
# Returns: @Object
|
||||||
#
|
#
|
||||||
|
# Errors: some
|
||||||
|
#
|
||||||
# TODO: frobnicate
|
# TODO: frobnicate
|
||||||
#
|
#
|
||||||
# Notes:
|
# Notes:
|
||||||
|
|
|
@ -173,6 +173,8 @@ another feature
|
||||||
@arg3 is undocumented
|
@arg3 is undocumented
|
||||||
section=Returns
|
section=Returns
|
||||||
@Object
|
@Object
|
||||||
|
section=Errors
|
||||||
|
some
|
||||||
section=TODO
|
section=TODO
|
||||||
frobnicate
|
frobnicate
|
||||||
section=Notes
|
section=Notes
|
||||||
|
|
|
@ -206,6 +206,12 @@ Returns
|
||||||
"Object"
|
"Object"
|
||||||
|
|
||||||
|
|
||||||
|
Errors
|
||||||
|
~~~~~~
|
||||||
|
|
||||||
|
some
|
||||||
|
|
||||||
|
|
||||||
Notes
|
Notes
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
doc-invalid-return.json:6: 'Returns:' is only valid for commands
|
doc-invalid-return.json:6: 'Returns' section is only valid for commands
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
doc-invalid-return2.json:5: 'Returns' section, but command doesn't return anything
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Command doesn't return anything
|
||||||
|
|
||||||
|
##
|
||||||
|
# @foo:
|
||||||
|
# Returns: blah
|
||||||
|
##
|
||||||
|
{ 'command': 'foo' }
|
|
@ -79,6 +79,7 @@ schemas = [
|
||||||
'doc-invalid-end.json',
|
'doc-invalid-end.json',
|
||||||
'doc-invalid-end2.json',
|
'doc-invalid-end2.json',
|
||||||
'doc-invalid-return.json',
|
'doc-invalid-return.json',
|
||||||
|
'doc-invalid-return2.json',
|
||||||
'doc-invalid-section.json',
|
'doc-invalid-section.json',
|
||||||
'doc-invalid-start.json',
|
'doc-invalid-start.json',
|
||||||
'doc-missing-colon.json',
|
'doc-missing-colon.json',
|
||||||
|
|
Loading…
Reference in New Issue