* [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements
@ 2015-09-25 14:03 marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy marcandre.lureau
` (37 more replies)
0 siblings, 38 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Hi,
I have grown a qapi branch during the past 2 months that was
post-poned for review until the introspection and other fixes got
merged or ready.
It could be splitted roughly in 3 parts, but since they depend on each
other, it make sense to send as one:
1. generate QAPI documentation from schema (1->12)
2. remove use generated qmp dispatch in monitor (13->20)
3. add some support for async commands (22->36)
1 and 2 are hopefully not controversial, however 3 was discussed
previously in 'async commands with QMP' thread:
QMP was initially designed with async support, but the implementation
was buggy, since the async context didn't hold the request 'id', and
thus it wasn't really used, so it was removed in 65207c59d a few
months ago.
However, there a valid reasons to want better async support. Many qmp
operations take time, and it's not a good idea to block the monitor
during this time. Also, some operations, such as screendump with QXL,
have to reenter the loop in order to complete. Furthermore, the
current protocol is not purely synchronous, since the client have to
handle unexpected in the middle replies, such as events.
The current status-quo for async commands is to return immediately,
and send loosely related events later. This is quite poor from an API
point of view, and the events are not related to a previous command
(they don't hold the request 'id'). They are also broadcasted, which
may not make sense to other clients for various commands (all the dump
& query for example) and this prevent from adding meaningful client
'id' field (since it may conflict with other clients 'id').
I propose to re-introduce a better 'async' support, where command may
return with the request 'id' only to the caller, when they are
finished, and not block the monitor. This will be opt-out, so existing
code do not have to change. Furthermore, since reply order is not
guaranteed, clients will have to have the new 'async' capability to
use those async commands. This scheme is not incompatible with having
additional commands to query the command status, or broadcast related
events to all clients.
Marc-André Lureau (36):
qapi: add comment block before ChardevDummy
qapi: add missing @
qapi: add some line spacing to help doc parser
monitor: use qapi for qmp_capabilities command
qapi: move examples to json schema
qapi: move documentation bits in schema files
qapi: add some headings in docs
qapi: add qapi2texi script
qapi: remove qmp-events.txt
texi2pod: learn quotation, deftp and deftypefn
build-sys: generate QAPI doc based on json
build-sys: generate qmp-commands.txt
build-sys: do not generate qmp-commands-old.h
monitor: remove usage of generated marshal functions
monitor: register gen:false commands manually
qmp: register qapi commands (no middle mode)
qmp: use qmp_dispatch()
qapi: remove "middle" mode
qmp: implement qmp_query_commands without qmp_cmds
qmp: remove old qmp-commands table
misc: spelling
qmp: teach qmp_dispatch() to take a pre-filled QDict
qmp: use a return callback for the command reply
qmp: add QmpClient
qmp: introduce async command type
qmp: check that async command have an 'id'
scripts: learn 'async' qapi commands
scripts: ensure -async commands are declared async
qapi: take 'id' from request
tests: change /0.15/* tests to /qmp/*
tests: add /qmp/dispatch_cmd_async test
qmp: update qmp-spec about async capability
monitor: add 'async' capability
console: graphic_hw_update return true if async
console: add graphic_hw_update_done()
console: add screendump-async
Makefile | 43 +-
Makefile.target | 7 +-
docs/qmp/qmp-events.txt | 664 -----
docs/qmp/qmp-spec.txt | 17 +-
hw/display/qxl-render.c | 14 +-
hw/display/qxl.c | 8 +-
hw/display/qxl.h | 2 +-
include/qapi/qmp/dispatch.h | 29 +-
include/ui/console.h | 4 +-
monitor.c | 409 +--
qapi-schema.json | 1258 ++++++++-
qapi/block-core.json | 456 +++-
qapi/block.json | 48 +-
qapi/common.json | 37 +-
qapi/event.json | 211 ++
qapi/introspect.json | 2 +-
qapi/qmp-dispatch.c | 92 +-
qapi/qmp-registry.c | 26 +-
qapi/rocker.json | 46 +
qapi/trace.json | 14 +
qga/main.c | 26 +-
qga/qapi-schema.json | 2 +
qmp-commands.hx | 4324 -------------------------------
scripts/qapi-commands.py | 156 +-
scripts/qapi-introspect.py | 7 +-
scripts/qapi.py | 103 +-
scripts/qapi2texi.py | 293 +++
scripts/texi2pod.pl | 44 +-
tests/Makefile | 1 +
tests/qapi-schema/async.err | 0
tests/qapi-schema/async.exit | 1 +
tests/qapi-schema/async.json | 1 +
tests/qapi-schema/async.out | 5 +
tests/qapi-schema/qapi-schema-test.json | 2 +
tests/qapi-schema/qapi-schema-test.out | 5 +
tests/qapi-schema/test-qapi.py | 6 +-
tests/test-qmp-commands.c | 132 +-
ui/console.c | 77 +-
vl.c | 1 +
39 files changed, 3108 insertions(+), 5465 deletions(-)
delete mode 100644 docs/qmp/qmp-events.txt
delete mode 100644 qmp-commands.hx
create mode 100755 scripts/qapi2texi.py
create mode 100644 tests/qapi-schema/async.err
create mode 100644 tests/qapi-schema/async.exit
create mode 100644 tests/qapi-schema/async.json
create mode 100644 tests/qapi-schema/async.out
--
2.4.3
^ permalink raw reply [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:03 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 02/36] qapi: add missing @ marcandre.lureau
` (36 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
This is mainly to please the doc generation that requires comment block
before the declaration.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 516c95b..3e2e53d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3042,13 +3042,17 @@
{ 'struct': 'ChardevRingbuf', 'data': { '*size' : 'int' } }
##
+# @ChardevDummy
+##
+{ 'struct': 'ChardevDummy', 'data': { } }
+
+##
# @ChardevBackend:
#
# Configuration info for the new chardev backend.
#
# Since: 1.4 (testdev since 2.2)
##
-{ 'struct': 'ChardevDummy', 'data': { } }
{ 'union': 'ChardevBackend', 'data': { 'file' : 'ChardevFile',
'serial' : 'ChardevHostdev',
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 02/36] qapi: add missing @
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:03 ` Eric Blake
2015-10-03 16:57 ` Michael Tokarev
2015-09-25 14:03 ` [Qemu-devel] [PATCH 03/36] qapi: add some line spacing to help doc parser marcandre.lureau
` (35 subsequent siblings)
37 siblings, 2 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/block.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qapi/block.json b/qapi/block.json
index aad645c..84022f1 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -6,7 +6,7 @@
{ 'include': 'block-core.json' }
##
-# BiosAtaTranslation:
+# @BiosAtaTranslation:
#
# Policy that BIOS should use to interpret cylinder/head/sector
# addresses. Note that Bochs BIOS and SeaBIOS will not actually
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 03/36] qapi: add some line spacing to help doc parser
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 02/36] qapi: add missing @ marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 04/36] monitor: use qapi for qmp_capabilities command marcandre.lureau
` (34 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Paragraphs are seperated by empty lines.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 14 ++++++++++++++
qapi/block-core.json | 26 ++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/qapi-schema.json b/qapi-schema.json
index 3e2e53d..eb7beeb 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -856,8 +856,11 @@
# the name resolution on the host and may be an IP address.
#
# @family: #optional 'ipv6' if the host is listening for IPv6 connections
+#
# 'ipv4' if the host is listening for IPv4 connections
+#
# 'unix' if the host is listening on a unix domain socket
+#
# 'unknown' otherwise
#
# @service: #optional The service name of the server's port. This may depends
@@ -865,16 +868,27 @@
# be relied on.
#
# @auth: #optional the current authentication type used by the server
+#
# 'none' if no authentication is being used
+#
# 'vnc' if VNC authentication is being used
+#
# 'vencrypt+plain' if VEncrypt is used with plain text authentication
+#
# 'vencrypt+tls+none' if VEncrypt is used with TLS and no authentication
+#
# 'vencrypt+tls+vnc' if VEncrypt is used with TLS and VNC authentication
+#
# 'vencrypt+tls+plain' if VEncrypt is used with TLS and plain text auth
+#
# 'vencrypt+x509+none' if VEncrypt is used with x509 and no auth
+#
# 'vencrypt+x509+vnc' if VEncrypt is used with x509 and VNC auth
+#
# 'vencrypt+x509+plain' if VEncrypt is used with x509 and plain text auth
+#
# 'vencrypt+tls+sasl' if VEncrypt is used with TLS and SASL auth
+#
# 'vencrypt+x509+sasl' if VEncrypt is used with x509 and SASL auth
#
# @clients: a list of @VncClientInfo of all currently connected clients
diff --git a/qapi/block-core.json b/qapi/block-core.json
index bb2189e..e458023 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -629,7 +629,9 @@
# @password: the password to use for the device
#
# Returns: nothing on success
+#
# If @device is not a valid block device, DeviceNotFound
+#
# If @device is not encrypted, DeviceNotEncrypted
#
# Notes: Not all block formats support encryption and some that do are not
@@ -655,6 +657,7 @@
# @size: new image size in bytes
#
# Returns: nothing on success
+#
# If @device is not a valid block device, DeviceNotFound
#
# Since: 0.14.0
@@ -792,6 +795,7 @@
# For the arguments, see the documentation of BlockdevSnapshot.
#
# Returns: nothing on success
+#
# If @device is not a valid block device, DeviceNotFound
#
# Since 0.14.0
@@ -858,6 +862,7 @@
# (Since 2.1)
#
# If top == base, that is an error.
+#
# If top == active, the job will not be completed by itself,
# user needs to complete the job with the block-job-complete
# command after getting the ready event. (Since 2.0)
@@ -872,10 +877,15 @@
# @speed: #optional the maximum speed, in bytes per second
#
# Returns: Nothing on success
+#
# If commit or stream is already active on this device, DeviceInUse
+#
# If @device does not exist, DeviceNotFound
+#
# If image commit is not supported by this device, NotSupported
+#
# If @base or @top is invalid, a generic error is returned
+#
# If @speed is invalid, InvalidParameter
#
# Since: 1.3
@@ -897,6 +907,7 @@
# For the arguments, see the documentation of DriveBackup.
#
# Returns: nothing on success
+#
# If @device is not a valid block device, DeviceNotFound
#
# Since 1.6
@@ -982,6 +993,7 @@
# Default is true. (Since 2.4)
#
# Returns: nothing on success
+#
# If @device is not a valid block device, DeviceNotFound
#
# Since 1.3
@@ -1028,7 +1040,9 @@
# Create a dirty bitmap with a name on the node
#
# Returns: nothing on success
+#
# If @node is not a valid block device or node, DeviceNotFound
+#
# If @name is already taken, GenericError with an explanation
#
# Since 2.4
@@ -1042,8 +1056,11 @@
# Remove a dirty bitmap on the node
#
# Returns: nothing on success
+#
# If @node is not a valid block device or node, DeviceNotFound
+#
# If @name is not found, GenericError with an explanation
+#
# if @name is frozen by an operation, GenericError
#
# Since 2.4
@@ -1057,7 +1074,9 @@
# Clear (reset) a dirty bitmap on the device
#
# Returns: nothing on success
+#
# If @node is not a valid block device, DeviceNotFound
+#
# If @name is not found, GenericError with an explanation
#
# Since 2.4
@@ -1122,6 +1141,7 @@
# @group: #optional throttle group name (Since 2.4)
#
# Returns: Nothing on success
+#
# If @device is not a valid block device, DeviceNotFound
#
# Since: 1.1
@@ -1179,6 +1199,7 @@
# supports io-status (see BlockInfo). Since 1.3.
#
# Returns: Nothing on success
+#
# If @device does not exist, DeviceNotFound
#
# Since: 1.1
@@ -1202,6 +1223,7 @@
# Defaults to 0.
#
# Returns: Nothing on success
+#
# If no background operation is active on this device, DeviceNotActive
#
# Since: 1.1
@@ -1233,6 +1255,7 @@
# false). Since 1.3.
#
# Returns: Nothing on success
+#
# If no background operation is active on this device, DeviceNotActive
#
# Since: 1.1
@@ -1256,6 +1279,7 @@
# @device: the device name
#
# Returns: Nothing on success
+#
# If no background operation is active on this device, DeviceNotActive
#
# Since: 1.3
@@ -1276,6 +1300,7 @@
# @device: the device name
#
# Returns: Nothing on success
+#
# If no background operation is active on this device, DeviceNotActive
#
# Since: 1.3
@@ -1302,6 +1327,7 @@
# @device: the device name
#
# Returns: Nothing on success
+#
# If no background operation is active on this device, DeviceNotActive
#
# Since: 1.3
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 04/36] monitor: use qapi for qmp_capabilities command
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (2 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 03/36] qapi: add some line spacing to help doc parser marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:09 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 05/36] qapi: move examples to json schema marcandre.lureau
` (33 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
This was initially done to add qmp_capabilities documentation to the
schema. Then I figured it would also help to get rid of the "middle
mode" monitor dispatch code.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 4 ++--
qapi-schema.json | 17 +++++++++++++++++
qmp-commands.hx | 2 +-
3 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/monitor.c b/monitor.c
index 4ae654c..7e8ad0c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -568,7 +568,7 @@ static void monitor_qapi_event_init(void)
qmp_event_set_func_emit(monitor_qapi_event_queue);
}
-static void qmp_capabilities(QDict *params, QObject **ret_data, Error **errp)
+void qmp_qmp_capabilities(Error **errp)
{
cur_mon->qmp.in_command_mode = true;
}
@@ -3539,7 +3539,7 @@ static int monitor_can_read(void *opaque)
static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
Error **errp)
{
- bool is_cap = cmd->mhandler.cmd_new == qmp_capabilities;
+ bool is_cap = cmd->mhandler.cmd_new == qmp_marshal_qmp_capabilities;
if (is_cap && mon->qmp.in_command_mode) {
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
diff --git a/qapi-schema.json b/qapi-schema.json
index eb7beeb..a9b16d9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -21,6 +21,23 @@
{ 'include': 'qapi/introspect.json' }
##
+# @qmp_capabilities:
+#
+# Enable QMP capabilities.
+#
+# Arguments: None.
+#
+# Example:
+#
+# -> { "execute": "qmp_capabilities" }
+# <- { "return": {} }
+#
+# Notes: This command must be issued before issuing any other command.
+#
+##
+{ 'command': 'qmp_capabilities' }
+
+##
# @LostTickPolicy:
#
# Policy for handling lost ticks in timer devices.
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ebf2880..910edf5 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2018,7 +2018,7 @@ EQMP
.args_type = "",
.params = "",
.help = "enable QMP capabilities",
- .mhandler.cmd_new = qmp_capabilities,
+ .mhandler.cmd_new = qmp_marshal_qmp_capabilities,
},
SQMP
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 05/36] qapi: move examples to json schema
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (3 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 04/36] monitor: use qapi for qmp_capabilities command marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:16 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files marcandre.lureau
` (32 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Clean-up qmp-commands.hx from examples.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 1128 +++++++++++++++-
qapi/block-core.json | 365 +++++
qapi/block.json | 32 +
qapi/common.json | 32 +
qapi/rocker.json | 43 +
qapi/trace.json | 12 +
qmp-commands.hx | 3617 +-------------------------------------------------
7 files changed, 1625 insertions(+), 3604 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index a9b16d9..1383011 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -80,6 +80,13 @@
# Returns: nothing on success.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "add_client", "arguments": { "protocol": "vnc",
+# "fdname": "myclient" } }
+# <- { "return": {} }
+#
##
{ 'command': 'add_client',
'data': { 'protocol': 'str', 'fdname': 'str', '*skipauth': 'bool',
@@ -104,6 +111,12 @@
# Returns: @NameInfo of the guest
#
# Since 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-name" }
+# <- { "return": { "name": "qemu-name" } }
+#
##
{ 'command': 'query-name', 'returns': 'NameInfo' }
@@ -128,6 +141,12 @@
# Returns: @KvmInfo
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-kvm" }
+# <- { "return": { "enabled": true, "present": true } }
+#
##
{ 'command': 'query-kvm', 'returns': 'KvmInfo' }
@@ -204,6 +223,12 @@
# Returns: @StatusInfo reflecting all VCPUs
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-status" }
+# <- { "return": { "running": true, "singlestep": false, "status": "running" } }
+#
##
{ 'command': 'query-status', 'returns': 'StatusInfo' }
@@ -228,6 +253,12 @@
# Returns: The @UuidInfo for the guest
#
# Since 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-uuid" }
+# <- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } }
+#
##
{ 'command': 'query-uuid', 'returns': 'UuidInfo' }
@@ -261,6 +292,30 @@
# Returns: a list of @ChardevInfo
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-chardev" }
+# <- {
+# "return": [
+# {
+# "label": "charchannel0",
+# "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.agent,server",
+# "frontend-open": false
+# },
+# {
+# "label": "charmonitor",
+# "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.monitor,server",
+# "frontend-open": true
+# },
+# {
+# "label": "charserial0",
+# "filename": "pty:/dev/pts/2",
+# "frontend-open": true
+# }
+# ]
+# }
+#
##
{ 'command': 'query-chardev', 'returns': ['ChardevInfo'] }
@@ -283,6 +338,27 @@
# Returns: a list of @ChardevBackendInfo
#
# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "query-chardev-backends" }
+# <- {
+# "return":[
+# {
+# "name":"udp"
+# },
+# {
+# "name":"tcp"
+# },
+# {
+# "name":"unix"
+# },
+# {
+# "name":"spiceport"
+# }
+# ]
+# }
+#
##
{ 'command': 'query-chardev-backends', 'returns': ['ChardevBackendInfo'] }
@@ -321,6 +397,15 @@
# Returns: Nothing on success
#
# Since: 1.4
+#
+# Example:
+#
+# -> { "execute": "ringbuf-write",
+# "arguments": { "device": "foo",
+# "data": "abcdefgh",
+# "format": "utf8" } }
+# <- { "return": {} }
+#
##
{ 'command': 'ringbuf-write',
'data': {'device': 'str', 'data': 'str',
@@ -348,6 +433,15 @@
# Returns: data read from the device
#
# Since: 1.4
+#
+# Example:
+#
+# -> { "execute": "ringbuf-read",
+# "arguments": { "device": "foo",
+# "size": 1000,
+# "format": "utf8" } }
+# <- {"return": "abcdefgh"}
+#
##
{ 'command': 'ringbuf-read',
'data': {'device': 'str', 'size': 'int', '*format': 'DataFormat'},
@@ -372,6 +466,23 @@
# Returns: A list of @EventInfo for all supported events
#
# Since: 1.2.0
+#
+# Example:
+#
+# -> { "execute": "query-events" }
+# <- {
+# "return":[
+# {
+# "name":"SHUTDOWN"
+# },
+# {
+# "name":"RESET"
+# }
+# ]
+# }
+#
+# Notes: This example has been shortened as the real response is too long.
+#
##
{ 'command': 'query-events', 'returns': ['EventInfo'] }
@@ -516,6 +627,116 @@
# Returns: @MigrationInfo
#
# Since: 0.14.0
+#
+# Example:
+#
+# 1. Before the first migration
+#
+# -> { "execute": "query-migrate" }
+# <- { "return": {} }
+#
+# 2. Migration is done and has succeeded
+#
+# -> { "execute": "query-migrate" }
+# <- { "return": {
+# "status": "completed",
+# "ram":{
+# "transferred":123,
+# "remaining":123,
+# "total":246,
+# "total-time":12345,
+# "setup-time":12345,
+# "downtime":12345,
+# "duplicate":123,
+# "normal":123,
+# "normal-bytes":123456,
+# "dirty-sync-count":15
+# }
+# }
+# }
+#
+# 3. Migration is done and has failed
+#
+# -> { "execute": "query-migrate" }
+# <- { "return": { "status": "failed" } }
+#
+# 4. Migration is being performed and is not a block migration:
+#
+# -> { "execute": "query-migrate" }
+# <- {
+# "return":{
+# "status":"active",
+# "ram":{
+# "transferred":123,
+# "remaining":123,
+# "total":246,
+# "total-time":12345,
+# "setup-time":12345,
+# "expected-downtime":12345,
+# "duplicate":123,
+# "normal":123,
+# "normal-bytes":123456,
+# "dirty-sync-count":15
+# }
+# }
+# }
+#
+# 5. Migration is being performed and is a block migration:
+#
+# -> { "execute": "query-migrate" }
+# <- {
+# "return":{
+# "status":"active",
+# "ram":{
+# "total":1057024,
+# "remaining":1053304,
+# "transferred":3720,
+# "total-time":12345,
+# "setup-time":12345,
+# "expected-downtime":12345,
+# "duplicate":123,
+# "normal":123,
+# "normal-bytes":123456,
+# "dirty-sync-count":15
+# },
+# "disk":{
+# "total":20971520,
+# "remaining":20880384,
+# "transferred":91136
+# }
+# }
+# }
+#
+# 6. Migration is being performed and XBZRLE is active:
+#
+# -> { "execute": "query-migrate" }
+# <- {
+# "return":{
+# "status":"active",
+# "capabilities" : [ { "capability": "xbzrle", "state" : true } ],
+# "ram":{
+# "total":1057024,
+# "remaining":1053304,
+# "transferred":3720,
+# "total-time":12345,
+# "setup-time":12345,
+# "expected-downtime":12345,
+# "duplicate":10,
+# "normal":3333,
+# "normal-bytes":3412992,
+# "dirty-sync-count":15
+# },
+# "xbzrle-cache":{
+# "cache-size":67108864,
+# "bytes":20971520,
+# "pages":2444343,
+# "cache-miss":2244,
+# "cache-miss-rate":0.123,
+# "overflow":34434
+# }
+# }
+# }
+#
##
{ 'command': 'query-migrate', 'returns': 'MigrationInfo' }
@@ -579,7 +800,19 @@
#
# @capabilities: json array of capability modifications to make
#
+# - "xbzrle": XBZRLE support
+# - "rdma-pin-all": pin all pages when using RDMA during migration
+# - "auto-converge": throttle down guest to help convergence of migration
+# - "zero-blocks": compress zero blocks during block migration
+# - "events": generate events for each migration state change
+#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "migrate-set-capabilities" , "arguments":
+# { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
+#
##
{ 'command': 'migrate-set-capabilities',
'data': { 'capabilities': ['MigrationCapabilityStatus'] } }
@@ -592,6 +825,12 @@
# Returns: @MigrationCapabilitiesStatus
#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "query-migrate-capabilities" }
+# <- { "return": [ { "state": false, "capability": "xbzrle" } ] }
+#
##
{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
@@ -630,6 +869,12 @@
# @decompress-threads: decompression thread count
#
# Since: 2.4
+#
+# Example:
+#
+# -> { "execute": "migrate-set-parameters" , "arguments":
+# { "compress-level": 1 } }
+#
##
{ 'command': 'migrate-set-parameters',
'data': { '*compress-level': 'int',
@@ -659,6 +904,18 @@
# Returns: @MigrationParameters
#
# Since: 2.4
+#
+# Example:
+#
+# -> { "execute": "query-migrate-parameters" }
+# <- {
+# "return": {
+# "decompress-threads", 2,
+# "compress-threads", 8,
+# "compress-level", 1
+# }
+# }
+#
##
{ 'command': 'query-migrate-parameters',
'returns': 'MigrationParameters' }
@@ -677,6 +934,15 @@
# @cert-subject: #optional server certificate subject
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "client_migrate_info",
+# "arguments": { "protocol": "spice",
+# "hostname": "virt42.lab.kraxel.org",
+# "port": 1234 } }
+# <- { "return": {} }
+#
##
{ 'command': 'client_migrate_info',
'data': { 'protocol': 'str', 'hostname': 'str', '*port': 'int',
@@ -709,6 +975,27 @@
# Returns: a list of @MouseInfo for each device
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-mice" }
+# <- {
+# "return":[
+# {
+# "name":"QEMU Microsoft Mouse",
+# "index":0,
+# "current":false,
+# "absolute":false
+# },
+# {
+# "name":"QEMU PS/2 Mouse",
+# "index":1,
+# "current":true,
+# "absolute":true
+# }
+# ]
+# }
+#
##
{ 'command': 'query-mice', 'returns': ['MouseInfo'] }
@@ -759,6 +1046,31 @@
# Returns: a list of @CpuInfo for each virtual CPU
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-cpus" }
+# <- {
+# "return":[
+# {
+# "CPU":0,
+# "current":true,
+# "halted":false,
+# "qom_path":"/machine/unattached/device[0]",
+# "pc":3227107138,
+# "thread_id":3134
+# },
+# {
+# "CPU":1,
+# "current":false,
+# "halted":true,
+# "qom_path":"/machine/unattached/device[2]",
+# "pc":7108165,
+# "thread_id":3135
+# }
+# ]
+# }
+#
##
{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }
@@ -788,6 +1100,23 @@
# Returns: a list of @IOThreadInfo for each iothread
#
# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "query-iothreads" }
+# <- {
+# "return":[
+# {
+# "id":"iothread0",
+# "thread-id":3134
+# },
+# {
+# "id":"iothread1",
+# "thread-id":3135
+# }
+# ]
+# }
+#
##
{ 'command': 'query-iothreads', 'returns': ['IOThreadInfo'] }
@@ -982,6 +1311,27 @@
# Returns: @VncInfo
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-vnc" }
+# <- {
+# "return":{
+# "enabled":true,
+# "host":"0.0.0.0",
+# "service":"50402",
+# "auth":"vnc",
+# "family":"ipv4",
+# "clients":[
+# {
+# "host":"127.0.0.1",
+# "service":"50401",
+# "family":"ipv4"
+# }
+# ]
+# }
+# }
+#
##
{ 'command': 'query-vnc', 'returns': 'VncInfo' }
@@ -1118,6 +1468,41 @@
# Returns: @SpiceInfo
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-spice" }
+# <- {
+# "return": {
+# "enabled": true,
+# "auth": "spice",
+# "port": 5920,
+# "tls-port": 5921,
+# "host": "0.0.0.0",
+# "channels": [
+# {
+# "port": "54924",
+# "family": "ipv4",
+# "channel-type": 1,
+# "connection-id": 1804289383,
+# "host": "127.0.0.1",
+# "channel-id": 0,
+# "tls": true
+# },
+# {
+# "port": "36710",
+# "family": "ipv4",
+# "channel-type": 4,
+# "connection-id": 1804289383,
+# "host": "127.0.0.1",
+# "channel-id": 0,
+# "tls": false
+# },
+# [ ... more channels follow ... ]
+# ]
+# }
+# }
+#
##
{ 'command': 'query-spice', 'returns': 'SpiceInfo' }
@@ -1144,6 +1529,16 @@
# If no balloon device is present, DeviceNotActive
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-balloon" }
+# <- {
+# "return":{
+# "actual":1073741824,
+# }
+# }
+#
##
{ 'command': 'query-balloon', 'returns': 'BalloonInfo' }
@@ -1306,6 +1701,141 @@
# Returns: a list of @PciInfo for each PCI bus
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-pci" }
+# <- {
+# "return":[
+# {
+# "bus":0,
+# "devices":[
+# {
+# "bus":0,
+# "qdev_id":"",
+# "slot":0,
+# "class_info":{
+# "class":1536,
+# "desc":"Host bridge"
+# },
+# "id":{
+# "device":32902,
+# "vendor":4663
+# },
+# "function":0,
+# "regions":[
+#
+# ]
+# },
+# {
+# "bus":0,
+# "qdev_id":"",
+# "slot":1,
+# "class_info":{
+# "class":1537,
+# "desc":"ISA bridge"
+# },
+# "id":{
+# "device":32902,
+# "vendor":28672
+# },
+# "function":0,
+# "regions":[
+#
+# ]
+# },
+# {
+# "bus":0,
+# "qdev_id":"",
+# "slot":1,
+# "class_info":{
+# "class":257,
+# "desc":"IDE controller"
+# },
+# "id":{
+# "device":32902,
+# "vendor":28688
+# },
+# "function":1,
+# "regions":[
+# {
+# "bar":4,
+# "size":16,
+# "address":49152,
+# "type":"io"
+# }
+# ]
+# },
+# {
+# "bus":0,
+# "qdev_id":"",
+# "slot":2,
+# "class_info":{
+# "class":768,
+# "desc":"VGA controller"
+# },
+# "id":{
+# "device":4115,
+# "vendor":184
+# },
+# "function":0,
+# "regions":[
+# {
+# "prefetch":true,
+# "mem_type_64":false,
+# "bar":0,
+# "size":33554432,
+# "address":4026531840,
+# "type":"memory"
+# },
+# {
+# "prefetch":false,
+# "mem_type_64":false,
+# "bar":1,
+# "size":4096,
+# "address":4060086272,
+# "type":"memory"
+# },
+# {
+# "prefetch":false,
+# "mem_type_64":false,
+# "bar":6,
+# "size":65536,
+# "address":-1,
+# "type":"memory"
+# }
+# ]
+# },
+# {
+# "bus":0,
+# "qdev_id":"",
+# "irq":11,
+# "slot":4,
+# "class_info":{
+# "class":1280,
+# "desc":"RAM controller"
+# },
+# "id":{
+# "device":6900,
+# "vendor":4098
+# },
+# "function":0,
+# "regions":[
+# {
+# "bar":0,
+# "size":32,
+# "address":49280,
+# "type":"io"
+# }
+# ]
+# }
+# ]
+# }
+# ]
+# }
+#
+# Note: This example has been shortened as the real response is too long.
+#
##
{ 'command': 'query-pci', 'returns': ['PciInfo'] }
@@ -1318,6 +1848,11 @@
# unexpected.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "quit" }
+# <- { "return": {} }
##
{ 'command': 'quit' }
@@ -1332,6 +1867,12 @@
# state. In "inmigrate" state, it will ensure that the guest
# remains paused once migration finishes, as if the -S option was
# passed on the command line.
+#
+# Example:
+#
+# -> { "execute": "stop" }
+# <- { "return": {} }
+#
##
{ 'command': 'stop' }
@@ -1341,6 +1882,12 @@
# Performs a hard reset of a guest.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "system_reset" }
+# <- { "return": {} }
+#
##
{ 'command': 'system_reset' }
@@ -1355,6 +1902,11 @@
# returning does not indicate that a guest has accepted the request or
# that it has shut down. Many guests will respond to this command by
# prompting the user in some way.
+# Example:
+#
+# -> { "execute": "system_powerdown" }
+# <- { "return": {} }
+#
##
{ 'command': 'system_powerdown' }
@@ -1379,6 +1931,11 @@
# Returns: Nothing on success
#
# Since 1.5
+#
+# Example:
+#
+# -> { "execute": "cpu-add", "arguments": { "id": 2 } }
+# <- { "return": {} }
##
{ 'command': 'cpu-add', 'data': {'id': 'int'} }
@@ -1401,6 +1958,15 @@
# Since: 0.14.0
#
# Notes: Errors were not reliably returned until 1.1
+#
+# Example:
+#
+# -> { "execute": "memsave",
+# "arguments": { "val": 10,
+# "size": 100,
+# "filename": "/tmp/virtual-mem-dump" } }
+# <- { "return": {} }
+#
##
{ 'command': 'memsave',
'data': {'val': 'int', 'size': 'int', 'filename': 'str', '*cpu-index': 'int'} }
@@ -1421,6 +1987,15 @@
# Since: 0.14.0
#
# Notes: Errors were not reliably returned until 1.1
+#
+# Example:
+#
+# -> { "execute": "pmemsave",
+# "arguments": { "val": 10,
+# "size": 100,
+# "filename": "/tmp/physical-mem-dump" } }
+# <- { "return": {} }
+#
##
{ 'command': 'pmemsave',
'data': {'val': 'int', 'size': 'int', 'filename': 'str'} }
@@ -1441,6 +2016,12 @@
# this case, the effect of the command is to make sure the guest
# starts once migration finishes, removing the effect of the -S
# command line option if it was passed.
+#
+# Example:
+#
+# -> { "execute": "cont" }
+# <- { "return": {} }
+#
##
{ 'command': 'cont' }
@@ -1452,6 +2033,12 @@
# Since: 1.1
#
# Returns: nothing.
+#
+# Example:
+#
+# -> { "execute": "system_wakeup" }
+# <- { "return": {} }
+#
##
{ 'command': 'system_wakeup' }
@@ -1465,6 +2052,12 @@
# Since: 0.14.0
#
# Note: prior to 2.1, this command was only supported for x86 and s390 VMs
+#
+# Example:
+#
+# -> { "execute": "inject-nmi" }
+# <- { "return": {} }
+#
##
{ 'command': 'inject-nmi' }
@@ -1485,6 +2078,12 @@
# Notes: Not all network adapters support setting link status. This command
# will succeed even if the network adapter does not support link status
# notification.
+#
+# Example:
+#
+# -> { "execute": "set_link", "arguments": { "name": "e1000.0", "up": false } }
+# <- { "return": {} }
+#
##
{ 'command': 'set_link', 'data': {'name': 'str', 'up': 'bool'} }
@@ -1505,6 +2104,12 @@
# size independent of this command.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "balloon", "arguments": { "value": 536870912 } }
+# <- { "return": {} }
+#
##
{ 'command': 'balloon', 'data': {'value': 'int'} }
@@ -1543,14 +2148,43 @@
##
# @transaction
#
+# @actions: List of @TransactionAction: information needed for the respective
+# operation
+#
# Executes a number of transactionable QMP commands atomically. If any
# operation fails, then the entire set of actions will be abandoned and the
# appropriate error returned.
#
-# List of:
-# @TransactionAction: information needed for the respective operation
+# Atomically operate on one or more block devices. The only supported operations
+# for now are drive-backup, internal and external snapshotting. A list of
+# dictionaries is accepted, that contains the actions to be performed.
+# If there is any failure performing any of the operations, all operations
+# for the group are abandoned.
+#
+# For external snapshots, the dictionary contains the device, the file to use for
+# the new snapshot, and the format. The default format, if not specified, is
+# qcow2.
+#
+# Each new snapshot defaults to being created by QEMU (wiping any
+# contents if the file already exists), but it is also possible to reuse
+# an externally-created file. In the latter case, you should ensure that
+# the new image file has the same contents as the current one; QEMU cannot
+# perform any meaningful check. Typically this is achieved by using the
+# current image file as the backing file for the new image.
+#
+# On failure, the original disks pre-snapshot attempt will be used.
+#
+# For internal snapshots, the dictionary contains the device and the snapshot's
+# name. If an internal snapshot matching name already exists, the request will
+# be rejected. Only some image formats support it, for example, qcow2, rbd,
+# and sheepdog.
+#
+# On failure, qemu will try delete the newly created internal snapshot in the
+# transaction. When an I/O error occurs during deletion, the user needs to fix
+# it later with qemu-img or other command.
#
# Returns: nothing on success
+#
# Errors depend on the operations of the transaction
#
# Note: The transaction aborts on the first failure. Therefore, there will be
@@ -1558,6 +2192,28 @@
# subsequent actions will not have been attempted.
#
# Since 1.1
+#
+# Example:
+#
+# -> { "execute": "transaction",
+# "arguments": { "actions": [
+# { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd0",
+# "snapshot-file": "/some/place/my-image",
+# "format": "qcow2" } },
+# { "type": "blockdev-snapshot-sync", "data" : { "node-name": "myfile",
+# "snapshot-file": "/some/place/my-image2",
+# "snapshot-node-name": "node3432",
+# "mode": "existing",
+# "format": "qcow2" } },
+# { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd1",
+# "snapshot-file": "/some/place/my-image2",
+# "mode": "existing",
+# "format": "qcow2" } },
+# { "type": "blockdev-snapshot-internal-sync", "data" : {
+# "device": "ide-hd2",
+# "name": "snapshot0" } } ] } }
+# <- { "return": {} }
+#
##
{ 'command': 'transaction',
'data': { 'actions': [ 'TransactionAction' ] } }
@@ -1585,6 +2241,12 @@
#
# o Commands that prompt the user for data (eg. 'cont' when the block
# device is encrypted) don't currently work
+#
+# Example:
+#
+# -> { "execute": "human-monitor-command", "arguments": { "command-line": "info kvm" } }
+# <- { "return": "kvm support: enabled\r\n" }
+#
##
{ 'command': 'human-monitor-command',
'data': {'command-line': 'str', '*cpu-index': 'int'},
@@ -1600,6 +2262,12 @@
# Notes: This command succeeds even if there is no migration process running.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "migrate_cancel" }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate_cancel' }
@@ -1613,6 +2281,12 @@
# Returns: nothing on success
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }
@@ -1628,6 +2302,12 @@
# Notes: A value lesser than zero will be automatically round up to zero.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
@@ -1644,6 +2324,12 @@
# Returns: nothing on success
#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "migrate-set-cache-size", "arguments": { "value": 536870912 } }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
@@ -1655,6 +2341,12 @@
# Returns: XBZRLE cache size in bytes
#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "query-migrate-cache-size" }
+# <- { "return": 67108864 }
+#
##
{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
@@ -1771,6 +2463,13 @@
# If Spice is not enabled, DeviceNotFound
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "set_password", "arguments": { "protocol": "vnc",
+# "password": "secret" } }
+# <- { "return": {} }
+#
##
{ 'command': 'set_password',
'data': {'protocol': 'str', 'password': 'str', '*connected': 'str'} }
@@ -1797,6 +2496,13 @@
# coordinate server time with client time. It is not recommended to
# use the absolute time version of the @time parameter unless you're
# sure you are on the same machine as the QEMU instance.
+#
+# Example:
+#
+# -> { "execute": "expire_password", "arguments": { "protocol": "vnc",
+# "time": "+60" } }
+# <- { "return": {} }
+#
##
{ 'command': 'expire_password', 'data': {'protocol': 'str', 'time': 'str'} }
@@ -1845,6 +2551,23 @@
# for changing block devices.
#
# Since: 0.14.0
+#
+# Example:
+#
+# 1. Change a removable medium
+#
+# -> { "execute": "change",
+# "arguments": { "device": "ide1-cd0",
+# "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } }
+# <- { "return": {} }
+#
+# 2. Change VNC password
+#
+# -> { "execute": "change",
+# "arguments": { "device": "vnc", "target": "password",
+# "arg": "foobar1" } }
+# <- { "return": {} }
+#
##
{ 'command': 'change',
'data': {'device': 'str', 'target': 'str', '*arg': 'str'} }
@@ -1927,6 +2650,22 @@
# Returns: nothing on success
#
# Since: 0.14.0
+#
+# Notes:
+#
+# 1. The 'query-migrate' command should be used to check migration's progress
+# and final result (this information is provided by the 'status' member)
+#
+# 2. All boolean arguments default to false
+#
+# 3. The user Monitor's "detach" argument is invalid in QMP and should not
+# be used
+#
+# Example:
+#
+# -> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate',
'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } }
@@ -1943,9 +2682,23 @@
# Returns: nothing on success
#
# Since: 2.3
-# Note: It's a bad idea to use a string for the uri, but it needs to stay
-# compatible with -incoming and the format of the uri is already exposed
-# above libvirt
+#
+# Note:
+#
+# 1. It's a bad idea to use a string for the uri, but it needs to stay
+# compatible with -incoming and the format of the uri is already exposed
+# above libvirt.
+#
+# 2. QEMU must be started with -incoming defer to allow migrate-incoming to
+# be used.
+#
+# 3. The uri format is the same as for -incoming
+#
+# Example:
+#
+# -> { "execute": "migrate-incoming", "arguments": { "uri": "tcp::4446" } }
+# <- { "return": {} }
+#
##
{ 'command': 'migrate-incoming', 'data': {'uri': 'str' } }
@@ -1961,6 +2714,13 @@
# Returns: Nothing on success
#
# Since: 1.1
+#
+# Example:
+#
+# -> { "execute": "xen-save-devices-state",
+# "arguments": { "filename": "/tmp/save" } }
+# <- { "return": {} }
+#
##
{ 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
@@ -1974,15 +2734,48 @@
# Returns: nothing
#
# Since: 1.3
+#
+# Example:
+#
+# -> { "execute": "xen-set-global-dirty-log",
+# "arguments": { "enable": true } }
+# <- { "return": {} }
+#
##
{ 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } }
##
+# @device_add:
+#
+# @driver: the name of the new device's driver
+# @bus: #optional the device's parent bus (device tree path)
+# @id: the device's ID, must be unique
+# @props: #optional a dictionary of properties to be passed to the backend
+#
+# Add a device.
+#
+# Notes:
+# 1. For detailed information about this command, please refer to the
+# 'docs/qdev-device-use.txt' file.
+#
+# 2. It's possible to list device properties by running QEMU with the
+# "-device DEVICE,\?" command-line argument, where DEVICE is the device's name
+#
+# Example:
+#
+# -> { "execute": "device_add", "arguments": { "driver": "e1000", "id": "net1" } }
+# <- { "return": {} }
+#
+##
+{ 'command': 'device_add',
+ 'data': {'driver': 'str', 'id': 'str'}, 'gen': false }
+
+##
# @device_del:
#
# Remove a device from a guest
#
-# @id: the name or QOM path of the device
+# @id: the device's ID or QOM path
#
# Returns: Nothing on success
# If @id is not a valid device, DeviceNotFound
@@ -1995,6 +2788,15 @@
# for all devices.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "device_del", "arguments": { "id": "net1" } }
+# <- { "return": {} }
+#
+# -> { "execute": "device_del", "arguments": { "id": "/machine/peripheral-anon/device[0]" } }
+# <- { "return": {} }
+#
##
{ 'command': 'device_del', 'data': {'id': 'str'} }
@@ -2060,6 +2862,12 @@
# Returns: nothing on success
#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "dump-guest-memory", "arguments": { "protocol": "fd:dump" } }
+# <- { "return": {} }
+#
##
{ 'command': 'dump-guest-memory',
'data': { 'paging': 'bool', 'protocol': 'str', '*begin': 'int',
@@ -2085,6 +2893,13 @@
# dump-guest-memory
#
# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "query-dump-guest-memory-capability" }
+# <- { "return": { "formats":
+# ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
+#
##
{ 'command': 'query-dump-guest-memory-capability',
'returns': 'DumpGuestMemoryCapability' }
@@ -2099,6 +2914,11 @@
# This command is only supported on s390 architecture.
#
# Since: 2.5
+# Example:
+#
+# -> { "execute": "dump-skeys", "arguments": { "filename": "/tmp/skeys" } }
+# <- { "return": {} }
+#
##
{ 'command': 'dump-skeys',
'data': { 'filename': 'str' } }
@@ -2117,6 +2937,14 @@
#
# Returns: Nothing on success
# If @type is not a valid network backend, DeviceNotFound
+#
+# Example:
+#
+# -> { "execute": "netdev_add",
+# "arguments": { "type": "user", "id": "netdev1",
+# "dnssearch": "example.org" } }
+# <- { "return": {} }
+#
##
{ 'command': 'netdev_add', 'data': 'Netdev', 'box': true }
@@ -2131,6 +2959,12 @@
# If @id is not a valid network backend, DeviceNotFound
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "netdev_del", "arguments": { "id": "netdev1" } }
+# <- { "return": {} }
+#
##
{ 'command': 'netdev_del', 'data': {'id': 'str'} }
@@ -2149,6 +2983,13 @@
# Error if @qom-type is not a valid class name
#
# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "object-add", "arguments": { "qom-type": "rng-random", "id": "rng1",
+# "props": { "filename": "/dev/hwrng" } } }
+# <- { "return": {} }
+#
##
{ 'command': 'object-add',
'data': {'qom-type': 'str', 'id': 'str', '*props': 'any'} }
@@ -2164,6 +3005,12 @@
# Error if @id is not a valid id for a QOM object
#
# Since: 2.0
+#
+# Example:
+#
+# -> { "execute": "object-del", "arguments": { "id": "rng1" } }
+# <- { "return": {} }
+#
##
{ 'command': 'object-del', 'data': {'id': 'str'} }
@@ -2661,8 +3508,15 @@
# Notes: If @fdname already exists, the file descriptor assigned to
# it will be closed and replaced by the received file
# descriptor.
+#
# The 'closefd' command can be used to explicitly close the
# file descriptor when it is no longer needed.
+#
+# Example:
+#
+# -> { "execute": "getfd", "arguments": { "fdname": "fd1" } }
+# <- { "return": {} }
+#
##
{ 'command': 'getfd', 'data': {'fdname': 'str'} }
@@ -2694,6 +3548,12 @@
# (since 1.5.0)
#
# Since: 1.2.0
+#
+# Example:
+#
+# -> { "execute": "closefd", "arguments": { "fdname": "fd1" } }
+# <- { "return": {} }
+#
##
{ 'struct': 'MachineInfo',
'data': { 'name': 'str', '*alias': 'str',
@@ -2764,6 +3624,12 @@
# If @fdset-id is not specified, a new fd set will be created.
#
# Since: 1.2.0
+#
+# Example:
+#
+# -> { "execute": "add-fd", "arguments": { "fdset-id": 1 } }
+# <- { "return": { "fdset-id": 1, "fd": 3 } }
+#
##
{ 'command': 'add-fd', 'data': {'*fdset-id': 'int', '*opaque': 'str'},
'returns': 'AddfdInfo' }
@@ -2786,6 +3652,12 @@
#
# If @fd is not specified, all file descriptors in @fdset-id
# will be removed.
+#
+# Example:
+#
+# -> { "execute": "remove-fd", "arguments": { "fdset-id": 1, "fd": 3 } }
+# <- { "return": {} }
+#
##
{ 'command': 'remove-fd', 'data': {'fdset-id': 'int', '*fd': 'int'} }
@@ -2828,6 +3700,37 @@
#
# Note: The list of fd sets is shared by all monitor connections.
#
+# Example:
+#
+# -> { "execute": "query-fdsets" }
+# <- { "return": [
+# {
+# "fds": [
+# {
+# "fd": 30,
+# "opaque": "rdonly:/path/to/file"
+# },
+# {
+# "fd": 24,
+# "opaque": "rdwr:/path/to/file"
+# }
+# ],
+# "fdset-id": 1
+# },
+# {
+# "fds": [
+# {
+# "fd": 28
+# },
+# {
+# "fd": 29
+# }
+# ],
+# "fdset-id": 0
+# }
+# ]
+# }
+#
##
{ 'command': 'query-fdsets', 'returns': ['FdsetInfo'] }
@@ -2915,6 +3818,14 @@
#
# Since: 1.3.0
#
+# Example:
+#
+# -> { "execute": "send-key",
+# "arguments": { "keys": [ { "type": "qcode", "data": "ctrl" },
+# { "type": "qcode", "data": "alt" },
+# { "type": "qcode", "data": "delete" } ] } }
+# <- { "return": {} }
+#
##
{ 'command': 'send-key',
'data': { 'keys': ['KeyValue'], '*hold-time': 'int' } }
@@ -2929,6 +3840,12 @@
# Returns: Nothing on success
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "screendump", "arguments": { "filename": "/tmp/image" } }
+# <- { "return": {} }
+#
##
{ 'command': 'screendump', 'data': {'filename': 'str'} }
@@ -3129,6 +4046,25 @@
# Returns: ChardevReturn.
#
# Since: 1.4
+#
+# Example:
+#
+# -> { "execute" : "chardev-add",
+# "arguments" : { "id" : "foo",
+# "backend" : { "type" : "null", "data" : {} } } }
+# <- { "return": {} }
+#
+# -> { "execute" : "chardev-add",
+# "arguments" : { "id" : "bar",
+# "backend" : { "type" : "file",
+# "data" : { "out" : "/tmp/bar.log" } } } }
+# <- { "return": {} }
+#
+# -> { "execute" : "chardev-add",
+# "arguments" : { "id" : "baz",
+# "backend" : { "type" : "pty", "data" : {} } } }
+# <- { "return": { "pty" : "/dev/pty/42" } }
+#
##
{ 'command': 'chardev-add', 'data': {'id' : 'str',
'backend' : 'ChardevBackend' },
@@ -3144,6 +4080,12 @@
# Returns: Nothing on success
#
# Since: 1.4
+#
+# Example:
+#
+# -> { "execute": "chardev-remove", "arguments": { "id" : "foo" } }
+# <- { "return": {} }
+#
##
{ 'command': 'chardev-remove', 'data': {'id': 'str'} }
@@ -3166,6 +4108,12 @@
# Returns: a list of TpmModel
#
# Since: 1.5
+#
+# Example:
+#
+# -> { "execute": "query-tpm-models" }
+# <- { "return": [ "tpm-tis" ] }
+#
##
{ 'command': 'query-tpm-models', 'returns': ['TpmModel'] }
@@ -3188,6 +4136,12 @@
# Returns: a list of TpmType
#
# Since: 1.5
+#
+# Example:
+#
+# -> { "execute": "query-tpm-types" }
+# <- { "return": [ "passthrough" ] }
+#
##
{ 'command': 'query-tpm-types', 'returns': ['TpmType'] }
@@ -3244,6 +4198,25 @@
# Returns: @TPMInfo on success
#
# Since: 1.5
+#
+# Example:
+#
+# -> { "execute": "query-tpm" }
+# <- { "return":
+# [
+# { "model": "tpm-tis",
+# "options":
+# { "type": "passthrough",
+# "data":
+# { "cancel-path": "/sys/class/misc/tpm0/device/cancel",
+# "path": "/dev/tpm0"
+# }
+# },
+# "id": "tpm0"
+# }
+# ]
+# }
+#
##
{ 'command': 'query-tpm', 'returns': ['TPMInfo'] }
@@ -3370,6 +4343,27 @@
# @option). Returns an error if the given @option doesn't exist.
#
# Since 1.5
+#
+# Example:
+#
+# -> { "execute": "query-command-line-options", "arguments": { "option": "option-rom" } }
+# <- { "return": [
+# {
+# "parameters": [
+# {
+# "name": "romfile",
+# "type": "string"
+# },
+# {
+# "name": "bootindex",
+# "type": "number"
+# }
+# ],
+# "option": "option-rom"
+# }
+# ]
+# }
+#
##
{'command': 'query-command-line-options', 'data': { '*option': 'str' },
'returns': ['CommandLineOptionInfo'] }
@@ -3481,6 +4475,36 @@
# isn't a NIC.
#
# Since: 1.6
+#
+# Example:
+#
+# -> { "execute": "query-rx-filter", "arguments": { "name": "vnet0" } }
+# <- { "return": [
+# {
+# "promiscuous": true,
+# "name": "vnet0",
+# "main-mac": "52:54:00:12:34:56",
+# "unicast": "normal",
+# "vlan": "normal",
+# "vlan-table": [
+# 4,
+# 0
+# ],
+# "unicast-table": [
+# ],
+# "multicast": "normal",
+# "multicast-overflow": false,
+# "unicast-overflow": false,
+# "multicast-table": [
+# "01:00:5e:00:00:01",
+# "33:33:00:00:00:01",
+# "33:33:ff:12:34:56"
+# ],
+# "broadcast-allowed": false
+# }
+# ]
+# }
+#
##
{ 'command': 'query-rx-filter', 'data': { '*name': 'str' },
'returns': ['RxFilterInfo'] }
@@ -3593,6 +4617,42 @@
#
# Note: this command is experimental, and not a stable API.
#
+# Example:
+#
+# Press left mouse button.
+#
+# -> { "execute": "x-input-send-event",
+# "arguments": { "console": 0,
+# "events": [ { "type": "btn",
+# "data" : { "down": true, "button": "Left" } } ] } }
+# <- { "return": {} }
+#
+# -> { "execute": "x-input-send-event",
+# "arguments": { "console": 0,
+# "events": [ { "type": "btn",
+# "data" : { "down": false, "button": "Left" } } ] } }
+# <- { "return": {} }
+#
+# 2. Press ctrl-alt-del.
+#
+# -> { "execute": "x-input-send-event",
+# "arguments": { "console": 0, "events": [
+# { "type": "key", "data" : { "down": true,
+# "key": {"type": "qcode", "data": "ctrl" } } },
+# { "type": "key", "data" : { "down": true,
+# "key": {"type": "qcode", "data": "alt" } } },
+# { "type": "key", "data" : { "down": true,
+# "key": {"type": "qcode", "data": "delete" } } } ] } }
+# <- { "return": {} }
+#
+# 3. Move mouse pointer to absolute coordinates (20000, 400).
+#
+# -> { "execute": "x-input-send-event" ,
+# "arguments": { "console": 0, "events": [
+# { "type": "abs", "data" : { "axis": "X", "value" : 20000 } },
+# { "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } }
+# <- { "return": {} }
+#
##
{ 'command': 'x-input-send-event',
'data': { '*console':'int', 'events': [ 'InputEvent' ] } }
@@ -3691,6 +4751,30 @@
# Returns: a list of @Memdev.
#
# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "query-memdev" }
+# <- { "return": [
+# {
+# "size": 536870912,
+# "merge": false,
+# "dump": true,
+# "prealloc": false,
+# "host-nodes": [0, 1],
+# "policy": "bind"
+# },
+# {
+# "size": 536870912,
+# "merge": false,
+# "dump": true,
+# "prealloc": true,
+# "host-nodes": [2, 3],
+# "policy": "preferred"
+# }
+# ]
+# }
+#
##
{ 'command': 'query-memdev', 'returns': ['Memdev'] }
@@ -3744,6 +4828,22 @@
# Lists available memory devices and their state
#
# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "query-memory-devices" }
+# <- { "return": [ { "data":
+# { "addr": 5368709120,
+# "hotpluggable": true,
+# "hotplugged": true,
+# "id": "d1",
+# "memdev": "/objects/memX",
+# "node": 0,
+# "size": 1073741824,
+# "slot": 0},
+# "type": "dimm"
+# } ] }
+#
##
{ 'command': 'query-memory-devices', 'returns': ['MemoryDeviceInfo'] }
@@ -3785,6 +4885,16 @@
# which might be reported via _OST method
#
# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "query-acpi-ospm-status" }
+# <- { "return": [ { "device": "d1", "slot": "0", "slot-type": "DIMM", "source": 1, "status": 0},
+# { "slot": "1", "slot-type": "DIMM", "source": 0, "status": 0},
+# { "slot": "2", "slot-type": "DIMM", "source": 0, "status": 0},
+# { "slot": "3", "slot-type": "DIMM", "source": 0, "status": 0}
+# ]}
+#
##
{ 'command': 'query-acpi-ospm-status', 'returns': ['ACPIOSTInfo'] }
@@ -3851,6 +4961,12 @@
# command.
#
# Since: 2.1
+#
+# Example:
+#
+# -> { "execute": "rtc-reset-reinjection" }
+# <- { "return": {} }
+#
##
{ 'command': 'rtc-reset-reinjection' }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index e458023..d5b6ed1 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -410,6 +410,87 @@
# Returns: a list of @BlockInfo describing each virtual block device
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-block" }
+# <- {
+# "return":[
+# {
+# "io-status": "ok",
+# "device":"ide0-hd0",
+# "locked":false,
+# "removable":false,
+# "inserted":{
+# "ro":false,
+# "drv":"qcow2",
+# "encrypted":false,
+# "file":"disks/test.qcow2",
+# "backing_file_depth":1,
+# "bps":1000000,
+# "bps_rd":0,
+# "bps_wr":0,
+# "iops":1000000,
+# "iops_rd":0,
+# "iops_wr":0,
+# "bps_max": 8000000,
+# "bps_rd_max": 0,
+# "bps_wr_max": 0,
+# "iops_max": 0,
+# "iops_rd_max": 0,
+# "iops_wr_max": 0,
+# "iops_size": 0,
+# "detect_zeroes": "on",
+# "write_threshold": 0,
+# "image":{
+# "filename":"disks/test.qcow2",
+# "format":"qcow2",
+# "virtual-size":2048000,
+# "backing_file":"base.qcow2",
+# "full-backing-filename":"disks/base.qcow2",
+# "backing-filename-format":"qcow2",
+# "snapshots":[
+# {
+# "id": "1",
+# "name": "snapshot1",
+# "vm-state-size": 0,
+# "date-sec": 10000200,
+# "date-nsec": 12,
+# "vm-clock-sec": 206,
+# "vm-clock-nsec": 30
+# }
+# ],
+# "backing-image":{
+# "filename":"disks/base.qcow2",
+# "format":"qcow2",
+# "virtual-size":2048000
+# }
+# }
+# },
+# "type":"unknown"
+# },
+# {
+# "io-status": "ok",
+# "device":"ide1-cd0",
+# "locked":false,
+# "removable":true,
+# "type":"unknown"
+# },
+# {
+# "device":"floppy0",
+# "locked":false,
+# "removable":true,
+# "type":"unknown"
+# },
+# {
+# "device":"sd0",
+# "locked":false,
+# "removable":true,
+# "type":"unknown"
+# }
+# ]
+# }
+#
##
{ 'command': 'query-block', 'returns': ['BlockInfo'] }
@@ -496,6 +577,94 @@
# Returns: A list of @BlockStats for each virtual block devices.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-blockstats" }
+# <- {
+# "return":[
+# {
+# "device":"ide0-hd0",
+# "parent":{
+# "stats":{
+# "wr_highest_offset":3686448128,
+# "wr_bytes":9786368,
+# "wr_operations":751,
+# "rd_bytes":122567168,
+# "rd_operations":36772
+# "wr_total_times_ns":313253456
+# "rd_total_times_ns":3465673657
+# "flush_total_times_ns":49653
+# "flush_operations":61,
+# "rd_merged":0,
+# "wr_merged":0
+# }
+# },
+# "stats":{
+# "wr_highest_offset":2821110784,
+# "wr_bytes":9786368,
+# "wr_operations":692,
+# "rd_bytes":122739200,
+# "rd_operations":36604
+# "flush_operations":51,
+# "wr_total_times_ns":313253456
+# "rd_total_times_ns":3465673657
+# "flush_total_times_ns":49653,
+# "rd_merged":0,
+# "wr_merged":0
+# }
+# },
+# {
+# "device":"ide1-cd0",
+# "stats":{
+# "wr_highest_offset":0,
+# "wr_bytes":0,
+# "wr_operations":0,
+# "rd_bytes":0,
+# "rd_operations":0
+# "flush_operations":0,
+# "wr_total_times_ns":0
+# "rd_total_times_ns":0
+# "flush_total_times_ns":0,
+# "rd_merged":0,
+# "wr_merged":0
+# }
+# },
+# {
+# "device":"floppy0",
+# "stats":{
+# "wr_highest_offset":0,
+# "wr_bytes":0,
+# "wr_operations":0,
+# "rd_bytes":0,
+# "rd_operations":0
+# "flush_operations":0,
+# "wr_total_times_ns":0
+# "rd_total_times_ns":0
+# "flush_total_times_ns":0,
+# "rd_merged":0,
+# "wr_merged":0
+# }
+# },
+# {
+# "device":"sd0",
+# "stats":{
+# "wr_highest_offset":0,
+# "wr_bytes":0,
+# "wr_operations":0,
+# "rd_bytes":0,
+# "rd_operations":0
+# "flush_operations":0,
+# "wr_total_times_ns":0
+# "rd_total_times_ns":0
+# "flush_total_times_ns":0,
+# "rd_merged":0,
+# "wr_merged":0
+# }
+# }
+# ]
+# }
+#
##
{ 'command': 'query-blockstats',
'data': { '*query-nodes': 'bool' },
@@ -639,6 +808,13 @@
# occur if an invalid password is specified.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0",
+# "password": "12345" } }
+# <- { "return": {} }
+#
##
{ 'command': 'block_passwd', 'data': {'*device': 'str',
'*node-name': 'str', 'password': 'str'} }
@@ -661,6 +837,12 @@
# If @device is not a valid block device, DeviceNotFound
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "block_resize", "arguments": { "device": "scratch", "size": 1073741824 } }
+# <- { "return": {} }
+#
##
{ 'command': 'block_resize', 'data': { '*device': 'str',
'*node-name': 'str',
@@ -799,6 +981,14 @@
# If @device is not a valid block device, DeviceNotFound
#
# Since 0.14.0
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-sync", "arguments": { "device": "ide-hd0",
+# "snapshot-file":
+# "/some/place/my-image",
+# "format": "qcow2" } }
+# <- { "return": {} }
+#
##
{ 'command': 'blockdev-snapshot-sync',
'data': 'BlockdevSnapshot' }
@@ -823,6 +1013,10 @@
# when specifying the string or the image chain may
# not be able to be reopened again.
#
+# Returns: Nothing on success
+#
+# If "device" does not exist or cannot be determined, DeviceNotFound
+#
# Since: 2.1
##
{ 'command': 'change-backing-file',
@@ -890,6 +1084,12 @@
#
# Since: 1.3
#
+# Example:
+#
+# -> { "execute": "block-commit", "arguments": { "device": "virtio0",
+# "top": "/tmp/snap1.qcow2" } }
+# <- { "return": {} }
+#
##
{ 'command': 'block-commit',
'data': { 'device': 'str', '*base': 'str', '*top': 'str',
@@ -911,6 +1111,14 @@
# If @device is not a valid block device, DeviceNotFound
#
# Since 1.6
+#
+# Example:
+#
+# -> { "execute": "drive-backup", "arguments": { "device": "drive0",
+# "sync": "full",
+# "target": "backup.img" } }
+# <- { "return": {} }
+#
##
{ 'command': 'drive-backup', 'data': 'DriveBackup' }
@@ -926,6 +1134,13 @@
# For the arguments, see the documentation of BlockdevBackup.
#
# Since 2.3
+#
+# Example:
+# -> { "execute": "blockdev-backup", "arguments": { "device": "src-id",
+# "sync": "full",
+# "target": "tgt-id" } }
+# <- { "return": {} }
+#
##
{ 'command': 'blockdev-backup', 'data': 'BlockdevBackup' }
@@ -938,6 +1153,55 @@
# Returns: the list of BlockDeviceInfo
#
# Since 2.0
+#
+# Example:
+#
+# -> { "execute": "query-named-block-nodes" }
+# <- { "return": [ { "ro":false,
+# "drv":"qcow2",
+# "encrypted":false,
+# "file":"disks/test.qcow2",
+# "node-name": "my-node",
+# "backing_file_depth":1,
+# "bps":1000000,
+# "bps_rd":0,
+# "bps_wr":0,
+# "iops":1000000,
+# "iops_rd":0,
+# "iops_wr":0,
+# "bps_max": 8000000,
+# "bps_rd_max": 0,
+# "bps_wr_max": 0,
+# "iops_max": 0,
+# "iops_rd_max": 0,
+# "iops_wr_max": 0,
+# "iops_size": 0,
+# "write_threshold": 0,
+# "image":{
+# "filename":"disks/test.qcow2",
+# "format":"qcow2",
+# "virtual-size":2048000,
+# "backing_file":"base.qcow2",
+# "full-backing-filename":"disks/base.qcow2",
+# "backing-filename-format":"qcow2",
+# "snapshots":[
+# {
+# "id": "1",
+# "name": "snapshot1",
+# "vm-state-size": 0,
+# "date-sec": 10000200,
+# "date-nsec": 12,
+# "vm-clock-sec": 206,
+# "vm-clock-nsec": 30
+# }
+# ],
+# "backing-image":{
+# "filename":"disks/base.qcow2",
+# "format":"qcow2",
+# "virtual-size":2048000
+# }
+# } } ] }
+#
##
{ 'command': 'query-named-block-nodes', 'returns': [ 'BlockDeviceInfo' ] }
@@ -997,6 +1261,15 @@
# If @device is not a valid block device, DeviceNotFound
#
# Since 1.3
+#
+# Example:
+#
+# -> { "execute": "drive-mirror", "arguments": { "device": "ide-hd0",
+# "target": "/some/place/my-image",
+# "sync": "full",
+# "format": "qcow2" } }
+# <- { "return": {} }
+#
##
{ 'command': 'drive-mirror',
'data': { 'device': 'str', 'target': 'str', '*format': 'str',
@@ -1030,6 +1303,13 @@
# block-dirty-bitmap-add
#
# Since 2.4
+#
+# Example:
+#
+# -> { "execute": "block-dirty-bitmap-add", "arguments": { "node": "drive0",
+# "name": "bitmap0" } }
+# <- { "return": {} }
+#
##
{ 'struct': 'BlockDirtyBitmapAdd',
'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32' } }
@@ -1064,6 +1344,13 @@
# if @name is frozen by an operation, GenericError
#
# Since 2.4
+#
+# Example:
+#
+# -> { "execute": "block-dirty-bitmap-remove", "arguments": { "node": "drive0",
+# "name": "bitmap0" } }
+# <- { "return": {} }
+#
##
{ 'command': 'block-dirty-bitmap-remove',
'data': 'BlockDirtyBitmap' }
@@ -1080,6 +1367,13 @@
# If @name is not found, GenericError with an explanation
#
# Since 2.4
+#
+# Example:
+#
+# -> { "execute": "block-dirty-bitmap-clear", "arguments": { "node": "drive0",
+# "name": "bitmap0" } }
+# <- { "return": {} }
+#
##
{ 'command': 'block-dirty-bitmap-clear',
'data': 'BlockDirtyBitmap' }
@@ -1145,6 +1439,25 @@
# If @device is not a valid block device, DeviceNotFound
#
# Since: 1.1
+#
+# Example:
+#
+# -> { "execute": "block_set_io_throttle", "arguments": { "device": "virtio0",
+# "bps": 1000000,
+# "bps_rd": 0,
+# "bps_wr": 0,
+# "iops": 0,
+# "iops_rd": 0,
+# "iops_wr": 0,
+# "bps_max": 8000000,
+# "bps_rd_max": 0,
+# "bps_wr_max": 0,
+# "iops_max": 0,
+# "iops_rd_max": 0,
+# "iops_wr_max": 0,
+# "iops_size": 0 } }
+# <- { "return": {} }
+#
##
{ 'command': 'block_set_io_throttle',
'data': { 'device': 'str', 'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
@@ -1203,6 +1516,12 @@
# If @device does not exist, DeviceNotFound
#
# Since: 1.1
+#
+# Example:
+#
+# -> { "execute": "block-stream", "arguments": { "device": "virtio0",
+# "base": "/tmp/master.qcow2" } }
+# <- { "return": {} }
##
{ 'command': 'block-stream',
'data': { 'device': 'str', '*base': 'str', '*backing-file': 'str',
@@ -1895,6 +2214,44 @@
# @options: block device options for the new device
#
# Since: 1.7
+#
+# Example:
+#
+# 1.
+# -> { "execute": "blockdev-add",
+# "arguments": { "options" : { "driver": "qcow2",
+# "file": { "driver": "file",
+# "filename": "test.qcow2" } } } }
+# <- { "return": {} }
+
+# 2.
+# -> { "execute": "blockdev-add",
+# "arguments": {
+# "options": {
+# "driver": "qcow2",
+# "id": "my_disk",
+# "discard": "unmap",
+# "cache": {
+# "direct": true,
+# "writeback": true
+# },
+# "file": {
+# "driver": "file",
+# "filename": "/tmp/test.qcow2"
+# },
+# "backing": {
+# "driver": "raw",
+# "file": {
+# "driver": "file",
+# "filename": "/dev/fdset/4"
+# }
+# }
+# }
+# }
+# }
+#
+# <- { "return": {} }
+#
##
{ 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
@@ -2137,6 +2494,14 @@
# Use 0 to disable the threshold.
#
# Since: 2.3
+#
+# Example:
+#
+# -> { "execute": "block-set-write-threshold",
+# "arguments": { "node-name": "mydev",
+# "write-threshold": 17179869184 } }
+# <- { "return": {} }
+#
##
{ 'command': 'block-set-write-threshold',
'data': { 'node-name': 'str', 'write-threshold': 'uint64' } }
diff --git a/qapi/block.json b/qapi/block.json
index 84022f1..9902b94 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -71,6 +71,15 @@
# BlockFormatFeatureNotSupported
#
# Since 1.7
+#
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-internal-sync",
+# "arguments": { "device": "ide-hd0",
+# "name": "snapshot0" }
+# }
+# <- { "return": {} }
+#
##
{ 'command': 'blockdev-snapshot-internal-sync',
'data': 'BlockdevSnapshotInternal' }
@@ -97,6 +106,24 @@
# If @id and @name are both not specified, GenericError
#
# Since 1.7
+#
+# Example:
+#
+# -> { "execute": "blockdev-snapshot-delete-internal-sync",
+# "arguments": { "device": "ide-hd0",
+# "name": "snapshot0" }
+# }
+# <- { "return": {
+# "id": "1",
+# "name": "snapshot0",
+# "vm-state-size": 0,
+# "date-sec": 1000012,
+# "date-nsec": 10,
+# "vm-clock-sec": 100,
+# "vm-clock-nsec": 20
+# }
+# }
+#
##
{ 'command': 'blockdev-snapshot-delete-internal-sync',
'data': { 'device': 'str', '*id': 'str', '*name': 'str'},
@@ -118,6 +145,11 @@
# Notes: Ejecting a device will no media results in success
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "eject", "arguments": { "device": "ide1-cd0" } }
+# <- { "return": {} }
##
{ 'command': 'eject', 'data': {'device': 'str', '*force': 'bool'} }
diff --git a/qapi/common.json b/qapi/common.json
index bad56bf..4e94c89 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -74,6 +74,21 @@
# Returns: A @VersionInfo object describing the current version of QEMU.
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-version" }
+# <- {
+# "return":{
+# "qemu":{
+# "major":0,
+# "minor":11,
+# "micro":5
+# },
+# "package":""
+# }
+# }
+#
##
{ 'command': 'query-version', 'returns': 'VersionInfo' }
@@ -96,6 +111,23 @@
# Returns: A list of @CommandInfo for all supported commands
#
# Since: 0.14.0
+#
+# Example:
+#
+# -> { "execute": "query-commands" }
+# <- {
+# "return":[
+# {
+# "name":"query-balloon"
+# },
+# {
+# "name":"system_powerdown"
+# }
+# ]
+# }
+#
+# Note: This example has been shortened as the real response is too long.
+#
##
{ 'command': 'query-commands', 'returns': ['CommandInfo'] }
diff --git a/qapi/rocker.json b/qapi/rocker.json
index 2fe7fdf..7cfccc4 100644
--- a/qapi/rocker.json
+++ b/qapi/rocker.json
@@ -22,6 +22,12 @@
# Returns: @Rocker information
#
# Since: 2.4
+#
+# Example:
+#
+# -> { "execute": "query-rocker", "arguments": { "name": "sw1" } }
+# <- { "return": {"name": "sw1", "ports": 2, "id": 1327446905938}}
+#
##
{ 'command': 'query-rocker',
'data': { 'name': 'str' },
@@ -85,6 +91,16 @@
# Returns: @Rocker information
#
# Since: 2.4
+#
+# Example:
+#
+# -> { "execute": "query-rocker-ports", "arguments": { "name": "sw1" } }
+# <- { "return": [ {"duplex": "full", "enabled": true, "name": "sw1.1",
+# "autoneg": "off", "link-up": true, "speed": 10000},
+# {"duplex": "full", "enabled": true, "name": "sw1.2",
+# "autoneg": "off", "link-up": true, "speed": 10000}
+# ]}
+#
##
{ 'command': 'query-rocker-ports',
'data': { 'name': 'str' },
@@ -218,6 +234,19 @@
# Returns: @Rocker OF-DPA flow information
#
# Since: 2.4
+#
+# Example:
+#
+# -> { "execute": "query-rocker-of-dpa-flows", "arguments": { "name": "sw1" } }
+# <- { "return": [ {"key": {"in-pport": 0, "priority": 1, "tbl-id": 0},
+# "hits": 138,
+# "cookie": 0,
+# "action": {"goto-tbl": 10},
+# "mask": {"in-pport": 4294901760}
+# },
+# {...more...},
+# ]}
+#
##
{ 'command': 'query-rocker-of-dpa-flows',
'data': { 'name': 'str', '*tbl-id': 'uint32' },
@@ -280,6 +309,20 @@
# Returns: @Rocker OF-DPA group information
#
# Since: 2.4
+#
+# Example:
+#
+# -> { "execute": "query-rocker-of-dpa-groups", "arguments": { "name": "sw1" } }
+# <- { "return": [ {"type": 0, "out-pport": 2, "pport": 2, "vlan-id": 3841,
+# "pop-vlan": 1, "id": 251723778},
+# {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3841,
+# "pop-vlan": 1, "id": 251723776},
+# {"type": 0, "out-pport": 1, "pport": 1, "vlan-id": 3840,
+# "pop-vlan": 1, "id": 251658241},
+# {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3840,
+# "pop-vlan": 1, "id": 251658240}
+# ]}
+#
##
{ 'command': 'query-rocker-of-dpa-groups',
'data': { 'name': 'str', '*type': 'uint8' },
diff --git a/qapi/trace.json b/qapi/trace.json
index 01b0a52..5111640 100644
--- a/qapi/trace.json
+++ b/qapi/trace.json
@@ -45,6 +45,12 @@
# Returns: a list of @TraceEventInfo for the matching events
#
# Since 2.2
+#
+# Example:
+#
+# -> { "execute": "trace-event-get-state", "arguments": { "name": "qemu_memalign" } }
+# <- { "return": [ { "name": "qemu_memalign", "state": "disabled" } ] }
+#
##
{ 'command': 'trace-event-get-state',
'data': {'name': 'str'},
@@ -60,6 +66,12 @@
# @ignore-unavailable: #optional Do not match unavailable events with @name.
#
# Since 2.2
+#
+# Example:
+#
+# -> { "execute": "trace-event-set-state", "arguments": { "name": "qemu_memalign", "enable": "true" } }
+# <- { "return": {} }
+#
##
{ 'command': 'trace-event-set-state',
'data': {'name': 'str', 'enable': 'bool', '*ignore-unavailable': 'bool'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 910edf5..c09918b 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -65,212 +65,46 @@ EQMP
.args_type = "",
.mhandler.cmd_new = qmp_marshal_quit,
},
-
-SQMP
-quit
-----
-
-Quit the emulator.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "quit" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "eject",
.args_type = "force:-f,device:B",
.mhandler.cmd_new = qmp_marshal_eject,
},
-
-SQMP
-eject
------
-
-Eject a removable medium.
-
-Arguments:
-
-- force: force ejection (json-bool, optional)
-- device: device name (json-string)
-
-Example:
-
--> { "execute": "eject", "arguments": { "device": "ide1-cd0" } }
-<- { "return": {} }
-
-Note: The "force" argument defaults to false.
-
-EQMP
-
{
.name = "change",
.args_type = "device:B,target:F,arg:s?",
.mhandler.cmd_new = qmp_marshal_change,
},
-
-SQMP
-change
-------
-
-Change a removable medium or VNC configuration.
-
-Arguments:
-
-- "device": device name (json-string)
-- "target": filename or item (json-string)
-- "arg": additional argument (json-string, optional)
-
-Examples:
-
-1. Change a removable medium
-
--> { "execute": "change",
- "arguments": { "device": "ide1-cd0",
- "target": "/srv/images/Fedora-12-x86_64-DVD.iso" } }
-<- { "return": {} }
-
-2. Change VNC password
-
--> { "execute": "change",
- "arguments": { "device": "vnc", "target": "password",
- "arg": "foobar1" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "screendump",
.args_type = "filename:F",
.mhandler.cmd_new = qmp_marshal_screendump,
},
-
-SQMP
-screendump
-----------
-
-Save screen into PPM image.
-
-Arguments:
-
-- "filename": file path (json-string)
-
-Example:
-
--> { "execute": "screendump", "arguments": { "filename": "/tmp/image" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "stop",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_stop,
},
-
-SQMP
-stop
-----
-
-Stop the emulator.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "stop" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "cont",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_cont,
},
-
-SQMP
-cont
-----
-
-Resume emulation.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "cont" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "system_wakeup",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_system_wakeup,
},
-
-SQMP
-system_wakeup
--------------
-
-Wakeup guest from suspend.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "system_wakeup" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "system_reset",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_system_reset,
},
-
-SQMP
-system_reset
-------------
-
-Reset the system.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "system_reset" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "system_powerdown",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_system_powerdown,
},
-
-SQMP
-system_powerdown
-----------------
-
-Send system power down event.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "system_powerdown" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "device_add",
.args_type = "device:O",
@@ -278,513 +112,96 @@ EQMP
.help = "add device, like -device on the command line",
.mhandler.cmd_new = qmp_device_add,
},
-
-SQMP
-device_add
-----------
-
-Add a device.
-
-Arguments:
-
-- "driver": the name of the new device's driver (json-string)
-- "bus": the device's parent bus (device tree path, json-string, optional)
-- "id": the device's ID, must be unique (json-string)
-- device properties
-
-Example:
-
--> { "execute": "device_add", "arguments": { "driver": "e1000", "id": "net1" } }
-<- { "return": {} }
-
-Notes:
-
-(1) For detailed information about this command, please refer to the
- 'docs/qdev-device-use.txt' file.
-
-(2) It's possible to list device properties by running QEMU with the
- "-device DEVICE,\?" command-line argument, where DEVICE is the device's name
-
-EQMP
-
{
.name = "device_del",
.args_type = "id:s",
.mhandler.cmd_new = qmp_marshal_device_del,
},
-
-SQMP
-device_del
-----------
-
-Remove a device.
-
-Arguments:
-
-- "id": the device's ID or QOM path (json-string)
-
-Example:
-
--> { "execute": "device_del", "arguments": { "id": "net1" } }
-<- { "return": {} }
-
-Example:
-
--> { "execute": "device_del", "arguments": { "id": "/machine/peripheral-anon/device[0]" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "send-key",
.args_type = "keys:q,hold-time:i?",
.mhandler.cmd_new = qmp_marshal_send_key,
},
-
-SQMP
-send-key
-----------
-
-Send keys to VM.
-
-Arguments:
-
-keys array:
- - "key": key sequence (a json-array of key union values,
- union can be number or qcode enum)
-
-- hold-time: time to delay key up events, milliseconds. Defaults to 100
- (json-int, optional)
-
-Example:
-
--> { "execute": "send-key",
- "arguments": { "keys": [ { "type": "qcode", "data": "ctrl" },
- { "type": "qcode", "data": "alt" },
- { "type": "qcode", "data": "delete" } ] } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "cpu",
.args_type = "index:i",
.mhandler.cmd_new = qmp_marshal_cpu,
},
-
-SQMP
-cpu
----
-
-Set the default CPU.
-
-Arguments:
-
-- "index": the CPU's index (json-int)
-
-Example:
-
--> { "execute": "cpu", "arguments": { "index": 0 } }
-<- { "return": {} }
-
-Note: CPUs' indexes are obtained with the 'query-cpus' command.
-
-EQMP
-
{
.name = "cpu-add",
.args_type = "id:i",
.mhandler.cmd_new = qmp_marshal_cpu_add,
},
-
-SQMP
-cpu-add
--------
-
-Adds virtual cpu
-
-Arguments:
-
-- "id": cpu id (json-int)
-
-Example:
-
--> { "execute": "cpu-add", "arguments": { "id": 2 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "memsave",
.args_type = "val:l,size:i,filename:s,cpu:i?",
.mhandler.cmd_new = qmp_marshal_memsave,
},
-
-SQMP
-memsave
--------
-
-Save to disk virtual memory dump starting at 'val' of size 'size'.
-
-Arguments:
-
-- "val": the starting address (json-int)
-- "size": the memory size, in bytes (json-int)
-- "filename": file path (json-string)
-- "cpu": virtual CPU index (json-int, optional)
-
-Example:
-
--> { "execute": "memsave",
- "arguments": { "val": 10,
- "size": 100,
- "filename": "/tmp/virtual-mem-dump" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "pmemsave",
.args_type = "val:l,size:i,filename:s",
.mhandler.cmd_new = qmp_marshal_pmemsave,
},
-
-SQMP
-pmemsave
---------
-
-Save to disk physical memory dump starting at 'val' of size 'size'.
-
-Arguments:
-
-- "val": the starting address (json-int)
-- "size": the memory size, in bytes (json-int)
-- "filename": file path (json-string)
-
-Example:
-
--> { "execute": "pmemsave",
- "arguments": { "val": 10,
- "size": 100,
- "filename": "/tmp/physical-mem-dump" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "inject-nmi",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_inject_nmi,
},
-
-SQMP
-inject-nmi
-----------
-
-Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).
-
-Arguments: None.
-
-Example:
-
--> { "execute": "inject-nmi" }
-<- { "return": {} }
-
-Note: inject-nmi fails when the guest doesn't support injecting.
-
-EQMP
-
{
.name = "ringbuf-write",
.args_type = "device:s,data:s,format:s?",
.mhandler.cmd_new = qmp_marshal_ringbuf_write,
},
-
-SQMP
-ringbuf-write
--------------
-
-Write to a ring buffer character device.
-
-Arguments:
-
-- "device": ring buffer character device name (json-string)
-- "data": data to write (json-string)
-- "format": data format (json-string, optional)
- - Possible values: "utf8" (default), "base64"
- Bug: invalid base64 is currently not rejected.
- Whitespace *is* invalid.
-
-Example:
-
--> { "execute": "ringbuf-write",
- "arguments": { "device": "foo",
- "data": "abcdefgh",
- "format": "utf8" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "ringbuf-read",
.args_type = "device:s,size:i,format:s?",
.mhandler.cmd_new = qmp_marshal_ringbuf_read,
},
-
-SQMP
-ringbuf-read
--------------
-
-Read from a ring buffer character device.
-
-Arguments:
-
-- "device": ring buffer character device name (json-string)
-- "size": how many bytes to read at most (json-int)
- - Number of data bytes, not number of characters in encoded data
-- "format": data format (json-string, optional)
- - Possible values: "utf8" (default), "base64"
- - Naturally, format "utf8" works only when the ring buffer
- contains valid UTF-8 text. Invalid UTF-8 sequences get
- replaced. Bug: replacement doesn't work. Bug: can screw
- up on encountering NUL characters, after the ring buffer
- lost data, and when reading stops because the size limit
- is reached.
-
-Example:
-
--> { "execute": "ringbuf-read",
- "arguments": { "device": "foo",
- "size": 1000,
- "format": "utf8" } }
-<- {"return": "abcdefgh"}
-
-EQMP
-
{
.name = "xen-save-devices-state",
.args_type = "filename:F",
.mhandler.cmd_new = qmp_marshal_xen_save_devices_state,
},
-
-SQMP
-xen-save-devices-state
--------
-
-Save the state of all devices to file. The RAM and the block devices
-of the VM are not saved by this command.
-
-Arguments:
-
-- "filename": the file to save the state of the devices to as binary
-data. See xen-save-devices-state.txt for a description of the binary
-format.
-
-Example:
-
--> { "execute": "xen-save-devices-state",
- "arguments": { "filename": "/tmp/save" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "xen-set-global-dirty-log",
.args_type = "enable:b",
.mhandler.cmd_new = qmp_marshal_xen_set_global_dirty_log,
},
-
-SQMP
-xen-set-global-dirty-log
--------
-
-Enable or disable the global dirty log mode.
-
-Arguments:
-
-- "enable": Enable it or disable it.
-
-Example:
-
--> { "execute": "xen-set-global-dirty-log",
- "arguments": { "enable": true } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "migrate",
.args_type = "detach:-d,blk:-b,inc:-i,uri:s",
.mhandler.cmd_new = qmp_marshal_migrate,
},
-
-SQMP
-migrate
--------
-
-Migrate to URI.
-
-Arguments:
-
-- "blk": block migration, full disk copy (json-bool, optional)
-- "inc": incremental disk copy (json-bool, optional)
-- "uri": Destination URI (json-string)
-
-Example:
-
--> { "execute": "migrate", "arguments": { "uri": "tcp:0:4446" } }
-<- { "return": {} }
-
-Notes:
-
-(1) The 'query-migrate' command should be used to check migration's progress
- and final result (this information is provided by the 'status' member)
-(2) All boolean arguments default to false
-(3) The user Monitor's "detach" argument is invalid in QMP and should not
- be used
-
-EQMP
-
{
.name = "migrate_cancel",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_migrate_cancel,
},
-
-SQMP
-migrate_cancel
---------------
-
-Cancel the current migration.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "migrate_cancel" }
-<- { "return": {} }
-
-EQMP
-
{
.name = "migrate-incoming",
.args_type = "uri:s",
.mhandler.cmd_new = qmp_marshal_migrate_incoming,
},
-
-SQMP
-migrate-incoming
-----------------
-
-Continue an incoming migration
-
-Arguments:
-
-- "uri": Source/listening URI (json-string)
-
-Example:
-
--> { "execute": "migrate-incoming", "arguments": { "uri": "tcp::4446" } }
-<- { "return": {} }
-
-Notes:
-
-(1) QEMU must be started with -incoming defer to allow migrate-incoming to
- be used
-(2) The uri format is the same as for -incoming
-
-EQMP
{
.name = "migrate-set-cache-size",
.args_type = "value:o",
.mhandler.cmd_new = qmp_marshal_migrate_set_cache_size,
},
-
-SQMP
-migrate-set-cache-size
-----------------------
-
-Set cache size to be used by XBZRLE migration, the cache size will be rounded
-down to the nearest power of 2
-
-Arguments:
-
-- "value": cache size in bytes (json-int)
-
-Example:
-
--> { "execute": "migrate-set-cache-size", "arguments": { "value": 536870912 } }
-<- { "return": {} }
-
-EQMP
{
.name = "query-migrate-cache-size",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_migrate_cache_size,
},
-
-SQMP
-query-migrate-cache-size
-------------------------
-
-Show cache size to be used by XBZRLE migration
-
-returns a json-object with the following information:
-- "size" : json-int
-
-Example:
-
--> { "execute": "query-migrate-cache-size" }
-<- { "return": 67108864 }
-
-EQMP
-
{
.name = "migrate_set_speed",
.args_type = "value:o",
.mhandler.cmd_new = qmp_marshal_migrate_set_speed,
},
-
-SQMP
-migrate_set_speed
------------------
-
-Set maximum speed for migrations.
-
-Arguments:
-
-- "value": maximum speed, in bytes per second (json-int)
-
-Example:
-
--> { "execute": "migrate_set_speed", "arguments": { "value": 1024 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "migrate_set_downtime",
.args_type = "value:T",
.mhandler.cmd_new = qmp_marshal_migrate_set_downtime,
},
-
-SQMP
-migrate_set_downtime
---------------------
-
-Set maximum tolerated downtime (in seconds) for migrations.
-
-Arguments:
-
-- "value": maximum downtime (json-number)
-
-Example:
-
--> { "execute": "migrate_set_downtime", "arguments": { "value": 0.1 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "client_migrate_info",
.args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
@@ -792,33 +209,6 @@ EQMP
.help = "set migration information for remote display",
.mhandler.cmd_new = qmp_marshal_client_migrate_info,
},
-
-SQMP
-client_migrate_info
--------------------
-
-Set migration information for remote display. This makes the server
-ask the client to automatically reconnect using the new parameters
-once migration finished successfully. Only implemented for SPICE.
-
-Arguments:
-
-- "protocol": must be "spice" (json-string)
-- "hostname": migration target hostname (json-string)
-- "port": spice tcp port for plaintext channels (json-int, optional)
-- "tls-port": spice tcp port for tls-secured channels (json-int, optional)
-- "cert-subject": server certificate subject (json-string, optional)
-
-Example:
-
--> { "execute": "client_migrate_info",
- "arguments": { "protocol": "spice",
- "hostname": "virt42.lab.kraxel.org",
- "port": 1234 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "dump-guest-memory",
.args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
@@ -826,57 +216,11 @@ EQMP
.help = "dump guest memory to file",
.mhandler.cmd_new = qmp_marshal_dump_guest_memory,
},
-
-SQMP
-dump
-
-
-Dump guest memory to file. The file can be processed with crash or gdb.
-
-Arguments:
-
-- "paging": do paging to get guest's memory mapping (json-bool)
-- "protocol": destination file(started with "file:") or destination file
- descriptor (started with "fd:") (json-string)
-- "begin": the starting physical address. It's optional, and should be specified
- with length together (json-int)
-- "length": the memory size, in bytes. It's optional, and should be specified
- with begin together (json-int)
-- "format": the format of guest memory dump. It's optional, and can be
- elf|kdump-zlib|kdump-lzo|kdump-snappy, but non-elf formats will
- conflict with paging and filter, ie. begin and length (json-string)
-
-Example:
-
--> { "execute": "dump-guest-memory", "arguments": { "protocol": "fd:dump" } }
-<- { "return": {} }
-
-Notes:
-
-(1) All boolean arguments default to false
-
-EQMP
-
{
.name = "query-dump-guest-memory-capability",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_dump_guest_memory_capability,
},
-
-SQMP
-query-dump-guest-memory-capability
-----------
-
-Show available formats for 'dump-guest-memory'
-
-Example:
-
--> { "execute": "query-dump-guest-memory-capability" }
-<- { "return": { "formats":
- ["elf", "kdump-zlib", "kdump-lzo", "kdump-snappy"] }
-
-EQMP
-
#if defined TARGET_S390X
{
.name = "dump-skeys",
@@ -884,356 +228,53 @@ EQMP
.mhandler.cmd_new = qmp_marshal_dump_skeys,
},
#endif
-
-SQMP
-dump-skeys
-----------
-
-Save guest storage keys to file.
-
-Arguments:
-
-- "filename": file path (json-string)
-
-Example:
-
--> { "execute": "dump-skeys", "arguments": { "filename": "/tmp/skeys" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "netdev_add",
.args_type = "netdev:O",
.mhandler.cmd_new = qmp_marshal_netdev_add,
},
-
-SQMP
-netdev_add
-----------
-
-Add host network device.
-
-Arguments:
-
-- "type": the device type, "tap", "user", ... (json-string)
-- "id": the device's ID, must be unique (json-string)
-- device options
-
-Example:
-
--> { "execute": "netdev_add",
- "arguments": { "type": "user", "id": "netdev1",
- "dnssearch": "example.org" } }
-<- { "return": {} }
-
-Note: The supported device options are the same ones supported by the '-netdev'
- command-line argument, which are listed in the '-help' output or QEMU's
- manual
-
-EQMP
-
{
.name = "netdev_del",
.args_type = "id:s",
.mhandler.cmd_new = qmp_marshal_netdev_del,
},
-
-SQMP
-netdev_del
-----------
-
-Remove host network device.
-
-Arguments:
-
-- "id": the device's ID, must be unique (json-string)
-
-Example:
-
--> { "execute": "netdev_del", "arguments": { "id": "netdev1" } }
-<- { "return": {} }
-
-
-EQMP
-
{
.name = "object-add",
.args_type = "qom-type:s,id:s,props:q?",
.mhandler.cmd_new = qmp_marshal_object_add,
},
-
-SQMP
-object-add
-----------
-
-Create QOM object.
-
-Arguments:
-
-- "qom-type": the object's QOM type, i.e. the class name (json-string)
-- "id": the object's ID, must be unique (json-string)
-- "props": a dictionary of object property values (optional, json-dict)
-
-Example:
-
--> { "execute": "object-add", "arguments": { "qom-type": "rng-random", "id": "rng1",
- "props": { "filename": "/dev/hwrng" } } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "object-del",
.args_type = "id:s",
.mhandler.cmd_new = qmp_marshal_object_del,
},
-
-SQMP
-object-del
-----------
-
-Remove QOM object.
-
-Arguments:
-
-- "id": the object's ID (json-string)
-
-Example:
-
--> { "execute": "object-del", "arguments": { "id": "rng1" } }
-<- { "return": {} }
-
-
-EQMP
-
-
{
.name = "block_resize",
.args_type = "device:s?,node-name:s?,size:o",
.mhandler.cmd_new = qmp_marshal_block_resize,
},
-
-SQMP
-block_resize
-------------
-
-Resize a block image while a guest is running.
-
-Arguments:
-
-- "device": the device's ID, must be unique (json-string)
-- "node-name": the node name in the block driver state graph (json-string)
-- "size": new size
-
-Example:
-
--> { "execute": "block_resize", "arguments": { "device": "scratch", "size": 1073741824 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-stream",
.args_type = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
.mhandler.cmd_new = qmp_marshal_block_stream,
},
-
-SQMP
-block-stream
-------------
-
-Copy data from a backing file into a block device.
-
-Arguments:
-
-- "device": The device's ID, must be unique (json-string)
-- "base": The file name of the backing image above which copying starts
- (json-string, optional)
-- "backing-file": The backing file string to write into the active layer. This
- filename is not validated.
-
- If a pathname string is such that it cannot be resolved by
- QEMU, that means that subsequent QMP or HMP commands must use
- node-names for the image in question, as filename lookup
- methods will fail.
-
- If not specified, QEMU will automatically determine the
- backing file string to use, or error out if there is no
- obvious choice. Care should be taken when specifying the
- string, to specify a valid filename or protocol.
- (json-string, optional) (Since 2.1)
-- "speed": the maximum speed, in bytes per second (json-int, optional)
-- "on-error": the action to take on an error (default 'report'). 'stop' and
- 'enospc' can only be used if the block device supports io-status.
- (json-string, optional) (Since 2.1)
-
-Example:
-
--> { "execute": "block-stream", "arguments": { "device": "virtio0",
- "base": "/tmp/master.qcow2" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-commit",
.args_type = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
.mhandler.cmd_new = qmp_marshal_block_commit,
},
-
-SQMP
-block-commit
-------------
-
-Live commit of data from overlay image nodes into backing nodes - i.e., writes
-data between 'top' and 'base' into 'base'.
-
-Arguments:
-
-- "device": The device's ID, must be unique (json-string)
-- "base": The file name of the backing image to write data into.
- If not specified, this is the deepest backing image
- (json-string, optional)
-- "top": The file name of the backing image within the image chain,
- which contains the topmost data to be committed down. If
- not specified, this is the active layer. (json-string, optional)
-
-- backing-file: The backing file string to write into the overlay
- image of 'top'. If 'top' is the active layer,
- specifying a backing file string is an error. This
- filename is not validated.
-
- If a pathname string is such that it cannot be
- resolved by QEMU, that means that subsequent QMP or
- HMP commands must use node-names for the image in
- question, as filename lookup methods will fail.
-
- If not specified, QEMU will automatically determine
- the backing file string to use, or error out if
- there is no obvious choice. Care should be taken
- when specifying the string, to specify a valid
- filename or protocol.
- (json-string, optional) (Since 2.1)
-
- If top == base, that is an error.
- If top == active, the job will not be completed by itself,
- user needs to complete the job with the block-job-complete
- command after getting the ready event. (Since 2.0)
-
- If the base image is smaller than top, then the base image
- will be resized to be the same size as top. If top is
- smaller than the base image, the base will not be
- truncated. If you want the base image size to match the
- size of the smaller top, you can safely truncate it
- yourself once the commit operation successfully completes.
- (json-string)
-- "speed": the maximum speed, in bytes per second (json-int, optional)
-
-
-Example:
-
--> { "execute": "block-commit", "arguments": { "device": "virtio0",
- "top": "/tmp/snap1.qcow2" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "drive-backup",
.args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
"bitmap:s?,on-source-error:s?,on-target-error:s?",
.mhandler.cmd_new = qmp_marshal_drive_backup,
},
-
-SQMP
-drive-backup
-------------
-
-Start a point-in-time copy of a block device to a new destination. The
-status of ongoing drive-backup operations can be checked with
-query-block-jobs where the BlockJobInfo.type field has the value 'backup'.
-The operation can be stopped before it has completed using the
-block-job-cancel command.
-
-Arguments:
-
-- "device": the name of the device which should be copied.
- (json-string)
-- "target": the target of the new image. If the file exists, or if it is a
- device, the existing file/device will be used as the new
- destination. If it does not exist, a new file will be created.
- (json-string)
-- "format": the format of the new destination, default is to probe if 'mode' is
- 'existing', else the format of the source
- (json-string, optional)
-- "sync": what parts of the disk image should be copied to the destination;
- possibilities include "full" for all the disk, "top" for only the sectors
- allocated in the topmost image, "incremental" for only the dirty sectors in
- the bitmap, or "none" to only replicate new I/O (MirrorSyncMode).
-- "bitmap": dirty bitmap name for sync==incremental. Must be present if sync
- is "incremental", must NOT be present otherwise.
-- "mode": whether and how QEMU should create a new image
- (NewImageMode, optional, default 'absolute-paths')
-- "speed": the maximum speed, in bytes per second (json-int, optional)
-- "on-source-error": the action to take on an error on the source, default
- 'report'. 'stop' and 'enospc' can only be used
- if the block device supports io-status.
- (BlockdevOnError, optional)
-- "on-target-error": the action to take on an error on the target, default
- 'report' (no limitations, since this applies to
- a different block device than device).
- (BlockdevOnError, optional)
-
-Example:
--> { "execute": "drive-backup", "arguments": { "device": "drive0",
- "sync": "full",
- "target": "backup.img" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "blockdev-backup",
.args_type = "sync:s,device:B,target:B,speed:i?,"
"on-source-error:s?,on-target-error:s?",
.mhandler.cmd_new = qmp_marshal_blockdev_backup,
},
-
-SQMP
-blockdev-backup
----------------
-
-The device version of drive-backup: this command takes an existing named device
-as backup target.
-
-Arguments:
-
-- "device": the name of the device which should be copied.
- (json-string)
-- "target": the name of the backup target device. (json-string)
-- "sync": what parts of the disk image should be copied to the destination;
- possibilities include "full" for all the disk, "top" for only the
- sectors allocated in the topmost image, or "none" to only replicate
- new I/O (MirrorSyncMode).
-- "speed": the maximum speed, in bytes per second (json-int, optional)
-- "on-source-error": the action to take on an error on the source, default
- 'report'. 'stop' and 'enospc' can only be used
- if the block device supports io-status.
- (BlockdevOnError, optional)
-- "on-target-error": the action to take on an error on the target, default
- 'report' (no limitations, since this applies to
- a different block device than device).
- (BlockdevOnError, optional)
-
-Example:
--> { "execute": "blockdev-backup", "arguments": { "device": "src-id",
- "sync": "full",
- "target": "tgt-id" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-job-set-speed",
.args_type = "device:B,speed:o",
@@ -1265,271 +306,37 @@ EQMP
.args_type = "actions:q",
.mhandler.cmd_new = qmp_marshal_transaction,
},
-
-SQMP
-transaction
------------
-
-Atomically operate on one or more block devices. The only supported operations
-for now are drive-backup, internal and external snapshotting. A list of
-dictionaries is accepted, that contains the actions to be performed.
-If there is any failure performing any of the operations, all operations
-for the group are abandoned.
-
-For external snapshots, the dictionary contains the device, the file to use for
-the new snapshot, and the format. The default format, if not specified, is
-qcow2.
-
-Each new snapshot defaults to being created by QEMU (wiping any
-contents if the file already exists), but it is also possible to reuse
-an externally-created file. In the latter case, you should ensure that
-the new image file has the same contents as the current one; QEMU cannot
-perform any meaningful check. Typically this is achieved by using the
-current image file as the backing file for the new image.
-
-On failure, the original disks pre-snapshot attempt will be used.
-
-For internal snapshots, the dictionary contains the device and the snapshot's
-name. If an internal snapshot matching name already exists, the request will
-be rejected. Only some image formats support it, for example, qcow2, rbd,
-and sheepdog.
-
-On failure, qemu will try delete the newly created internal snapshot in the
-transaction. When an I/O error occurs during deletion, the user needs to fix
-it later with qemu-img or other command.
-
-Arguments:
-
-actions array:
- - "type": the operation to perform. The only supported
- value is "blockdev-snapshot-sync". (json-string)
- - "data": a dictionary. The contents depend on the value
- of "type". When "type" is "blockdev-snapshot-sync":
- - "device": device name to snapshot (json-string)
- - "node-name": graph node name to snapshot (json-string)
- - "snapshot-file": name of new image file (json-string)
- - "snapshot-node-name": graph node name of the new snapshot (json-string)
- - "format": format of new image (json-string, optional)
- - "mode": whether and how QEMU should create the snapshot file
- (NewImageMode, optional, default "absolute-paths")
- When "type" is "blockdev-snapshot-internal-sync":
- - "device": device name to snapshot (json-string)
- - "name": name of the new snapshot (json-string)
-
-Example:
-
--> { "execute": "transaction",
- "arguments": { "actions": [
- { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd0",
- "snapshot-file": "/some/place/my-image",
- "format": "qcow2" } },
- { "type": "blockdev-snapshot-sync", "data" : { "node-name": "myfile",
- "snapshot-file": "/some/place/my-image2",
- "snapshot-node-name": "node3432",
- "mode": "existing",
- "format": "qcow2" } },
- { "type": "blockdev-snapshot-sync", "data" : { "device": "ide-hd1",
- "snapshot-file": "/some/place/my-image2",
- "mode": "existing",
- "format": "qcow2" } },
- { "type": "blockdev-snapshot-internal-sync", "data" : {
- "device": "ide-hd2",
- "name": "snapshot0" } } ] } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-dirty-bitmap-add",
.args_type = "node:B,name:s,granularity:i?",
.mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_add,
},
-
-SQMP
-
-block-dirty-bitmap-add
-----------------------
-Since 2.4
-
-Create a dirty bitmap with a name on the device, and start tracking the writes.
-
-Arguments:
-
-- "node": device/node on which to create dirty bitmap (json-string)
-- "name": name of the new dirty bitmap (json-string)
-- "granularity": granularity to track writes with (int, optional)
-
-Example:
-
--> { "execute": "block-dirty-bitmap-add", "arguments": { "node": "drive0",
- "name": "bitmap0" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-dirty-bitmap-remove",
.args_type = "node:B,name:s",
.mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_remove,
},
-
-SQMP
-
-block-dirty-bitmap-remove
--------------------------
-Since 2.4
-
-Stop write tracking and remove the dirty bitmap that was created with
-block-dirty-bitmap-add.
-
-Arguments:
-
-- "node": device/node on which to remove dirty bitmap (json-string)
-- "name": name of the dirty bitmap to remove (json-string)
-
-Example:
-
--> { "execute": "block-dirty-bitmap-remove", "arguments": { "node": "drive0",
- "name": "bitmap0" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-dirty-bitmap-clear",
.args_type = "node:B,name:s",
.mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_clear,
},
-
-SQMP
-
-block-dirty-bitmap-clear
-------------------------
-Since 2.4
-
-Reset the dirty bitmap associated with a node so that an incremental backup
-from this point in time forward will only backup clusters modified after this
-clear operation.
-
-Arguments:
-
-- "node": device/node on which to remove dirty bitmap (json-string)
-- "name": name of the dirty bitmap to remove (json-string)
-
-Example:
-
--> { "execute": "block-dirty-bitmap-clear", "arguments": { "node": "drive0",
- "name": "bitmap0" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "blockdev-snapshot-sync",
.args_type = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
.mhandler.cmd_new = qmp_marshal_blockdev_snapshot_sync,
},
-
-SQMP
-blockdev-snapshot-sync
-----------------------
-
-Synchronous snapshot of a block device. snapshot-file specifies the
-target of the new image. If the file exists, or if it is a device, the
-snapshot will be created in the existing file/device. If does not
-exist, a new file will be created. format specifies the format of the
-snapshot image, default is qcow2.
-
-Arguments:
-
-- "device": device name to snapshot (json-string)
-- "node-name": graph node name to snapshot (json-string)
-- "snapshot-file": name of new image file (json-string)
-- "snapshot-node-name": graph node name of the new snapshot (json-string)
-- "mode": whether and how QEMU should create the snapshot file
- (NewImageMode, optional, default "absolute-paths")
-- "format": format of new image (json-string, optional)
-
-Example:
-
--> { "execute": "blockdev-snapshot-sync", "arguments": { "device": "ide-hd0",
- "snapshot-file":
- "/some/place/my-image",
- "format": "qcow2" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "blockdev-snapshot-internal-sync",
.args_type = "device:B,name:s",
.mhandler.cmd_new = qmp_marshal_blockdev_snapshot_internal_sync,
},
-
-SQMP
-blockdev-snapshot-internal-sync
--------------------------------
-
-Synchronously take an internal snapshot of a block device when the format of
-image used supports it. If the name is an empty string, or a snapshot with
-name already exists, the operation will fail.
-
-Arguments:
-
-- "device": device name to snapshot (json-string)
-- "name": name of the new snapshot (json-string)
-
-Example:
-
--> { "execute": "blockdev-snapshot-internal-sync",
- "arguments": { "device": "ide-hd0",
- "name": "snapshot0" }
- }
-<- { "return": {} }
-
-EQMP
-
{
.name = "blockdev-snapshot-delete-internal-sync",
.args_type = "device:B,id:s?,name:s?",
.mhandler.cmd_new =
qmp_marshal_blockdev_snapshot_delete_internal_sync,
},
-
-SQMP
-blockdev-snapshot-delete-internal-sync
---------------------------------------
-
-Synchronously delete an internal snapshot of a block device when the format of
-image used supports it. The snapshot is identified by name or id or both. One
-of name or id is required. If the snapshot is not found, the operation will
-fail.
-
-Arguments:
-
-- "device": device name (json-string)
-- "id": ID of the snapshot (json-string, optional)
-- "name": name of the snapshot (json-string, optional)
-
-Example:
-
--> { "execute": "blockdev-snapshot-delete-internal-sync",
- "arguments": { "device": "ide-hd0",
- "name": "snapshot0" }
- }
-<- { "return": {
- "id": "1",
- "name": "snapshot0",
- "vm-state-size": 0,
- "date-sec": 1000012,
- "date-nsec": 10,
- "vm-clock-sec": 100,
- "vm-clock-nsec": 20
- }
- }
-
-EQMP
-
{
.name = "drive-mirror",
.args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
@@ -1539,147 +346,21 @@ EQMP
"granularity:i?,buf-size:i?",
.mhandler.cmd_new = qmp_marshal_drive_mirror,
},
-
-SQMP
-drive-mirror
-------------
-
-Start mirroring a block device's writes to a new destination. target
-specifies the target of the new image. If the file exists, or if it is
-a device, it will be used as the new destination for writes. If it does not
-exist, a new file will be created. format specifies the format of the
-mirror image, default is to probe if mode='existing', else the format
-of the source.
-
-Arguments:
-
-- "device": device name to operate on (json-string)
-- "target": name of new image file (json-string)
-- "format": format of new image (json-string, optional)
-- "node-name": the name of the new block driver state in the node graph
- (json-string, optional)
-- "replaces": the block driver node name to replace when finished
- (json-string, optional)
-- "mode": how an image file should be created into the target
- file/device (NewImageMode, optional, default 'absolute-paths')
-- "speed": maximum speed of the streaming job, in bytes per second
- (json-int)
-- "granularity": granularity of the dirty bitmap, in bytes (json-int, optional)
-- "buf_size": maximum amount of data in flight from source to target, in bytes
- (json-int, default 10M)
-- "sync": what parts of the disk image should be copied to the destination;
- possibilities include "full" for all the disk, "top" for only the sectors
- allocated in the topmost image, or "none" to only replicate new I/O
- (MirrorSyncMode).
-- "on-source-error": the action to take on an error on the source
- (BlockdevOnError, default 'report')
-- "on-target-error": the action to take on an error on the target
- (BlockdevOnError, default 'report')
-- "unmap": whether the target sectors should be discarded where source has only
- zeroes. (json-bool, optional, default true)
-
-The default value of the granularity is the image cluster size clamped
-between 4096 and 65536, if the image format defines one. If the format
-does not define a cluster size, the default value of the granularity
-is 65536.
-
-
-Example:
-
--> { "execute": "drive-mirror", "arguments": { "device": "ide-hd0",
- "target": "/some/place/my-image",
- "sync": "full",
- "format": "qcow2" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "change-backing-file",
.args_type = "device:s,image-node-name:s,backing-file:s",
.mhandler.cmd_new = qmp_marshal_change_backing_file,
},
-
-SQMP
-change-backing-file
--------------------
-Since: 2.1
-
-Change the backing file in the image file metadata. This does not cause
-QEMU to reopen the image file to reparse the backing filename (it may,
-however, perform a reopen to change permissions from r/o -> r/w -> r/o,
-if needed). The new backing file string is written into the image file
-metadata, and the QEMU internal strings are updated.
-
-Arguments:
-
-- "image-node-name": The name of the block driver state node of the
- image to modify. The "device" is argument is used to
- verify "image-node-name" is in the chain described by
- "device".
- (json-string, optional)
-
-- "device": The name of the device.
- (json-string)
-
-- "backing-file": The string to write as the backing file. This string is
- not validated, so care should be taken when specifying
- the string or the image chain may not be able to be
- reopened again.
- (json-string)
-
-Returns: Nothing on success
- If "device" does not exist or cannot be determined, DeviceNotFound
-
-EQMP
-
{
.name = "balloon",
.args_type = "value:M",
.mhandler.cmd_new = qmp_marshal_balloon,
},
-
-SQMP
-balloon
--------
-
-Request VM to change its memory allocation (in bytes).
-
-Arguments:
-
-- "value": New memory allocation (json-int)
-
-Example:
-
--> { "execute": "balloon", "arguments": { "value": 536870912 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "set_link",
.args_type = "name:s,up:b",
.mhandler.cmd_new = qmp_marshal_set_link,
},
-
-SQMP
-set_link
---------
-
-Change the link status of a network adapter.
-
-Arguments:
-
-- "name": network device name (json-string)
-- "up": status is up (json-bool)
-
-Example:
-
--> { "execute": "set_link", "arguments": { "name": "e1000.0", "up": false } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "getfd",
.args_type = "fdname:s",
@@ -1687,32 +368,6 @@ EQMP
.help = "receive a file descriptor via SCM rights and assign it a name",
.mhandler.cmd_new = qmp_marshal_getfd,
},
-
-SQMP
-getfd
------
-
-Receive a file descriptor via SCM rights and assign it a name.
-
-Arguments:
-
-- "fdname": file descriptor name (json-string)
-
-Example:
-
--> { "execute": "getfd", "arguments": { "fdname": "fd1" } }
-<- { "return": {} }
-
-Notes:
-
-(1) If the name specified by the "fdname" argument already exists,
- the file descriptor assigned to it will be closed and replaced
- by the received file descriptor.
-(2) The 'closefd' command can be used to explicitly close the file
- descriptor when it is no longer needed.
-
-EQMP
-
{
.name = "closefd",
.args_type = "fdname:s",
@@ -1720,24 +375,6 @@ EQMP
.help = "close a file descriptor previously passed via SCM rights",
.mhandler.cmd_new = qmp_marshal_closefd,
},
-
-SQMP
-closefd
--------
-
-Close a file descriptor previously passed via SCM rights.
-
-Arguments:
-
-- "fdname": file descriptor name (json-string)
-
-Example:
-
--> { "execute": "closefd", "arguments": { "fdname": "fd1" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "add-fd",
.args_type = "fdset-id:i?,opaque:s?",
@@ -1745,38 +382,6 @@ EQMP
.help = "Add a file descriptor, that was passed via SCM rights, to an fd set",
.mhandler.cmd_new = qmp_marshal_add_fd,
},
-
-SQMP
-add-fd
--------
-
-Add a file descriptor, that was passed via SCM rights, to an fd set.
-
-Arguments:
-
-- "fdset-id": The ID of the fd set to add the file descriptor to.
- (json-int, optional)
-- "opaque": A free-form string that can be used to describe the fd.
- (json-string, optional)
-
-Return a json-object with the following information:
-
-- "fdset-id": The ID of the fd set that the fd was added to. (json-int)
-- "fd": The file descriptor that was received via SCM rights and added to the
- fd set. (json-int)
-
-Example:
-
--> { "execute": "add-fd", "arguments": { "fdset-id": 1 } }
-<- { "return": { "fdset-id": 1, "fd": 3 } }
-
-Notes:
-
-(1) The list of fd sets is shared by all monitor connections.
-(2) If "fdset-id" is not specified, a new fd set will be created.
-
-EQMP
-
{
.name = "remove-fd",
.args_type = "fdset-id:i,fd:i?",
@@ -1784,1305 +389,118 @@ EQMP
.help = "Remove a file descriptor from an fd set",
.mhandler.cmd_new = qmp_marshal_remove_fd,
},
-
-SQMP
-remove-fd
----------
-
-Remove a file descriptor from an fd set.
-
-Arguments:
-
-- "fdset-id": The ID of the fd set that the file descriptor belongs to.
- (json-int)
-- "fd": The file descriptor that is to be removed. (json-int, optional)
-
-Example:
-
--> { "execute": "remove-fd", "arguments": { "fdset-id": 1, "fd": 3 } }
-<- { "return": {} }
-
-Notes:
-
-(1) The list of fd sets is shared by all monitor connections.
-(2) If "fd" is not specified, all file descriptors in "fdset-id" will be
- removed.
-
-EQMP
-
{
.name = "query-fdsets",
.args_type = "",
.help = "Return information describing all fd sets",
.mhandler.cmd_new = qmp_marshal_query_fdsets,
},
-
-SQMP
-query-fdsets
--------------
-
-Return information describing all fd sets.
-
-Arguments: None
-
-Example:
-
--> { "execute": "query-fdsets" }
-<- { "return": [
- {
- "fds": [
- {
- "fd": 30,
- "opaque": "rdonly:/path/to/file"
- },
- {
- "fd": 24,
- "opaque": "rdwr:/path/to/file"
- }
- ],
- "fdset-id": 1
- },
- {
- "fds": [
- {
- "fd": 28
- },
- {
- "fd": 29
- }
- ],
- "fdset-id": 0
- }
- ]
- }
-
-Note: The list of fd sets is shared by all monitor connections.
-
-EQMP
-
{
.name = "block_passwd",
.args_type = "device:s?,node-name:s?,password:s",
.mhandler.cmd_new = qmp_marshal_block_passwd,
},
-
-SQMP
-block_passwd
-------------
-
-Set the password of encrypted block devices.
-
-Arguments:
-
-- "device": device name (json-string)
-- "node-name": name in the block driver state graph (json-string)
-- "password": password (json-string)
-
-Example:
-
--> { "execute": "block_passwd", "arguments": { "device": "ide0-hd0",
- "password": "12345" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block_set_io_throttle",
.args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l,bps_max:l?,bps_rd_max:l?,bps_wr_max:l?,iops_max:l?,iops_rd_max:l?,iops_wr_max:l?,iops_size:l?,group:s?",
.mhandler.cmd_new = qmp_marshal_block_set_io_throttle,
},
-
-SQMP
-block_set_io_throttle
-------------
-
-Change I/O throttle limits for a block drive.
-
-Arguments:
-
-- "device": device name (json-string)
-- "bps": total throughput limit in bytes per second (json-int)
-- "bps_rd": read throughput limit in bytes per second (json-int)
-- "bps_wr": write throughput limit in bytes per second (json-int)
-- "iops": total I/O operations per second (json-int)
-- "iops_rd": read I/O operations per second (json-int)
-- "iops_wr": write I/O operations per second (json-int)
-- "bps_max": total max in bytes (json-int)
-- "bps_rd_max": read max in bytes (json-int)
-- "bps_wr_max": write max in bytes (json-int)
-- "iops_max": total I/O operations max (json-int)
-- "iops_rd_max": read I/O operations max (json-int)
-- "iops_wr_max": write I/O operations max (json-int)
-- "iops_size": I/O size in bytes when limiting (json-int)
-- "group": throttle group name (json-string)
-
-Example:
-
--> { "execute": "block_set_io_throttle", "arguments": { "device": "virtio0",
- "bps": 1000000,
- "bps_rd": 0,
- "bps_wr": 0,
- "iops": 0,
- "iops_rd": 0,
- "iops_wr": 0,
- "bps_max": 8000000,
- "bps_rd_max": 0,
- "bps_wr_max": 0,
- "iops_max": 0,
- "iops_rd_max": 0,
- "iops_wr_max": 0,
- "iops_size": 0 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "set_password",
.args_type = "protocol:s,password:s,connected:s?",
.mhandler.cmd_new = qmp_marshal_set_password,
},
-
-SQMP
-set_password
-------------
-
-Set the password for vnc/spice protocols.
-
-Arguments:
-
-- "protocol": protocol name (json-string)
-- "password": password (json-string)
-- "connected": [ keep | disconnect | fail ] (json-string, optional)
-
-Example:
-
--> { "execute": "set_password", "arguments": { "protocol": "vnc",
- "password": "secret" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "expire_password",
.args_type = "protocol:s,time:s",
.mhandler.cmd_new = qmp_marshal_expire_password,
},
-
-SQMP
-expire_password
----------------
-
-Set the password expire time for vnc/spice protocols.
-
-Arguments:
-
-- "protocol": protocol name (json-string)
-- "time": [ now | never | +secs | secs ] (json-string)
-
-Example:
-
--> { "execute": "expire_password", "arguments": { "protocol": "vnc",
- "time": "+60" } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "add_client",
.args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
.mhandler.cmd_new = qmp_marshal_add_client,
},
-
-SQMP
-add_client
-----------
-
-Add a graphics client
-
-Arguments:
-
-- "protocol": protocol name (json-string)
-- "fdname": file descriptor name (json-string)
-- "skipauth": whether to skip authentication (json-bool, optional)
-- "tls": whether to perform TLS (json-bool, optional)
-
-Example:
-
--> { "execute": "add_client", "arguments": { "protocol": "vnc",
- "fdname": "myclient" } }
-<- { "return": {} }
-
-EQMP
{
.name = "qmp_capabilities",
.args_type = "",
- .params = "",
.help = "enable QMP capabilities",
.mhandler.cmd_new = qmp_marshal_qmp_capabilities,
},
-
-SQMP
-qmp_capabilities
-----------------
-
-Enable QMP capabilities.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "qmp_capabilities" }
-<- { "return": {} }
-
-Note: This command must be issued before issuing any other command.
-
-EQMP
-
{
.name = "human-monitor-command",
.args_type = "command-line:s,cpu-index:i?",
.mhandler.cmd_new = qmp_marshal_human_monitor_command,
},
-
-SQMP
-human-monitor-command
----------------------
-
-Execute a Human Monitor command.
-
-Arguments:
-
-- command-line: the command name and its arguments, just like the
- Human Monitor's shell (json-string)
-- cpu-index: select the CPU number to be used by commands which access CPU
- data, like 'info registers'. The Monitor selects CPU 0 if this
- argument is not provided (json-int, optional)
-
-Example:
-
--> { "execute": "human-monitor-command", "arguments": { "command-line": "info kvm" } }
-<- { "return": "kvm support: enabled\r\n" }
-
-Notes:
-
-(1) The Human Monitor is NOT an stable interface, this means that command
- names, arguments and responses can change or be removed at ANY time.
- Applications that rely on long term stability guarantees should NOT
- use this command
-
-(2) Limitations:
-
- o This command is stateless, this means that commands that depend
- on state information (such as getfd) might not work
-
- o Commands that prompt the user for data (eg. 'cont' when the block
- device is encrypted) don't currently work
-
-3. Query Commands
-=================
-
-HXCOMM Each query command below is inside a SQMP/EQMP section, do NOT change
-HXCOMM this! We will possibly move query commands definitions inside those
-HXCOMM sections, just like regular commands.
-
-EQMP
-
-SQMP
-query-version
--------------
-
-Show QEMU version.
-
-Return a json-object with the following information:
-
-- "qemu": A json-object containing three integer values:
- - "major": QEMU's major version (json-int)
- - "minor": QEMU's minor version (json-int)
- - "micro": QEMU's micro version (json-int)
-- "package": package's version (json-string)
-
-Example:
-
--> { "execute": "query-version" }
-<- {
- "return":{
- "qemu":{
- "major":0,
- "minor":11,
- "micro":5
- },
- "package":""
- }
- }
-
-EQMP
-
{
.name = "query-version",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_version,
},
-
-SQMP
-query-commands
---------------
-
-List QMP available commands.
-
-Each command is represented by a json-object, the returned value is a json-array
-of all commands.
-
-Each json-object contain:
-
-- "name": command's name (json-string)
-
-Example:
-
--> { "execute": "query-commands" }
-<- {
- "return":[
- {
- "name":"query-balloon"
- },
- {
- "name":"system_powerdown"
- }
- ]
- }
-
-Note: This example has been shortened as the real response is too long.
-
-EQMP
-
{
.name = "query-commands",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_commands,
},
-
-SQMP
-query-events
---------------
-
-List QMP available events.
-
-Each event is represented by a json-object, the returned value is a json-array
-of all events.
-
-Each json-object contains:
-
-- "name": event's name (json-string)
-
-Example:
-
--> { "execute": "query-events" }
-<- {
- "return":[
- {
- "name":"SHUTDOWN"
- },
- {
- "name":"RESET"
- }
- ]
- }
-
-Note: This example has been shortened as the real response is too long.
-
-EQMP
-
{
.name = "query-events",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_events,
},
-
-SQMP
-query-qmp-schema
-----------------
-
-Return the QMP wire schema. The returned value is a json-array of
-named schema entities. Entities are commands, events and various
-types. See docs/qapi-code-gen.txt for information on their structure
-and intended use.
-
-EQMP
-
{
.name = "query-qmp-schema",
.args_type = "",
.mhandler.cmd_new = qmp_query_qmp_schema,
},
-
-SQMP
-query-chardev
--------------
-
-Each device is represented by a json-object. The returned value is a json-array
-of all devices.
-
-Each json-object contain the following:
-
-- "label": device's label (json-string)
-- "filename": device's file (json-string)
-- "frontend-open": open/closed state of the frontend device attached to this
- backend (json-bool)
-
-Example:
-
--> { "execute": "query-chardev" }
-<- {
- "return": [
- {
- "label": "charchannel0",
- "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.agent,server",
- "frontend-open": false
- },
- {
- "label": "charmonitor",
- "filename": "unix:/var/lib/libvirt/qemu/seabios.rhel6.monitor,server",
- "frontend-open": true
- },
- {
- "label": "charserial0",
- "filename": "pty:/dev/pts/2",
- "frontend-open": true
- }
- ]
- }
-
-EQMP
-
{
.name = "query-chardev",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_chardev,
},
-
-SQMP
-query-chardev-backends
--------------
-
-List available character device backends.
-
-Each backend is represented by a json-object, the returned value is a json-array
-of all backends.
-
-Each json-object contains:
-
-- "name": backend name (json-string)
-
-Example:
-
--> { "execute": "query-chardev-backends" }
-<- {
- "return":[
- {
- "name":"udp"
- },
- {
- "name":"tcp"
- },
- {
- "name":"unix"
- },
- {
- "name":"spiceport"
- }
- ]
- }
-
-EQMP
-
{
.name = "query-chardev-backends",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_chardev_backends,
},
-
-SQMP
-query-block
------------
-
-Show the block devices.
-
-Each block device information is stored in a json-object and the returned value
-is a json-array of all devices.
-
-Each json-object contain the following:
-
-- "device": device name (json-string)
-- "type": device type (json-string)
- - deprecated, retained for backward compatibility
- - Possible values: "unknown"
-- "removable": true if the device is removable, false otherwise (json-bool)
-- "locked": true if the device is locked, false otherwise (json-bool)
-- "tray_open": only present if removable, true if the device has a tray,
- and it is open (json-bool)
-- "inserted": only present if the device is inserted, it is a json-object
- containing the following:
- - "file": device file name (json-string)
- - "ro": true if read-only, false otherwise (json-bool)
- - "drv": driver format name (json-string)
- - Possible values: "blkdebug", "bochs", "cloop", "dmg",
- "file", "file", "ftp", "ftps", "host_cdrom",
- "host_device", "http", "https",
- "nbd", "parallels", "qcow", "qcow2", "raw",
- "tftp", "vdi", "vmdk", "vpc", "vvfat"
- - "backing_file": backing file name (json-string, optional)
- - "backing_file_depth": number of files in the backing file chain (json-int)
- - "encrypted": true if encrypted, false otherwise (json-bool)
- - "bps": limit total bytes per second (json-int)
- - "bps_rd": limit read bytes per second (json-int)
- - "bps_wr": limit write bytes per second (json-int)
- - "iops": limit total I/O operations per second (json-int)
- - "iops_rd": limit read operations per second (json-int)
- - "iops_wr": limit write operations per second (json-int)
- - "bps_max": total max in bytes (json-int)
- - "bps_rd_max": read max in bytes (json-int)
- - "bps_wr_max": write max in bytes (json-int)
- - "iops_max": total I/O operations max (json-int)
- - "iops_rd_max": read I/O operations max (json-int)
- - "iops_wr_max": write I/O operations max (json-int)
- - "iops_size": I/O size when limiting by iops (json-int)
- - "detect_zeroes": detect and optimize zero writing (json-string)
- - Possible values: "off", "on", "unmap"
- - "write_threshold": write offset threshold in bytes, a event will be
- emitted if crossed. Zero if disabled (json-int)
- - "image": the detail of the image, it is a json-object containing
- the following:
- - "filename": image file name (json-string)
- - "format": image format (json-string)
- - "virtual-size": image capacity in bytes (json-int)
- - "dirty-flag": true if image is not cleanly closed, not present
- means clean (json-bool, optional)
- - "actual-size": actual size on disk in bytes of the image, not
- present when image does not support thin
- provision (json-int, optional)
- - "cluster-size": size of a cluster in bytes, not present if image
- format does not support it (json-int, optional)
- - "encrypted": true if the image is encrypted, not present means
- false or the image format does not support
- encryption (json-bool, optional)
- - "backing_file": backing file name, not present means no backing
- file is used or the image format does not
- support backing file chain
- (json-string, optional)
- - "full-backing-filename": full path of the backing file, not
- present if it equals backing_file or no
- backing file is used
- (json-string, optional)
- - "backing-filename-format": the format of the backing file, not
- present means unknown or no backing
- file (json-string, optional)
- - "snapshots": the internal snapshot info, it is an optional list
- of json-object containing the following:
- - "id": unique snapshot id (json-string)
- - "name": snapshot name (json-string)
- - "vm-state-size": size of the VM state in bytes (json-int)
- - "date-sec": UTC date of the snapshot in seconds (json-int)
- - "date-nsec": fractional part in nanoseconds to be used with
- date-sec (json-int)
- - "vm-clock-sec": VM clock relative to boot in seconds
- (json-int)
- - "vm-clock-nsec": fractional part in nanoseconds to be used
- with vm-clock-sec (json-int)
- - "backing-image": the detail of the backing image, it is an
- optional json-object only present when a
- backing image present for this image
-
-- "io-status": I/O operation status, only present if the device supports it
- and the VM is configured to stop on errors. It's always reset
- to "ok" when the "cont" command is issued (json_string, optional)
- - Possible values: "ok", "failed", "nospace"
-
-Example:
-
--> { "execute": "query-block" }
-<- {
- "return":[
- {
- "io-status": "ok",
- "device":"ide0-hd0",
- "locked":false,
- "removable":false,
- "inserted":{
- "ro":false,
- "drv":"qcow2",
- "encrypted":false,
- "file":"disks/test.qcow2",
- "backing_file_depth":1,
- "bps":1000000,
- "bps_rd":0,
- "bps_wr":0,
- "iops":1000000,
- "iops_rd":0,
- "iops_wr":0,
- "bps_max": 8000000,
- "bps_rd_max": 0,
- "bps_wr_max": 0,
- "iops_max": 0,
- "iops_rd_max": 0,
- "iops_wr_max": 0,
- "iops_size": 0,
- "detect_zeroes": "on",
- "write_threshold": 0,
- "image":{
- "filename":"disks/test.qcow2",
- "format":"qcow2",
- "virtual-size":2048000,
- "backing_file":"base.qcow2",
- "full-backing-filename":"disks/base.qcow2",
- "backing-filename-format":"qcow2",
- "snapshots":[
- {
- "id": "1",
- "name": "snapshot1",
- "vm-state-size": 0,
- "date-sec": 10000200,
- "date-nsec": 12,
- "vm-clock-sec": 206,
- "vm-clock-nsec": 30
- }
- ],
- "backing-image":{
- "filename":"disks/base.qcow2",
- "format":"qcow2",
- "virtual-size":2048000
- }
- }
- },
- "type":"unknown"
- },
- {
- "io-status": "ok",
- "device":"ide1-cd0",
- "locked":false,
- "removable":true,
- "type":"unknown"
- },
- {
- "device":"floppy0",
- "locked":false,
- "removable":true,
- "type":"unknown"
- },
- {
- "device":"sd0",
- "locked":false,
- "removable":true,
- "type":"unknown"
- }
- ]
- }
-
-EQMP
-
{
.name = "query-block",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_block,
},
-
-SQMP
-query-blockstats
-----------------
-
-Show block device statistics.
-
-Each device statistic information is stored in a json-object and the returned
-value is a json-array of all devices.
-
-Each json-object contain the following:
-
-- "device": device name (json-string)
-- "stats": A json-object with the statistics information, it contains:
- - "rd_bytes": bytes read (json-int)
- - "wr_bytes": bytes written (json-int)
- - "rd_operations": read operations (json-int)
- - "wr_operations": write operations (json-int)
- - "flush_operations": cache flush operations (json-int)
- - "wr_total_time_ns": total time spend on writes in nano-seconds (json-int)
- - "rd_total_time_ns": total time spend on reads in nano-seconds (json-int)
- - "flush_total_time_ns": total time spend on cache flushes in nano-seconds (json-int)
- - "wr_highest_offset": Highest offset of a sector written since the
- BlockDriverState has been opened (json-int)
- - "rd_merged": number of read requests that have been merged into
- another request (json-int)
- - "wr_merged": number of write requests that have been merged into
- another request (json-int)
-- "parent": Contains recursively the statistics of the underlying
- protocol (e.g. the host file for a qcow2 image). If there is
- no underlying protocol, this field is omitted
- (json-object, optional)
-
-Example:
-
--> { "execute": "query-blockstats" }
-<- {
- "return":[
- {
- "device":"ide0-hd0",
- "parent":{
- "stats":{
- "wr_highest_offset":3686448128,
- "wr_bytes":9786368,
- "wr_operations":751,
- "rd_bytes":122567168,
- "rd_operations":36772
- "wr_total_times_ns":313253456
- "rd_total_times_ns":3465673657
- "flush_total_times_ns":49653
- "flush_operations":61,
- "rd_merged":0,
- "wr_merged":0
- }
- },
- "stats":{
- "wr_highest_offset":2821110784,
- "wr_bytes":9786368,
- "wr_operations":692,
- "rd_bytes":122739200,
- "rd_operations":36604
- "flush_operations":51,
- "wr_total_times_ns":313253456
- "rd_total_times_ns":3465673657
- "flush_total_times_ns":49653,
- "rd_merged":0,
- "wr_merged":0
- }
- },
- {
- "device":"ide1-cd0",
- "stats":{
- "wr_highest_offset":0,
- "wr_bytes":0,
- "wr_operations":0,
- "rd_bytes":0,
- "rd_operations":0
- "flush_operations":0,
- "wr_total_times_ns":0
- "rd_total_times_ns":0
- "flush_total_times_ns":0,
- "rd_merged":0,
- "wr_merged":0
- }
- },
- {
- "device":"floppy0",
- "stats":{
- "wr_highest_offset":0,
- "wr_bytes":0,
- "wr_operations":0,
- "rd_bytes":0,
- "rd_operations":0
- "flush_operations":0,
- "wr_total_times_ns":0
- "rd_total_times_ns":0
- "flush_total_times_ns":0,
- "rd_merged":0,
- "wr_merged":0
- }
- },
- {
- "device":"sd0",
- "stats":{
- "wr_highest_offset":0,
- "wr_bytes":0,
- "wr_operations":0,
- "rd_bytes":0,
- "rd_operations":0
- "flush_operations":0,
- "wr_total_times_ns":0
- "rd_total_times_ns":0
- "flush_total_times_ns":0,
- "rd_merged":0,
- "wr_merged":0
- }
- }
- ]
- }
-
-EQMP
-
{
.name = "query-blockstats",
.args_type = "query-nodes:b?",
.mhandler.cmd_new = qmp_marshal_query_blockstats,
},
-
-SQMP
-query-cpus
-----------
-
-Show CPU information.
-
-Return a json-array. Each CPU is represented by a json-object, which contains:
-
-- "CPU": CPU index (json-int)
-- "current": true if this is the current CPU, false otherwise (json-bool)
-- "halted": true if the cpu is halted, false otherwise (json-bool)
-- "qom_path": path to the CPU object in the QOM tree (json-str)
-- Current program counter. The key's name depends on the architecture:
- "pc": i386/x86_64 (json-int)
- "nip": PPC (json-int)
- "pc" and "npc": sparc (json-int)
- "PC": mips (json-int)
-- "thread_id": ID of the underlying host thread (json-int)
-
-Example:
-
--> { "execute": "query-cpus" }
-<- {
- "return":[
- {
- "CPU":0,
- "current":true,
- "halted":false,
- "qom_path":"/machine/unattached/device[0]",
- "pc":3227107138,
- "thread_id":3134
- },
- {
- "CPU":1,
- "current":false,
- "halted":true,
- "qom_path":"/machine/unattached/device[2]",
- "pc":7108165,
- "thread_id":3135
- }
- ]
- }
-
-EQMP
-
{
.name = "query-cpus",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_cpus,
},
-
-SQMP
-query-iothreads
----------------
-
-Returns a list of information about each iothread.
-
-Note this list excludes the QEMU main loop thread, which is not declared
-using the -object iothread command-line option. It is always the main thread
-of the process.
-
-Return a json-array. Each iothread is represented by a json-object, which contains:
-
-- "id": name of iothread (json-str)
-- "thread-id": ID of the underlying host thread (json-int)
-
-Example:
-
--> { "execute": "query-iothreads" }
-<- {
- "return":[
- {
- "id":"iothread0",
- "thread-id":3134
- },
- {
- "id":"iothread1",
- "thread-id":3135
- }
- ]
- }
-
-EQMP
-
{
.name = "query-iothreads",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_iothreads,
},
-
-SQMP
-query-pci
----------
-
-PCI buses and devices information.
-
-The returned value is a json-array of all buses. Each bus is represented by
-a json-object, which has a key with a json-array of all PCI devices attached
-to it. Each device is represented by a json-object.
-
-The bus json-object contains the following:
-
-- "bus": bus number (json-int)
-- "devices": a json-array of json-objects, each json-object represents a
- PCI device
-
-The PCI device json-object contains the following:
-
-- "bus": identical to the parent's bus number (json-int)
-- "slot": slot number (json-int)
-- "function": function number (json-int)
-- "class_info": a json-object containing:
- - "desc": device class description (json-string, optional)
- - "class": device class number (json-int)
-- "id": a json-object containing:
- - "device": device ID (json-int)
- - "vendor": vendor ID (json-int)
-- "irq": device's IRQ if assigned (json-int, optional)
-- "qdev_id": qdev id string (json-string)
-- "pci_bridge": It's a json-object, only present if this device is a
- PCI bridge, contains:
- - "bus": bus number (json-int)
- - "secondary": secondary bus number (json-int)
- - "subordinate": subordinate bus number (json-int)
- - "io_range": I/O memory range information, a json-object with the
- following members:
- - "base": base address, in bytes (json-int)
- - "limit": limit address, in bytes (json-int)
- - "memory_range": memory range information, a json-object with the
- following members:
- - "base": base address, in bytes (json-int)
- - "limit": limit address, in bytes (json-int)
- - "prefetchable_range": Prefetchable memory range information, a
- json-object with the following members:
- - "base": base address, in bytes (json-int)
- - "limit": limit address, in bytes (json-int)
- - "devices": a json-array of PCI devices if there's any attached, each
- each element is represented by a json-object, which contains
- the same members of the 'PCI device json-object' described
- above (optional)
-- "regions": a json-array of json-objects, each json-object represents a
- memory region of this device
-
-The memory range json-object contains the following:
-
-- "base": base memory address (json-int)
-- "limit": limit value (json-int)
-
-The region json-object can be an I/O region or a memory region, an I/O region
-json-object contains the following:
-
-- "type": "io" (json-string, fixed)
-- "bar": BAR number (json-int)
-- "address": memory address (json-int)
-- "size": memory size (json-int)
-
-A memory region json-object contains the following:
-
-- "type": "memory" (json-string, fixed)
-- "bar": BAR number (json-int)
-- "address": memory address (json-int)
-- "size": memory size (json-int)
-- "mem_type_64": true or false (json-bool)
-- "prefetch": true or false (json-bool)
-
-Example:
-
--> { "execute": "query-pci" }
-<- {
- "return":[
- {
- "bus":0,
- "devices":[
- {
- "bus":0,
- "qdev_id":"",
- "slot":0,
- "class_info":{
- "class":1536,
- "desc":"Host bridge"
- },
- "id":{
- "device":32902,
- "vendor":4663
- },
- "function":0,
- "regions":[
-
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "slot":1,
- "class_info":{
- "class":1537,
- "desc":"ISA bridge"
- },
- "id":{
- "device":32902,
- "vendor":28672
- },
- "function":0,
- "regions":[
-
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "slot":1,
- "class_info":{
- "class":257,
- "desc":"IDE controller"
- },
- "id":{
- "device":32902,
- "vendor":28688
- },
- "function":1,
- "regions":[
- {
- "bar":4,
- "size":16,
- "address":49152,
- "type":"io"
- }
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "slot":2,
- "class_info":{
- "class":768,
- "desc":"VGA controller"
- },
- "id":{
- "device":4115,
- "vendor":184
- },
- "function":0,
- "regions":[
- {
- "prefetch":true,
- "mem_type_64":false,
- "bar":0,
- "size":33554432,
- "address":4026531840,
- "type":"memory"
- },
- {
- "prefetch":false,
- "mem_type_64":false,
- "bar":1,
- "size":4096,
- "address":4060086272,
- "type":"memory"
- },
- {
- "prefetch":false,
- "mem_type_64":false,
- "bar":6,
- "size":65536,
- "address":-1,
- "type":"memory"
- }
- ]
- },
- {
- "bus":0,
- "qdev_id":"",
- "irq":11,
- "slot":4,
- "class_info":{
- "class":1280,
- "desc":"RAM controller"
- },
- "id":{
- "device":6900,
- "vendor":4098
- },
- "function":0,
- "regions":[
- {
- "bar":0,
- "size":32,
- "address":49280,
- "type":"io"
- }
- ]
- }
- ]
- }
- ]
- }
-
-Note: This example has been shortened as the real response is too long.
-
-EQMP
-
{
.name = "query-pci",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_pci,
},
-
-SQMP
-query-kvm
----------
-
-Show KVM information.
-
-Return a json-object with the following information:
-
-- "enabled": true if KVM support is enabled, false otherwise (json-bool)
-- "present": true if QEMU has KVM support, false otherwise (json-bool)
-
-Example:
-
--> { "execute": "query-kvm" }
-<- { "return": { "enabled": true, "present": true } }
-
-EQMP
-
{
.name = "query-kvm",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_kvm,
},
-
-SQMP
-query-status
-------------
-
-Return a json-object with the following information:
-
-- "running": true if the VM is running, or false if it is paused (json-bool)
-- "singlestep": true if the VM is in single step mode,
- false otherwise (json-bool)
-- "status": one of the following values (json-string)
- "debug" - QEMU is running on a debugger
- "inmigrate" - guest is paused waiting for an incoming migration
- "internal-error" - An internal error that prevents further guest
- execution has occurred
- "io-error" - the last IOP has failed and the device is configured
- to pause on I/O errors
- "paused" - guest has been paused via the 'stop' command
- "postmigrate" - guest is paused following a successful 'migrate'
- "prelaunch" - QEMU was started with -S and guest has not started
- "finish-migrate" - guest is paused to finish the migration process
- "restore-vm" - guest is paused to restore VM state
- "running" - guest is actively running
- "save-vm" - guest is paused to save the VM state
- "shutdown" - guest is shut down (and -no-shutdown is in use)
- "watchdog" - the watchdog action is configured to pause and
- has been triggered
-
-Example:
-
--> { "execute": "query-status" }
-<- { "return": { "running": true, "singlestep": false, "status": "running" } }
-
-EQMP
-
{
.name = "query-status",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_status,
},
-
-SQMP
-query-mice
-----------
-
-Show VM mice information.
-
-Each mouse is represented by a json-object, the returned value is a json-array
-of all mice.
-
-The mouse json-object contains the following:
-
-- "name": mouse's name (json-string)
-- "index": mouse's index (json-int)
-- "current": true if this mouse is receiving events, false otherwise (json-bool)
-- "absolute": true if the mouse generates absolute input events (json-bool)
-
-Example:
-
--> { "execute": "query-mice" }
-<- {
- "return":[
- {
- "name":"QEMU Microsoft Mouse",
- "index":0,
- "current":false,
- "absolute":false
- },
- {
- "name":"QEMU PS/2 Mouse",
- "index":1,
- "current":true,
- "absolute":true
- }
- ]
- }
-
-EQMP
-
{
.name = "query-mice",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_mice,
},
-
-SQMP
-query-vnc
----------
-
-Show VNC server information.
-
-Return a json-object with server information. Connected clients are returned
-as a json-array of json-objects.
-
-The main json-object contains the following:
-
-- "enabled": true or false (json-bool)
-- "host": server's IP address (json-string)
-- "family": address family (json-string)
- - Possible values: "ipv4", "ipv6", "unix", "unknown"
-- "service": server's port number (json-string)
-- "auth": authentication method (json-string)
- - Possible values: "invalid", "none", "ra2", "ra2ne", "sasl", "tight",
- "tls", "ultra", "unknown", "vencrypt", "vencrypt",
- "vencrypt+plain", "vencrypt+tls+none",
- "vencrypt+tls+plain", "vencrypt+tls+sasl",
- "vencrypt+tls+vnc", "vencrypt+x509+none",
- "vencrypt+x509+plain", "vencrypt+x509+sasl",
- "vencrypt+x509+vnc", "vnc"
-- "clients": a json-array of all connected clients
-
-Clients are described by a json-object, each one contain the following:
-
-- "host": client's IP address (json-string)
-- "family": address family (json-string)
- - Possible values: "ipv4", "ipv6", "unix", "unknown"
-- "service": client's port number (json-string)
-- "x509_dname": TLS dname (json-string, optional)
-- "sasl_username": SASL username (json-string, optional)
-
-Example:
-
--> { "execute": "query-vnc" }
-<- {
- "return":{
- "enabled":true,
- "host":"0.0.0.0",
- "service":"50402",
- "auth":"vnc",
- "family":"ipv4",
- "clients":[
- {
- "host":"127.0.0.1",
- "service":"50401",
- "family":"ipv4"
- }
- ]
- }
- }
-
-EQMP
-
{
.name = "query-vnc",
.args_type = "",
@@ -3093,491 +511,55 @@ EQMP
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_vnc_servers,
},
-
-SQMP
-query-spice
------------
-
-Show SPICE server information.
-
-Return a json-object with server information. Connected clients are returned
-as a json-array of json-objects.
-
-The main json-object contains the following:
-
-- "enabled": true or false (json-bool)
-- "host": server's IP address (json-string)
-- "port": server's port number (json-int, optional)
-- "tls-port": server's port number (json-int, optional)
-- "auth": authentication method (json-string)
- - Possible values: "none", "spice"
-- "channels": a json-array of all active channels clients
-
-Channels are described by a json-object, each one contain the following:
-
-- "host": client's IP address (json-string)
-- "family": address family (json-string)
- - Possible values: "ipv4", "ipv6", "unix", "unknown"
-- "port": client's port number (json-string)
-- "connection-id": spice connection id. All channels with the same id
- belong to the same spice session (json-int)
-- "channel-type": channel type. "1" is the main control channel, filter for
- this one if you want track spice sessions only (json-int)
-- "channel-id": channel id. Usually "0", might be different needed when
- multiple channels of the same type exist, such as multiple
- display channels in a multihead setup (json-int)
-- "tls": whether the channel is encrypted (json-bool)
-
-Example:
-
--> { "execute": "query-spice" }
-<- {
- "return": {
- "enabled": true,
- "auth": "spice",
- "port": 5920,
- "tls-port": 5921,
- "host": "0.0.0.0",
- "channels": [
- {
- "port": "54924",
- "family": "ipv4",
- "channel-type": 1,
- "connection-id": 1804289383,
- "host": "127.0.0.1",
- "channel-id": 0,
- "tls": true
- },
- {
- "port": "36710",
- "family": "ipv4",
- "channel-type": 4,
- "connection-id": 1804289383,
- "host": "127.0.0.1",
- "channel-id": 0,
- "tls": false
- },
- [ ... more channels follow ... ]
- ]
- }
- }
-
-EQMP
-
#if defined(CONFIG_SPICE)
{
.name = "query-spice",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_spice,
- },
-#endif
-
-SQMP
-query-name
-----------
-
-Show VM name.
-
-Return a json-object with the following information:
-
-- "name": VM's name (json-string, optional)
-
-Example:
-
--> { "execute": "query-name" }
-<- { "return": { "name": "qemu-name" } }
-
-EQMP
-
- {
- .name = "query-name",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_name,
- },
-
-SQMP
-query-uuid
-----------
-
-Show VM UUID.
-
-Return a json-object with the following information:
-
-- "UUID": Universally Unique Identifier (json-string)
-
-Example:
-
--> { "execute": "query-uuid" }
-<- { "return": { "UUID": "550e8400-e29b-41d4-a716-446655440000" } }
-
-EQMP
-
- {
- .name = "query-uuid",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_uuid,
- },
-
-SQMP
-query-command-line-options
---------------------------
-
-Show command line option schema.
-
-Return a json-array of command line option schema for all options (or for
-the given option), returning an error if the given option doesn't exist.
-
-Each array entry contains the following:
-
-- "option": option name (json-string)
-- "parameters": a json-array describes all parameters of the option:
- - "name": parameter name (json-string)
- - "type": parameter type (one of 'string', 'boolean', 'number',
- or 'size')
- - "help": human readable description of the parameter
- (json-string, optional)
- - "default": default value string for the parameter
- (json-string, optional)
-
-Example:
-
--> { "execute": "query-command-line-options", "arguments": { "option": "option-rom" } }
-<- { "return": [
- {
- "parameters": [
- {
- "name": "romfile",
- "type": "string"
- },
- {
- "name": "bootindex",
- "type": "number"
- }
- ],
- "option": "option-rom"
- }
- ]
- }
-
-EQMP
-
- {
- .name = "query-command-line-options",
- .args_type = "option:s?",
- .mhandler.cmd_new = qmp_marshal_query_command_line_options,
- },
-
-SQMP
-query-migrate
--------------
-
-Migration status.
-
-Return a json-object. If migration is active there will be another json-object
-with RAM migration status and if block migration is active another one with
-block migration status.
-
-The main json-object contains the following:
-
-- "status": migration status (json-string)
- - Possible values: "setup", "active", "completed", "failed", "cancelled"
-- "total-time": total amount of ms since migration started. If
- migration has ended, it returns the total migration
- time (json-int)
-- "setup-time" amount of setup time in milliseconds _before_ the
- iterations begin but _after_ the QMP command is issued.
- This is designed to provide an accounting of any activities
- (such as RDMA pinning) which may be expensive, but do not
- actually occur during the iterative migration rounds
- themselves. (json-int)
-- "downtime": only present when migration has finished correctly
- total amount in ms for downtime that happened (json-int)
-- "expected-downtime": only present while migration is active
- total amount in ms for downtime that was calculated on
- the last bitmap round (json-int)
-- "ram": only present if "status" is "active", it is a json-object with the
- following RAM information:
- - "transferred": amount transferred in bytes (json-int)
- - "remaining": amount remaining to transfer in bytes (json-int)
- - "total": total amount of memory in bytes (json-int)
- - "duplicate": number of pages filled entirely with the same
- byte (json-int)
- These are sent over the wire much more efficiently.
- - "skipped": number of skipped zero pages (json-int)
- - "normal" : number of whole pages transferred. I.e. they
- were not sent as duplicate or xbzrle pages (json-int)
- - "normal-bytes" : number of bytes transferred in whole
- pages. This is just normal pages times size of one page,
- but this way upper levels don't need to care about page
- size (json-int)
- - "dirty-sync-count": times that dirty ram was synchronized (json-int)
-- "disk": only present if "status" is "active" and it is a block migration,
- it is a json-object with the following disk information:
- - "transferred": amount transferred in bytes (json-int)
- - "remaining": amount remaining to transfer in bytes json-int)
- - "total": total disk size in bytes (json-int)
-- "xbzrle-cache": only present if XBZRLE is active.
- It is a json-object with the following XBZRLE information:
- - "cache-size": XBZRLE cache size in bytes
- - "bytes": number of bytes transferred for XBZRLE compressed pages
- - "pages": number of XBZRLE compressed pages
- - "cache-miss": number of XBRZRLE page cache misses
- - "cache-miss-rate": rate of XBRZRLE page cache misses
- - "overflow": number of times XBZRLE overflows. This means
- that the XBZRLE encoding was bigger than just sent the
- whole page, and then we sent the whole page instead (as as
- normal page).
-
-Examples:
-
-1. Before the first migration
-
--> { "execute": "query-migrate" }
-<- { "return": {} }
-
-2. Migration is done and has succeeded
-
--> { "execute": "query-migrate" }
-<- { "return": {
- "status": "completed",
- "ram":{
- "transferred":123,
- "remaining":123,
- "total":246,
- "total-time":12345,
- "setup-time":12345,
- "downtime":12345,
- "duplicate":123,
- "normal":123,
- "normal-bytes":123456,
- "dirty-sync-count":15
- }
- }
- }
-
-3. Migration is done and has failed
-
--> { "execute": "query-migrate" }
-<- { "return": { "status": "failed" } }
-
-4. Migration is being performed and is not a block migration:
-
--> { "execute": "query-migrate" }
-<- {
- "return":{
- "status":"active",
- "ram":{
- "transferred":123,
- "remaining":123,
- "total":246,
- "total-time":12345,
- "setup-time":12345,
- "expected-downtime":12345,
- "duplicate":123,
- "normal":123,
- "normal-bytes":123456,
- "dirty-sync-count":15
- }
- }
- }
-
-5. Migration is being performed and is a block migration:
-
--> { "execute": "query-migrate" }
-<- {
- "return":{
- "status":"active",
- "ram":{
- "total":1057024,
- "remaining":1053304,
- "transferred":3720,
- "total-time":12345,
- "setup-time":12345,
- "expected-downtime":12345,
- "duplicate":123,
- "normal":123,
- "normal-bytes":123456,
- "dirty-sync-count":15
- },
- "disk":{
- "total":20971520,
- "remaining":20880384,
- "transferred":91136
- }
- }
- }
-
-6. Migration is being performed and XBZRLE is active:
-
--> { "execute": "query-migrate" }
-<- {
- "return":{
- "status":"active",
- "capabilities" : [ { "capability": "xbzrle", "state" : true } ],
- "ram":{
- "total":1057024,
- "remaining":1053304,
- "transferred":3720,
- "total-time":12345,
- "setup-time":12345,
- "expected-downtime":12345,
- "duplicate":10,
- "normal":3333,
- "normal-bytes":3412992,
- "dirty-sync-count":15
- },
- "xbzrle-cache":{
- "cache-size":67108864,
- "bytes":20971520,
- "pages":2444343,
- "cache-miss":2244,
- "cache-miss-rate":0.123,
- "overflow":34434
- }
- }
- }
-
-EQMP
-
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_spice,
+ },
+#endif
+ {
+ .name = "query-name",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_name,
+ },
+ {
+ .name = "query-uuid",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_uuid,
+ },
+ {
+ .name = "query-command-line-options",
+ .args_type = "option:s?",
+ .mhandler.cmd_new = qmp_marshal_query_command_line_options,
+ },
{
.name = "query-migrate",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_migrate,
},
-
-SQMP
-migrate-set-capabilities
-------------------------
-
-Enable/Disable migration capabilities
-
-- "xbzrle": XBZRLE support
-- "rdma-pin-all": pin all pages when using RDMA during migration
-- "auto-converge": throttle down guest to help convergence of migration
-- "zero-blocks": compress zero blocks during block migration
-- "events": generate events for each migration state change
-
-Arguments:
-
-Example:
-
--> { "execute": "migrate-set-capabilities" , "arguments":
- { "capabilities": [ { "capability": "xbzrle", "state": true } ] } }
-
-EQMP
-
{
.name = "migrate-set-capabilities",
.args_type = "capabilities:q",
.params = "capability:s,state:b",
.mhandler.cmd_new = qmp_marshal_migrate_set_capabilities,
},
-SQMP
-query-migrate-capabilities
---------------------------
-
-Query current migration capabilities
-
-- "capabilities": migration capabilities state
- - "xbzrle" : XBZRLE state (json-bool)
- - "rdma-pin-all" : RDMA Pin Page state (json-bool)
- - "auto-converge" : Auto Converge state (json-bool)
- - "zero-blocks" : Zero Blocks state (json-bool)
-
-Arguments:
-
-Example:
-
--> { "execute": "query-migrate-capabilities" }
-<- { "return": [ { "state": false, "capability": "xbzrle" } ] }
-
-EQMP
-
{
.name = "query-migrate-capabilities",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_migrate_capabilities,
},
-
-SQMP
-migrate-set-parameters
-----------------------
-
-Set migration parameters
-
-- "compress-level": set compression level during migration (json-int)
-- "compress-threads": set compression thread count for migration (json-int)
-- "decompress-threads": set decompression thread count for migration (json-int)
-
-Arguments:
-
-Example:
-
--> { "execute": "migrate-set-parameters" , "arguments":
- { "compress-level": 1 } }
-
-EQMP
-
{
.name = "migrate-set-parameters",
.args_type =
"compress-level:i?,compress-threads:i?,decompress-threads:i?",
.mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
},
-SQMP
-query-migrate-parameters
-------------------------
-
-Query current migration parameters
-
-- "parameters": migration parameters value
- - "compress-level" : compression level value (json-int)
- - "compress-threads" : compression thread count value (json-int)
- - "decompress-threads" : decompression thread count value (json-int)
-
-Arguments:
-
-Example:
-
--> { "execute": "query-migrate-parameters" }
-<- {
- "return": {
- "decompress-threads", 2,
- "compress-threads", 8,
- "compress-level", 1
- }
- }
-
-EQMP
-
{
.name = "query-migrate-parameters",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_migrate_parameters,
},
-
-SQMP
-query-balloon
--------------
-
-Show balloon information.
-
-Make an asynchronous request for balloon info. When the request completes a
-json-object will be returned containing the following data:
-
-- "actual": current balloon value in bytes (json-int)
-
-Example:
-
--> { "execute": "query-balloon" }
-<- {
- "return":{
- "actual":1073741824,
- }
- }
-
-EQMP
-
{
.name = "query-balloon",
.args_type = "",
@@ -3664,411 +646,56 @@ EQMP
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_tpm,
},
-
-SQMP
-query-tpm
----------
-
-Return information about the TPM device.
-
-Arguments: None
-
-Example:
-
--> { "execute": "query-tpm" }
-<- { "return":
- [
- { "model": "tpm-tis",
- "options":
- { "type": "passthrough",
- "data":
- { "cancel-path": "/sys/class/misc/tpm0/device/cancel",
- "path": "/dev/tpm0"
- }
- },
- "id": "tpm0"
- }
- ]
- }
-
-EQMP
-
{
.name = "query-tpm-models",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_tpm_models,
},
-
-SQMP
-query-tpm-models
-----------------
-
-Return a list of supported TPM models.
-
-Arguments: None
-
-Example:
-
--> { "execute": "query-tpm-models" }
-<- { "return": [ "tpm-tis" ] }
-
-EQMP
-
{
.name = "query-tpm-types",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_tpm_types,
},
-
-SQMP
-query-tpm-types
----------------
-
-Return a list of supported TPM types.
-
-Arguments: None
-
-Example:
-
--> { "execute": "query-tpm-types" }
-<- { "return": [ "passthrough" ] }
-
-EQMP
-
{
.name = "chardev-add",
.args_type = "id:s,backend:q",
.mhandler.cmd_new = qmp_marshal_chardev_add,
},
-
-SQMP
-chardev-add
-----------------
-
-Add a chardev.
-
-Arguments:
-
-- "id": the chardev's ID, must be unique (json-string)
-- "backend": chardev backend type + parameters
-
-Examples:
-
--> { "execute" : "chardev-add",
- "arguments" : { "id" : "foo",
- "backend" : { "type" : "null", "data" : {} } } }
-<- { "return": {} }
-
--> { "execute" : "chardev-add",
- "arguments" : { "id" : "bar",
- "backend" : { "type" : "file",
- "data" : { "out" : "/tmp/bar.log" } } } }
-<- { "return": {} }
-
--> { "execute" : "chardev-add",
- "arguments" : { "id" : "baz",
- "backend" : { "type" : "pty", "data" : {} } } }
-<- { "return": { "pty" : "/dev/pty/42" } }
-
-EQMP
-
{
.name = "chardev-remove",
.args_type = "id:s",
.mhandler.cmd_new = qmp_marshal_chardev_remove,
},
-
-
-SQMP
-chardev-remove
---------------
-
-Remove a chardev.
-
-Arguments:
-
-- "id": the chardev's ID, must exist and not be in use (json-string)
-
-Example:
-
--> { "execute": "chardev-remove", "arguments": { "id" : "foo" } }
-<- { "return": {} }
-
-EQMP
{
.name = "query-rx-filter",
.args_type = "name:s?",
.mhandler.cmd_new = qmp_marshal_query_rx_filter,
},
-
-SQMP
-query-rx-filter
----------------
-
-Show rx-filter information.
-
-Returns a json-array of rx-filter information for all NICs (or for the
-given NIC), returning an error if the given NIC doesn't exist, or
-given NIC doesn't support rx-filter querying, or given net client
-isn't a NIC.
-
-The query will clear the event notification flag of each NIC, then qemu
-will start to emit event to QMP monitor.
-
-Each array entry contains the following:
-
-- "name": net client name (json-string)
-- "promiscuous": promiscuous mode is enabled (json-bool)
-- "multicast": multicast receive state (one of 'normal', 'none', 'all')
-- "unicast": unicast receive state (one of 'normal', 'none', 'all')
-- "vlan": vlan receive state (one of 'normal', 'none', 'all') (Since 2.0)
-- "broadcast-allowed": allow to receive broadcast (json-bool)
-- "multicast-overflow": multicast table is overflowed (json-bool)
-- "unicast-overflow": unicast table is overflowed (json-bool)
-- "main-mac": main macaddr string (json-string)
-- "vlan-table": a json-array of active vlan id
-- "unicast-table": a json-array of unicast macaddr string
-- "multicast-table": a json-array of multicast macaddr string
-
-Example:
-
--> { "execute": "query-rx-filter", "arguments": { "name": "vnet0" } }
-<- { "return": [
- {
- "promiscuous": true,
- "name": "vnet0",
- "main-mac": "52:54:00:12:34:56",
- "unicast": "normal",
- "vlan": "normal",
- "vlan-table": [
- 4,
- 0
- ],
- "unicast-table": [
- ],
- "multicast": "normal",
- "multicast-overflow": false,
- "unicast-overflow": false,
- "multicast-table": [
- "01:00:5e:00:00:01",
- "33:33:00:00:00:01",
- "33:33:ff:12:34:56"
- ],
- "broadcast-allowed": false
- }
- ]
- }
-
-EQMP
-
{
.name = "blockdev-add",
.args_type = "options:q",
.mhandler.cmd_new = qmp_marshal_blockdev_add,
},
-
-SQMP
-blockdev-add
-------------
-
-Add a block device.
-
-This command is still a work in progress. It doesn't support all
-block drivers, it lacks a matching blockdev-del, and more. Stay away
-from it unless you want to help with its development.
-
-Arguments:
-
-- "options": block driver options
-
-Example (1):
-
--> { "execute": "blockdev-add",
- "arguments": { "options" : { "driver": "qcow2",
- "file": { "driver": "file",
- "filename": "test.qcow2" } } } }
-<- { "return": {} }
-
-Example (2):
-
--> { "execute": "blockdev-add",
- "arguments": {
- "options": {
- "driver": "qcow2",
- "id": "my_disk",
- "discard": "unmap",
- "cache": {
- "direct": true,
- "writeback": true
- },
- "file": {
- "driver": "file",
- "filename": "/tmp/test.qcow2"
- },
- "backing": {
- "driver": "raw",
- "file": {
- "driver": "file",
- "filename": "/dev/fdset/4"
- }
- }
- }
- }
- }
-
-<- { "return": {} }
-
-EQMP
-
{
.name = "query-named-block-nodes",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_named_block_nodes,
},
-
-SQMP
-@query-named-block-nodes
-------------------------
-
-Return a list of BlockDeviceInfo for all the named block driver nodes
-
-Example:
-
--> { "execute": "query-named-block-nodes" }
-<- { "return": [ { "ro":false,
- "drv":"qcow2",
- "encrypted":false,
- "file":"disks/test.qcow2",
- "node-name": "my-node",
- "backing_file_depth":1,
- "bps":1000000,
- "bps_rd":0,
- "bps_wr":0,
- "iops":1000000,
- "iops_rd":0,
- "iops_wr":0,
- "bps_max": 8000000,
- "bps_rd_max": 0,
- "bps_wr_max": 0,
- "iops_max": 0,
- "iops_rd_max": 0,
- "iops_wr_max": 0,
- "iops_size": 0,
- "write_threshold": 0,
- "image":{
- "filename":"disks/test.qcow2",
- "format":"qcow2",
- "virtual-size":2048000,
- "backing_file":"base.qcow2",
- "full-backing-filename":"disks/base.qcow2",
- "backing-filename-format":"qcow2",
- "snapshots":[
- {
- "id": "1",
- "name": "snapshot1",
- "vm-state-size": 0,
- "date-sec": 10000200,
- "date-nsec": 12,
- "vm-clock-sec": 206,
- "vm-clock-nsec": 30
- }
- ],
- "backing-image":{
- "filename":"disks/base.qcow2",
- "format":"qcow2",
- "virtual-size":2048000
- }
- } } ] }
-
-EQMP
-
{
.name = "query-memdev",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_memdev,
},
-
-SQMP
-query-memdev
-------------
-
-Show memory devices information.
-
-
-Example (1):
-
--> { "execute": "query-memdev" }
-<- { "return": [
- {
- "size": 536870912,
- "merge": false,
- "dump": true,
- "prealloc": false,
- "host-nodes": [0, 1],
- "policy": "bind"
- },
- {
- "size": 536870912,
- "merge": false,
- "dump": true,
- "prealloc": true,
- "host-nodes": [2, 3],
- "policy": "preferred"
- }
- ]
- }
-
-EQMP
-
{
.name = "query-memory-devices",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_memory_devices,
},
-
-SQMP
-@query-memory-devices
---------------------
-
-Return a list of memory devices.
-
-Example:
--> { "execute": "query-memory-devices" }
-<- { "return": [ { "data":
- { "addr": 5368709120,
- "hotpluggable": true,
- "hotplugged": true,
- "id": "d1",
- "memdev": "/objects/memX",
- "node": 0,
- "size": 1073741824,
- "slot": 0},
- "type": "dimm"
- } ] }
-EQMP
-
{
.name = "query-acpi-ospm-status",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_query_acpi_ospm_status,
},
-
-SQMP
-@query-acpi-ospm-status
---------------------
-
-Return list of ACPIOSTInfo for devices that support status reporting
-via ACPI _OST method.
-
-Example:
--> { "execute": "query-acpi-ospm-status" }
-<- { "return": [ { "device": "d1", "slot": "0", "slot-type": "DIMM", "source": 1, "status": 0},
- { "slot": "1", "slot-type": "DIMM", "source": 0, "status": 0},
- { "slot": "2", "slot-type": "DIMM", "source": 0, "status": 0},
- { "slot": "3", "slot-type": "DIMM", "source": 0, "status": 0}
- ]}
-EQMP
-
#if defined TARGET_I386
{
.name = "rtc-reset-reinjection",
@@ -4076,249 +703,43 @@ EQMP
.mhandler.cmd_new = qmp_marshal_rtc_reset_reinjection,
},
#endif
-
-SQMP
-rtc-reset-reinjection
----------------------
-
-Reset the RTC interrupt reinjection backlog.
-
-Arguments: None.
-
-Example:
-
--> { "execute": "rtc-reset-reinjection" }
-<- { "return": {} }
-EQMP
-
{
.name = "trace-event-get-state",
.args_type = "name:s",
.mhandler.cmd_new = qmp_marshal_trace_event_get_state,
},
-
-SQMP
-trace-event-get-state
----------------------
-
-Query the state of events.
-
-Example:
-
--> { "execute": "trace-event-get-state", "arguments": { "name": "qemu_memalign" } }
-<- { "return": [ { "name": "qemu_memalign", "state": "disabled" } ] }
-EQMP
-
{
.name = "trace-event-set-state",
.args_type = "name:s,enable:b,ignore-unavailable:b?",
.mhandler.cmd_new = qmp_marshal_trace_event_set_state,
},
-
-SQMP
-trace-event-set-state
----------------------
-
-Set the state of events.
-
-Example:
-
--> { "execute": "trace-event-set-state", "arguments": { "name": "qemu_memalign", "enable": "true" } }
-<- { "return": {} }
-EQMP
-
{
.name = "x-input-send-event",
.args_type = "console:i?,events:q",
.mhandler.cmd_new = qmp_marshal_x_input_send_event,
},
-
-SQMP
-@x-input-send-event
------------------
-
-Send input event to guest.
-
-Arguments:
-
-- "console": console index. (json-int, optional)
-- "events": list of input events.
-
-The consoles are visible in the qom tree, under
-/backend/console[$index]. They have a device link and head property, so
-it is possible to map which console belongs to which device and display.
-
-Note: this command is experimental, and not a stable API.
-
-Example (1):
-
-Press left mouse button.
-
--> { "execute": "x-input-send-event",
- "arguments": { "console": 0,
- "events": [ { "type": "btn",
- "data" : { "down": true, "button": "Left" } } ] } }
-<- { "return": {} }
-
--> { "execute": "x-input-send-event",
- "arguments": { "console": 0,
- "events": [ { "type": "btn",
- "data" : { "down": false, "button": "Left" } } ] } }
-<- { "return": {} }
-
-Example (2):
-
-Press ctrl-alt-del.
-
--> { "execute": "x-input-send-event",
- "arguments": { "console": 0, "events": [
- { "type": "key", "data" : { "down": true,
- "key": {"type": "qcode", "data": "ctrl" } } },
- { "type": "key", "data" : { "down": true,
- "key": {"type": "qcode", "data": "alt" } } },
- { "type": "key", "data" : { "down": true,
- "key": {"type": "qcode", "data": "delete" } } } ] } }
-<- { "return": {} }
-
-Example (3):
-
-Move mouse pointer to absolute coordinates (20000, 400).
-
--> { "execute": "x-input-send-event" ,
- "arguments": { "console": 0, "events": [
- { "type": "abs", "data" : { "axis": "X", "value" : 20000 } },
- { "type": "abs", "data" : { "axis": "Y", "value" : 400 } } ] } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "block-set-write-threshold",
.args_type = "node-name:s,write-threshold:l",
.mhandler.cmd_new = qmp_marshal_block_set_write_threshold,
},
-
-SQMP
-block-set-write-threshold
-------------
-
-Change the write threshold for a block drive. The threshold is an offset,
-thus must be non-negative. Default is no write threshold.
-Setting the threshold to zero disables it.
-
-Arguments:
-
-- "node-name": the node name in the block driver state graph (json-string)
-- "write-threshold": the write threshold in bytes (json-int)
-
-Example:
-
--> { "execute": "block-set-write-threshold",
- "arguments": { "node-name": "mydev",
- "write-threshold": 17179869184 } }
-<- { "return": {} }
-
-EQMP
-
{
.name = "query-rocker",
.args_type = "name:s",
.mhandler.cmd_new = qmp_marshal_query_rocker,
},
-
-SQMP
-Show rocker switch
-------------------
-
-Arguments:
-
-- "name": switch name
-
-Example:
-
--> { "execute": "query-rocker", "arguments": { "name": "sw1" } }
-<- { "return": {"name": "sw1", "ports": 2, "id": 1327446905938}}
-
-EQMP
-
{
.name = "query-rocker-ports",
.args_type = "name:s",
.mhandler.cmd_new = qmp_marshal_query_rocker_ports,
},
-
-SQMP
-Show rocker switch ports
-------------------------
-
-Arguments:
-
-- "name": switch name
-
-Example:
-
--> { "execute": "query-rocker-ports", "arguments": { "name": "sw1" } }
-<- { "return": [ {"duplex": "full", "enabled": true, "name": "sw1.1",
- "autoneg": "off", "link-up": true, "speed": 10000},
- {"duplex": "full", "enabled": true, "name": "sw1.2",
- "autoneg": "off", "link-up": true, "speed": 10000}
- ]}
-
-EQMP
-
{
.name = "query-rocker-of-dpa-flows",
.args_type = "name:s,tbl-id:i?",
.mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_flows,
},
-
-SQMP
-Show rocker switch OF-DPA flow tables
--------------------------------------
-
-Arguments:
-
-- "name": switch name
-- "tbl-id": (optional) flow table ID
-
-Example:
-
--> { "execute": "query-rocker-of-dpa-flows", "arguments": { "name": "sw1" } }
-<- { "return": [ {"key": {"in-pport": 0, "priority": 1, "tbl-id": 0},
- "hits": 138,
- "cookie": 0,
- "action": {"goto-tbl": 10},
- "mask": {"in-pport": 4294901760}
- },
- {...more...},
- ]}
-
-EQMP
-
{
.name = "query-rocker-of-dpa-groups",
.args_type = "name:s,type:i?",
.mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_groups,
},
-
-SQMP
-Show rocker OF-DPA group tables
--------------------------------
-
-Arguments:
-
-- "name": switch name
-- "type": (optional) group type
-
-Example:
-
--> { "execute": "query-rocker-of-dpa-groups", "arguments": { "name": "sw1" } }
-<- { "return": [ {"type": 0, "out-pport": 2, "pport": 2, "vlan-id": 3841,
- "pop-vlan": 1, "id": 251723778},
- {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3841,
- "pop-vlan": 1, "id": 251723776},
- {"type": 0, "out-pport": 1, "pport": 1, "vlan-id": 3840,
- "pop-vlan": 1, "id": 251658241},
- {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3840,
- "pop-vlan": 1, "id": 251658240}
- ]}
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (4 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 05/36] qapi: move examples to json schema marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:23 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 07/36] qapi: add some headings in docs marcandre.lureau
` (31 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Moving the remaining bits of documentation to the schema files.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 48 ++++++++++++++++++++++++++++++++++++++++++-
qmp-commands.hx | 62 --------------------------------------------------------
2 files changed, 47 insertions(+), 63 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 1383011..c8ee75d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1,6 +1,52 @@
# -*- Mode: Python -*-
+##
+# = Introduction
+#
+# This document describes all commands currently supported by QMP.
+#
+# Most of the time their usage is exactly the same as in the user Monitor, this
+# means that any other document which also describe commands (the manpage,
+# QEMU's manual, etc) can and should be consulted.
+#
+# QMP has two types of commands: regular and query commands. Regular commands
+# usually change the Virtual Machine's state someway, while query commands just
+# return information. The sections below are divided accordingly.
+#
+# It's important to observe that all communication examples are formatted in
+# a reader-friendly way, so that they're easier to understand. However, in real
+# protocol usage, they're emitted as a single line.
+#
+# Also, the following notation is used to denote data flow:
+#
+# Example:
+#
+# | -> data issued by the Client
+# | <- Server data response
+#
+# Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed
+# information on the Server command and response formats.
+#
+# = Stability Considerations
+#
+# The current QMP command set (described in this file) may be useful for a
+# number of use cases, however it's limited and several commands have bad
+# defined semantics, specially with regard to command completion.
+#
+# These problems are going to be solved incrementally in the next QEMU releases
+# and we're going to establish a deprecation policy for badly defined commands.
+#
+# If you're planning to adopt QMP, please observe the following:
+#
+# 1. The deprecation policy will take effect and be documented soon, please
+# check the documentation of each used command as soon as a new release of
+# QEMU is available
+#
+# 2. DO NOT rely on anything which is not explicit documented
+#
+# 3. Errors, in special, are not documented. Applications should NOT check
+# for specific errors classes or data (it's strongly recommended to only
+# check for the "error" key)
#
-# QAPI Schema
# QAPI common definitions
{ 'include': 'qapi/common.json' }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index c09918b..3a7af18 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1,65 +1,3 @@
-HXCOMM QMP dispatch table and documentation
-HXCOMM Text between SQMP and EQMP is copied to the QMP documentation file and
-HXCOMM does not show up in the other formats.
-
-SQMP
- QMP Supported Commands
- ----------------------
-
-This document describes all commands currently supported by QMP.
-
-Most of the time their usage is exactly the same as in the user Monitor, this
-means that any other document which also describe commands (the manpage,
-QEMU's manual, etc) can and should be consulted.
-
-QMP has two types of commands: regular and query commands. Regular commands
-usually change the Virtual Machine's state someway, while query commands just
-return information. The sections below are divided accordingly.
-
-It's important to observe that all communication examples are formatted in
-a reader-friendly way, so that they're easier to understand. However, in real
-protocol usage, they're emitted as a single line.
-
-Also, the following notation is used to denote data flow:
-
--> data issued by the Client
-<- Server data response
-
-Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed
-information on the Server command and response formats.
-
-NOTE: This document is temporary and will be replaced soon.
-
-1. Stability Considerations
-===========================
-
-The current QMP command set (described in this file) may be useful for a
-number of use cases, however it's limited and several commands have bad
-defined semantics, specially with regard to command completion.
-
-These problems are going to be solved incrementally in the next QEMU releases
-and we're going to establish a deprecation policy for badly defined commands.
-
-If you're planning to adopt QMP, please observe the following:
-
- 1. The deprecation policy will take effect and be documented soon, please
- check the documentation of each used command as soon as a new release of
- QEMU is available
-
- 2. DO NOT rely on anything which is not explicit documented
-
- 3. Errors, in special, are not documented. Applications should NOT check
- for specific errors classes or data (it's strongly recommended to only
- check for the "error" key)
-
-2. Regular Commands
-===================
-
-Server's responses in the examples below are always a success response, please
-refer to the QMP specification for more details on error responses.
-
-EQMP
-
{
.name = "quit",
.args_type = "",
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 07/36] qapi: add some headings in docs
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (5 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:26 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 08/36] qapi: add qapi2texi script marcandre.lureau
` (30 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Add some missing double-#, the doc parser can't easily distinguish doc
comments from comments to be ignored otherwise.
Also add some more section headings.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 12 ++++++++++--
qapi/block-core.json | 6 ++++--
qapi/block.json | 5 +++--
qapi/common.json | 5 +++--
qapi/event.json | 5 +++++
qapi/rocker.json | 3 +++
qapi/trace.json | 2 ++
qga/qapi-schema.json | 2 ++
8 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index c8ee75d..b01de49 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -67,6 +67,9 @@
{ 'include': 'qapi/introspect.json' }
##
+# = QMP commands
+
+##
# @qmp_capabilities:
#
# Enable QMP capabilities.
@@ -107,6 +110,7 @@
{ 'enum': 'LostTickPolicy',
'data': ['discard', 'delay', 'merge', 'slew' ] }
+##
# @add_client
#
# Allow client connections for VNC, Spice and socket based
@@ -590,6 +594,7 @@
'cache-miss': 'int', 'cache-miss-rate': 'number',
'overflow': 'int' } }
+##
# @MigrationStatus:
#
# An enumeration of migration status.
@@ -880,6 +885,7 @@
##
{ 'command': 'query-migrate-capabilities', 'returns': ['MigrationCapabilityStatus']}
+##
# @MigrationParameter
#
# Migration parameters enumeration
@@ -903,7 +909,7 @@
{ 'enum': 'MigrationParameter',
'data': ['compress-level', 'compress-threads', 'decompress-threads'] }
-#
+##
# @migrate-set-parameters
#
# Set the following migration parameters
@@ -927,7 +933,7 @@
'*compress-threads': 'int',
'*decompress-threads': 'int'} }
-#
+##
# @MigrationParameters
#
# @compress-level: compression level
@@ -2748,6 +2754,7 @@
##
{ 'command': 'migrate-incoming', 'data': {'uri': 'str' } }
+##
# @xen-save-devices-state:
#
# Save the state of all devices to file. The RAM and the block devices
@@ -3639,6 +3646,7 @@
##
{ 'command': 'query-cpu-definitions', 'returns': ['CpuDefinitionInfo'] }
+##
# @AddfdInfo:
#
# Information about a file descriptor that was added to an fd set.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index d5b6ed1..ff2d4a6 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1,6 +1,7 @@
# -*- Mode: Python -*-
-#
-# QAPI block core definitions (vm unrelated)
+
+##
+# == QAPI block core definitions (vm unrelated)
# QAPI common definitions
{ 'include': 'common.json' }
@@ -2440,6 +2441,7 @@
'offset': 'int',
'speed' : 'int' } }
+##
# @PreallocMode
#
# Preallocation mode of QEMU image file
diff --git a/qapi/block.json b/qapi/block.json
index 9902b94..487abb2 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -1,6 +1,7 @@
# -*- Mode: Python -*-
-#
-# QAPI block definitions (vm related)
+
+##
+# = QAPI block definitions (vm related)
# QAPI block core definitions
{ 'include': 'block-core.json' }
diff --git a/qapi/common.json b/qapi/common.json
index 4e94c89..0972f4a 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -1,6 +1,7 @@
# -*- Mode: Python -*-
-#
-# QAPI common definitions
+
+##
+# = QAPI common definitions
##
# @ErrorClass
diff --git a/qapi/event.json b/qapi/event.json
index f0cef01..ce5853d 100644
--- a/qapi/event.json
+++ b/qapi/event.json
@@ -1,3 +1,8 @@
+# -*- Mode: Python -*-
+
+##
+# = Events
+
##
# @SHUTDOWN
#
diff --git a/qapi/rocker.json b/qapi/rocker.json
index 7cfccc4..fe17d36 100644
--- a/qapi/rocker.json
+++ b/qapi/rocker.json
@@ -1,4 +1,7 @@
##
+# = Rocker API
+
+##
# @Rocker:
#
# Rocker switch information.
diff --git a/qapi/trace.json b/qapi/trace.json
index 5111640..4faa6d3 100644
--- a/qapi/trace.json
+++ b/qapi/trace.json
@@ -5,6 +5,8 @@
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.
+##
+# = Tracing commands
##
# @TraceEventState:
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 82894c6..c138a41 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -808,6 +808,7 @@
{ 'command': 'guest-set-user-password',
'data': { 'username': 'str', 'password': 'str', 'crypted': 'bool' } }
+##
# @GuestMemoryBlock:
#
# @phys-index: Arbitrary guest-specific unique identifier of the MEMORY BLOCK.
@@ -907,6 +908,7 @@
'data': {'mem-blks': ['GuestMemoryBlock'] },
'returns': ['GuestMemoryBlockResponse'] }
+##
# @GuestMemoryBlockInfo:
#
# @size: the size (in bytes) of the guest memory blocks,
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 08/36] qapi: add qapi2texi script
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (6 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 07/36] qapi: add some headings in docs marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:34 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 09/36] qapi: remove qmp-events.txt marcandre.lureau
` (29 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
As the name suggests, the qapi2texi script converts JSON QAPI
description into a standalone texi file suitable for different target
formats.
It parses the following kind of blocks with some little variations:
##
# = Section
# == Subsection
#
# Some text foo with *emphasis*
# 1. with a list
# 2. like that
#
# And some code:
# | <- do this
# | -> get that
#
##
##
# @symbol
#
# Symbol body ditto ergo sum. Foo bar
# baz ding.
#
# @arg: foo
# @arg: #optional foo
#
# Returns: returns bla bla
#
# Or bla blah
#
# Since: version
# Notes: notes, comments can have
# - itemized list
# - like this
#
# and continue...
#
# Example:
#
# -> { "execute": "quit" }
# <- { "return": {} }
#
##
Thanks to the json declaration, it's able to give extra information
about the type of arguments and return value expected.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 88 +++++++++++++++-
scripts/qapi2texi.py | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 379 insertions(+), 2 deletions(-)
create mode 100755 scripts/qapi2texi.py
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 27894c1..2a9b6e5 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -112,6 +112,67 @@ class QAPIExprError(Exception):
"%s:%d: %s" % (self.info['file'], self.info['line'], self.msg)
+class QAPIDoc:
+ def __init__(self, comment):
+ self.symbol = None
+ self.comment = ""
+ self.args = OrderedDict()
+ self.meta = OrderedDict()
+ self.section = None
+
+ for line in comment.split('\n'):
+ sline = ' '.join(line.split())
+ split = sline.split(' ', 1)
+ key = split[0].rstrip(':')
+
+ if line.startswith(" @"):
+ key = key[1:]
+ sline = split[1] if len(split) > 1 else ""
+ if self.symbol is None:
+ self.symbol = key
+ else:
+ self.start_section(self.args, key)
+ elif self.symbol and \
+ key in ("Since", "Returns", "Notes", "Note", "Example"):
+ sline = split[1] if len(split) > 1 else ""
+ line = None
+ self.start_section(self.meta, key)
+
+ if self.section and self.section[1] == "Example":
+ self.append_comment(line)
+ else:
+ self.append_comment(sline)
+
+ self.end_section()
+
+ def append_comment(self, line):
+ if line is None:
+ return
+ if self.section is not None:
+ if self.section[-1] == "" and line == "":
+ self.end_section()
+ else:
+ self.section.append(line)
+ elif self.comment == "":
+ self.comment = line
+ else:
+ self.comment += "\n" + line
+
+ def end_section(self):
+ if self.section is not None:
+ dic = self.section[0]
+ key = self.section[1]
+ doc = "\n".join(self.section[2:])
+ if key != "Example":
+ doc = doc.strip()
+ dic[key] = doc
+ self.section = None
+
+ def start_section(self, dic, key):
+ self.end_section()
+ self.section = [dic, key] # .. remaining elems will be the doc
+
+
class QAPISchemaParser(object):
def __init__(self, fp, previously_included=[], incl_info=None):
@@ -127,11 +188,14 @@ class QAPISchemaParser(object):
self.line = 1
self.line_pos = 0
self.exprs = []
+ self.comment = None
+ self.apidoc = incl_info['doc'] if incl_info else []
self.accept()
while self.tok is not None:
expr_info = {'file': fname, 'line': self.line,
- 'parent': self.incl_info}
+ 'parent': self.incl_info, 'doc': self.apidoc}
+ self.apidoc = []
expr = self.get_expr(False)
if isinstance(expr, dict) and "include" in expr:
if len(expr) != 1:
@@ -152,6 +216,8 @@ class QAPISchemaParser(object):
inf = inf['parent']
# skip multiple include of the same file
if incl_abs_fname in previously_included:
+ expr_info['doc'].extend(self.apidoc)
+ self.apidoc = expr_info['doc']
continue
try:
fobj = open(incl_abs_fname, 'r')
@@ -166,6 +232,12 @@ class QAPISchemaParser(object):
'info': expr_info}
self.exprs.append(expr_elem)
+ def append_doc(self):
+ if self.comment:
+ apidoc = QAPIDoc(self.comment)
+ self.apidoc.append(apidoc)
+ self.comment = None
+
def accept(self):
while True:
self.tok = self.src[self.cursor]
@@ -174,8 +246,20 @@ class QAPISchemaParser(object):
self.val = None
if self.tok == '#':
- self.cursor = self.src.find('\n', self.cursor)
+ end = self.src.find('\n', self.cursor)
+ line = self.src[self.cursor:end+1]
+ # start a comment section after ##
+ if line[0] == "#":
+ if self.comment is None:
+ self.comment = ""
+ # skip modeline
+ elif line.find("-*") == -1 and self.comment is not None:
+ self.comment += line
+ if self.src[end] == "\n" and self.src[end+1] == "\n":
+ self.append_doc()
+ self.cursor = end
elif self.tok in ['{', '}', ':', ',', '[', ']']:
+ self.append_doc()
return
elif self.tok == "'":
string = ''
diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
new file mode 100755
index 0000000..76ade1b
--- /dev/null
+++ b/scripts/qapi2texi.py
@@ -0,0 +1,293 @@
+#!/usr/bin/env python
+# QAPI texi generator
+#
+# This work is licensed under the terms of the GNU GPL, version 2.
+# See the COPYING file in the top-level directory.
+"""This script produces the documentation of a qapi schema in texinfo format"""
+import re
+import sys
+
+from qapi import QAPISchemaParser, QAPISchemaError, check_exprs, QAPIExprError
+
+COMMAND_FMT = """
+@deftypefn {type} {{{ret}}} {name} @
+{{{args}}}
+
+{body}
+
+@end deftypefn
+
+""".format
+
+ENUM_FMT = """
+@deftp Enum {name}
+
+{body}
+
+@end deftp
+
+""".format
+
+STRUCT_FMT = """
+@deftp {type} {name} @
+{{{attrs}}}
+
+{body}
+
+@end deftp
+
+""".format
+
+EXAMPLE_FMT = """@example
+{code}
+@end example
+""".format
+
+
+def subst_emph(doc):
+ return re.sub(r'\*(\w*)\*', r'@emph{\1}', doc)
+
+
+def subst_vars(doc):
+ return re.sub(r'@(\w*)', r'@var{\1}', doc)
+
+
+def subst_braces(doc):
+ return doc.replace("{", "@{").replace("}", "@}")
+
+
+def texi_example(doc):
+ return EXAMPLE_FMT(code=subst_braces(doc).strip('\n'))
+
+
+def texi_comment(doc):
+ lines = []
+ doc = subst_vars(doc)
+ doc = subst_emph(doc)
+ inlist = False
+ lastempty = False
+ for line in doc.split('\n'):
+ empty = line == ""
+
+ if line.startswith("| "):
+ line = EXAMPLE_FMT(code=line[1:])
+ elif line.startswith("= "):
+ line = "@section " + line[1:]
+ elif line.startswith("== "):
+ line = "@subsection " + line[2:]
+ elif re.match("^([0-9]*[.) ]) ", line):
+ if not inlist:
+ lines.append("@enumerate")
+ inlist = "enumerate"
+ line = line[line.find(" ")+1:]
+ lines.append("@item")
+ elif re.match("^[o*-] ", line):
+ if not inlist:
+ lines.append("@itemize %s" % {'o': "@bullet",
+ '*': "@minus",
+ '-': ""}[line[0]])
+ inlist = "itemize"
+ lines.append("@item")
+ line = line[2:]
+ elif lastempty and inlist:
+ lines.append("@end %s\n" % inlist)
+ inlist = False
+
+ lastempty = empty
+ lines.append(line)
+
+ if inlist:
+ lines.append("@end %s\n" % inlist)
+ return "\n".join(lines)
+
+
+def texi_args(expr):
+ data = expr["data"] if "data" in expr else {}
+ if isinstance(data, str):
+ args = data
+ else:
+ args = []
+ for name, typ in data.iteritems():
+ # optional arg
+ if name.startswith("*"):
+ name = name[1:]
+ args.append("['%s': @var{%s}]" % (name, typ))
+ # regular arg
+ else:
+ args.append("'%s': @var{%s}" % (name, typ))
+ args = ", ".join(args)
+ return args
+
+
+def texi_body(doc, arg="@var"):
+ body = "@table %s\n" % arg
+ for arg, desc in doc.args.iteritems():
+ if desc.startswith("#optional"):
+ desc = desc[10:]
+ arg += "*"
+ body += "@item %s\n%s\n" % (arg, texi_comment(desc))
+ body += "@end table\n"
+ body += texi_comment(doc.comment)
+
+ for k in ("Returns", "Note", "Notes", "Since", "Example"):
+ if k not in doc.meta:
+ continue
+ func = texi_comment if k != "Example" else texi_example
+ body += "\n@quotation %s\n%s\n@end quotation" % \
+ (k, func(doc.meta[k]))
+ return body
+
+
+def texi_alternate(expr, doc):
+ args = texi_args(expr)
+ body = texi_body(doc)
+ return STRUCT_FMT(type="Alternate",
+ name=doc.symbol,
+ attrs="[ " + args + " ]",
+ body=body)
+
+
+def texi_union(expr, doc):
+ args = texi_args(expr)
+ body = texi_body(doc)
+ return STRUCT_FMT(type="Union",
+ name=doc.symbol,
+ attrs="[ " + args + " ]",
+ body=body)
+
+
+def texi_enum(_, doc):
+ body = texi_body(doc, "@samp")
+ return ENUM_FMT(name=doc.symbol,
+ body=body)
+
+
+def texi_struct(expr, doc):
+ args = texi_args(expr)
+ body = texi_body(doc)
+ return STRUCT_FMT(type="Struct",
+ name=doc.symbol,
+ attrs="@{ " + args + " @}",
+ body=body)
+
+
+def texi_command(expr, doc):
+ args = texi_args(expr)
+ ret = expr["returns"] if "returns" in expr else ""
+ body = texi_body(doc)
+ return COMMAND_FMT(type="Command",
+ name=doc.symbol,
+ ret=ret,
+ args="(" + args + ")",
+ body=body)
+
+
+def texi_event(expr, doc):
+ args = texi_args(expr)
+ body = texi_body(doc)
+ return COMMAND_FMT(type="Event",
+ name=doc.symbol,
+ ret="",
+ args="(" + args + ")",
+ body=body)
+
+
+def parse_schema(fname):
+ try:
+ schema = QAPISchemaParser(open(fname, "r"))
+ check_exprs(schema.exprs)
+ return schema.exprs
+ except (QAPISchemaError, QAPIExprError), err:
+ print >>sys.stderr, err
+ exit(1)
+
+def main(argv):
+ if len(argv) != 5:
+ print >>sys.stderr, "%s: need exactly 4 arguments" % argv[0]
+ sys.exit(1)
+
+ exprs = parse_schema(argv[4])
+
+ print r"""
+\input texinfo
+@setfilename {filename}
+@documentlanguage en
+@exampleindent 0
+@paragraphindent 0
+
+@settitle {title}
+
+@ifinfo
+@direntry
+* QEMU: (qemu-doc). {title}
+@end direntry
+@end ifinfo
+
+@titlepage
+@title {title} {version}
+@end titlepage
+
+@ifnottex
+@node Top
+@top
+
+This is the API reference for QEMU {version}.
+
+@menu
+* API Reference::
+* Commands and Events Index::
+* Data Types Index::
+@end menu
+
+@end ifnottex
+
+@contents
+
+@node API Reference
+@chapter API Reference
+
+@c man begin DESCRIPTION
+""".format(title=argv[1], version=argv[2], filename=argv[3])
+
+ for cmd in exprs:
+ try:
+ expr = cmd['expr']
+ docs = cmd['info']['doc']
+
+ (kind, _) = expr.items()[0]
+
+ for doc in docs[0:-1]:
+ print texi_body(doc)
+
+ texi = {"command": texi_command,
+ "struct": texi_struct,
+ "enum": texi_enum,
+ "union": texi_union,
+ "alternate": texi_alternate,
+ "event": texi_event}
+ try:
+ print texi[kind](expr, docs[-1])
+ except KeyError:
+ raise ValueError("Unknown expression kind '%s'" % kind)
+ except:
+ print >>sys.stderr, "error at @%s" % cmd
+ raise
+
+ print """
+@c man end
+
+@c man begin SEEALSO
+The HTML documentation of QEMU for more precise information.
+@c man end
+
+@node Commands and Events Index
+@unnumbered Commands and Events Index
+@printindex fn
+@node Data Types Index
+@unnumbered Data Types Index
+@printindex tp
+@bye
+"""
+
+if __name__ == "__main__":
+ main(sys.argv)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 09/36] qapi: remove qmp-events.txt
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (7 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 08/36] qapi: add qapi2texi script marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:40 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 10/36] texi2pod: learn quotation, deftp and deftypefn marcandre.lureau
` (28 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Move the examples in the json file with the rest of the documentation to
avoid duplication.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
docs/qmp/qmp-events.txt | 664 ------------------------------------------------
qapi/block-core.json | 59 ++++-
qapi/block.json | 9 +
qapi/event.json | 206 +++++++++++++++
4 files changed, 272 insertions(+), 666 deletions(-)
delete mode 100644 docs/qmp/qmp-events.txt
diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt
deleted file mode 100644
index d92cc48..0000000
--- a/docs/qmp/qmp-events.txt
+++ /dev/null
@@ -1,664 +0,0 @@
- QEMU Machine Protocol Events
- ============================
-
-ACPI_DEVICE_OST
----------------
-
-Emitted when guest executes ACPI _OST method.
-
- - data: ACPIOSTInfo type as described in qapi-schema.json
-
-{ "event": "ACPI_DEVICE_OST",
- "data": { "device": "d1", "slot": "0", "slot-type": "DIMM", "source": 1, "status": 0 } }
-
-BALLOON_CHANGE
---------------
-
-Emitted when the guest changes the actual BALLOON level. This
-value is equivalent to the 'actual' field return by the
-'query-balloon' command
-
-Data:
-
-- "actual": actual level of the guest memory balloon in bytes (json-number)
-
-Example:
-
-{ "event": "BALLOON_CHANGE",
- "data": { "actual": 944766976 },
- "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-
-BLOCK_IMAGE_CORRUPTED
----------------------
-
-Emitted when a disk image is being marked corrupt. The image can be
-identified by its device or node name. The 'device' field is always
-present for compatibility reasons, but it can be empty ("") if the
-image does not have a device name associated.
-
-Data:
-
-- "device": Device name (json-string)
-- "node-name": Node name (json-string, optional)
-- "msg": Informative message (e.g., reason for the corruption)
- (json-string)
-- "offset": If the corruption resulted from an image access, this
- is the host's access offset into the image
- (json-int, optional)
-- "size": If the corruption resulted from an image access, this
- is the access size (json-int, optional)
-
-Example:
-
-{ "event": "BLOCK_IMAGE_CORRUPTED",
- "data": { "device": "ide0-hd0", "node-name": "node0",
- "msg": "Prevented active L1 table overwrite", "offset": 196608,
- "size": 65536 },
- "timestamp": { "seconds": 1378126126, "microseconds": 966463 } }
-
-BLOCK_IO_ERROR
---------------
-
-Emitted when a disk I/O error occurs.
-
-Data:
-
-- "device": device name (json-string)
-- "operation": I/O operation (json-string, "read" or "write")
-- "action": action that has been taken, it's one of the following (json-string):
- "ignore": error has been ignored
- "report": error has been reported to the device
- "stop": the VM is going to stop because of the error
-
-Example:
-
-{ "event": "BLOCK_IO_ERROR",
- "data": { "device": "ide0-hd1",
- "operation": "write",
- "action": "stop" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-Note: If action is "stop", a STOP event will eventually follow the
-BLOCK_IO_ERROR event.
-
-BLOCK_JOB_CANCELLED
--------------------
-
-Emitted when a block job has been cancelled.
-
-Data:
-
-- "type": Job type (json-string; "stream" for image streaming
- "commit" for block commit)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-
-Example:
-
-{ "event": "BLOCK_JOB_CANCELLED",
- "data": { "type": "stream", "device": "virtio-disk0",
- "len": 10737418240, "offset": 134217728,
- "speed": 0 },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-BLOCK_JOB_COMPLETED
--------------------
-
-Emitted when a block job has completed.
-
-Data:
-
-- "type": Job type (json-string; "stream" for image streaming
- "commit" for block commit)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-- "error": Error message (json-string, optional)
- Only present on failure. This field contains a human-readable
- error message. There are no semantics other than that streaming
- has failed and clients should not try to interpret the error
- string.
-
-Example:
-
-{ "event": "BLOCK_JOB_COMPLETED",
- "data": { "type": "stream", "device": "virtio-disk0",
- "len": 10737418240, "offset": 10737418240,
- "speed": 0 },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-BLOCK_JOB_ERROR
----------------
-
-Emitted when a block job encounters an error.
-
-Data:
-
-- "device": device name (json-string)
-- "operation": I/O operation (json-string, "read" or "write")
-- "action": action that has been taken, it's one of the following (json-string):
- "ignore": error has been ignored, the job may fail later
- "report": error will be reported and the job canceled
- "stop": error caused job to be paused
-
-Example:
-
-{ "event": "BLOCK_JOB_ERROR",
- "data": { "device": "ide0-hd1",
- "operation": "write",
- "action": "stop" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-BLOCK_JOB_READY
----------------
-
-Emitted when a block job is ready to complete.
-
-Data:
-
-- "type": Job type (json-string; "stream" for image streaming
- "commit" for block commit)
-- "device": Device name (json-string)
-- "len": Maximum progress value (json-int)
-- "offset": Current progress value (json-int)
- On success this is equal to len.
- On failure this is less than len.
-- "speed": Rate limit, bytes per second (json-int)
-
-Example:
-
-{ "event": "BLOCK_JOB_READY",
- "data": { "device": "drive0", "type": "mirror", "speed": 0,
- "len": 2097152, "offset": 2097152 }
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-Note: The "ready to complete" status is always reset by a BLOCK_JOB_ERROR
-event.
-
-DEVICE_DELETED
---------------
-
-Emitted whenever the device removal completion is acknowledged
-by the guest.
-At this point, it's safe to reuse the specified device ID.
-Device removal can be initiated by the guest or by HMP/QMP commands.
-
-Data:
-
-- "device": device name (json-string, optional)
-- "path": device path (json-string)
-
-{ "event": "DEVICE_DELETED",
- "data": { "device": "virtio-net-pci-0",
- "path": "/machine/peripheral/virtio-net-pci-0" },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-DEVICE_TRAY_MOVED
------------------
-
-It's emitted whenever the tray of a removable device is moved by the guest
-or by HMP/QMP commands.
-
-Data:
-
-- "device": device name (json-string)
-- "tray-open": true if the tray has been opened or false if it has been closed
- (json-bool)
-
-{ "event": "DEVICE_TRAY_MOVED",
- "data": { "device": "ide1-cd0",
- "tray-open": true
- },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-GUEST_PANICKED
---------------
-
-Emitted when guest OS panic is detected.
-
-Data:
-
-- "action": Action that has been taken (json-string, currently always "pause").
-
-Example:
-
-{ "event": "GUEST_PANICKED",
- "data": { "action": "pause" } }
-
-MEM_UNPLUG_ERROR
---------------------
-Emitted when memory hot unplug error occurs.
-
-Data:
-
-- "device": device name (json-string)
-- "msg": Informative message (e.g., reason for the error) (json-string)
-
-Example:
-
-{ "event": "MEM_UNPLUG_ERROR"
- "data": { "device": "dimm1",
- "msg": "acpi: device unplug for unsupported device"
- },
- "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
-
-NIC_RX_FILTER_CHANGED
----------------------
-
-The event is emitted once until the query command is executed,
-the first event will always be emitted.
-
-Data:
-
-- "name": net client name (json-string)
-- "path": device path (json-string)
-
-{ "event": "NIC_RX_FILTER_CHANGED",
- "data": { "name": "vnet0",
- "path": "/machine/peripheral/vnet0/virtio-backend" },
- "timestamp": { "seconds": 1368697518, "microseconds": 326866 } }
-}
-
-POWERDOWN
----------
-
-Emitted when the Virtual Machine is powered down through the power
-control system, such as via ACPI.
-
-Data: None.
-
-Example:
-
-{ "event": "POWERDOWN",
- "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
-
-QUORUM_FAILURE
---------------
-
-Emitted by the Quorum block driver if it fails to establish a quorum.
-
-Data:
-
-- "reference": device name if defined else node name.
-- "sector-num": Number of the first sector of the failed read operation.
-- "sectors-count": Failed read operation sector count.
-
-Example:
-
-{ "event": "QUORUM_FAILURE",
- "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
- "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
-
-QUORUM_REPORT_BAD
------------------
-
-Emitted to report a corruption of a Quorum file.
-
-Data:
-
-- "error": Error message (json-string, optional)
- Only present on failure. This field contains a human-readable
- error message. There are no semantics other than that the
- block layer reported an error and clients should not try to
- interpret the error string.
-- "node-name": The graph node name of the block driver state.
-- "sector-num": Number of the first sector of the failed read operation.
-- "sectors-count": Failed read operation sector count.
-
-Example:
-
-{ "event": "QUORUM_REPORT_BAD",
- "data": { "node-name": "1.raw", "sector-num": 345435, "sectors-count": 5 },
- "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
-
-RESET
------
-
-Emitted when the Virtual Machine is reset.
-
-Data: None.
-
-Example:
-
-{ "event": "RESET",
- "timestamp": { "seconds": 1267041653, "microseconds": 9518 } }
-
-RESUME
-------
-
-Emitted when the Virtual Machine resumes execution.
-
-Data: None.
-
-Example:
-
-{ "event": "RESUME",
- "timestamp": { "seconds": 1271770767, "microseconds": 582542 } }
-
-RTC_CHANGE
-----------
-
-Emitted when the guest changes the RTC time.
-
-Data:
-
-- "offset": Offset between base RTC clock (as specified by -rtc base), and
-new RTC clock value (json-number)
-
-Example:
-
-{ "event": "RTC_CHANGE",
- "data": { "offset": 78 },
- "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
-
-SHUTDOWN
---------
-
-Emitted when the Virtual Machine has shut down, indicating that qemu
-is about to exit.
-
-Data: None.
-
-Example:
-
-{ "event": "SHUTDOWN",
- "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
-
-Note: If the command-line option "-no-shutdown" has been specified, a STOP
-event will eventually follow the SHUTDOWN event.
-
-SPICE_CONNECTED
----------------
-
-Emitted when a SPICE client connects.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-
-Example:
-
-{ "timestamp": {"seconds": 1290688046, "microseconds": 388707},
- "event": "SPICE_CONNECTED",
- "data": {
- "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
- "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
-}}
-
-SPICE_DISCONNECTED
-------------------
-
-Emitted when a SPICE client disconnects.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-
-Example:
-
-{ "timestamp": {"seconds": 1290688046, "microseconds": 388707},
- "event": "SPICE_DISCONNECTED",
- "data": {
- "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
- "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
-}}
-
-SPICE_INITIALIZED
------------------
-
-Emitted after initial handshake and authentication takes place (if any)
-and the SPICE channel is up and running
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "port": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "connection-id": spice connection id. All channels with the same id
- belong to the same spice session (json-int)
- - "channel-type": channel type. "1" is the main control channel, filter for
- this one if you want track spice sessions only (json-int)
- - "channel-id": channel id. Usually "0", might be different needed when
- multiple channels of the same type exist, such as multiple
- display channels in a multihead setup (json-int)
- - "tls": whevener the channel is encrypted (json-bool)
-
-Example:
-
-{ "timestamp": {"seconds": 1290688046, "microseconds": 417172},
- "event": "SPICE_INITIALIZED",
- "data": {"server": {"auth": "spice", "port": "5921",
- "family": "ipv4", "host": "127.0.0.1"},
- "client": {"port": "49004", "family": "ipv4", "channel-type": 3,
- "connection-id": 1804289383, "host": "127.0.0.1",
- "channel-id": 0, "tls": true}
-}}
-
-SPICE_MIGRATE_COMPLETED
------------------------
-
-Emitted when SPICE migration has completed
-
-Data: None.
-
-Example:
-
-{ "timestamp": {"seconds": 1290688046, "microseconds": 417172},
- "event": "SPICE_MIGRATE_COMPLETED" }
-
-MIGRATION
----------
-
-Emitted when a migration event happens
-
-Data: None.
-
- - "status": migration status
- See MigrationStatus in ~/qapi-schema.json for possible values
-
-Example:
-
-{"timestamp": {"seconds": 1432121972, "microseconds": 744001},
- "event": "MIGRATION", "data": {"status": "completed"}}
-
-STOP
-----
-
-Emitted when the Virtual Machine is stopped.
-
-Data: None.
-
-Example:
-
-{ "event": "STOP",
- "timestamp": { "seconds": 1267041730, "microseconds": 281295 } }
-
-SUSPEND
--------
-
-Emitted when guest enters S3 state.
-
-Data: None.
-
-Example:
-
-{ "event": "SUSPEND",
- "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
-
-SUSPEND_DISK
-------------
-
-Emitted when the guest makes a request to enter S4 state.
-
-Data: None.
-
-Example:
-
-{ "event": "SUSPEND_DISK",
- "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
-
-Note: QEMU shuts down when entering S4 state.
-
-VNC_CONNECTED
--------------
-
-Emitted when a VNC client establishes a connection.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
-
-Example:
-
-{ "event": "VNC_CONNECTED",
- "data": {
- "server": { "auth": "sasl", "family": "ipv4",
- "service": "5901", "host": "0.0.0.0" },
- "client": { "family": "ipv4", "service": "58425",
- "host": "127.0.0.1" } },
- "timestamp": { "seconds": 1262976601, "microseconds": 975795 } }
-
-
-Note: This event is emitted before any authentication takes place, thus
-the authentication ID is not provided.
-
-VNC_DISCONNECTED
-----------------
-
-Emitted when the connection is closed.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "x509_dname": TLS dname (json-string, optional)
- - "sasl_username": SASL username (json-string, optional)
-
-Example:
-
-{ "event": "VNC_DISCONNECTED",
- "data": {
- "server": { "auth": "sasl", "family": "ipv4",
- "service": "5901", "host": "0.0.0.0" },
- "client": { "family": "ipv4", "service": "58425",
- "host": "127.0.0.1", "sasl_username": "luiz" } },
- "timestamp": { "seconds": 1262976601, "microseconds": 975795 } }
-
-VNC_INITIALIZED
----------------
-
-Emitted after authentication takes place (if any) and the VNC session is
-made active.
-
-Data:
-
-- "server": Server information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "auth": authentication method (json-string, optional)
-- "client": Client information (json-object)
- - "host": IP address (json-string)
- - "service": port number (json-string)
- - "family": address family (json-string, "ipv4" or "ipv6")
- - "x509_dname": TLS dname (json-string, optional)
- - "sasl_username": SASL username (json-string, optional)
-
-Example:
-
-{ "event": "VNC_INITIALIZED",
- "data": {
- "server": { "auth": "sasl", "family": "ipv4",
- "service": "5901", "host": "0.0.0.0"},
- "client": { "family": "ipv4", "service": "46089",
- "host": "127.0.0.1", "sasl_username": "luiz" } },
- "timestamp": { "seconds": 1263475302, "microseconds": 150772 } }
-
-VSERPORT_CHANGE
----------------
-
-Emitted when the guest opens or closes a virtio-serial port.
-
-Data:
-
-- "id": device identifier of the virtio-serial port (json-string)
-- "open": true if the guest has opened the virtio-serial port (json-bool)
-
-Example:
-
-{ "event": "VSERPORT_CHANGE",
- "data": { "id": "channel0", "open": true },
- "timestamp": { "seconds": 1401385907, "microseconds": 422329 } }
-
-WAKEUP
-------
-
-Emitted when the guest has woken up from S3 and is running.
-
-Data: None.
-
-Example:
-
-{ "event": "WAKEUP",
- "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
-
-WATCHDOG
---------
-
-Emitted when the watchdog device's timer is expired.
-
-Data:
-
-- "action": Action that has been taken, it's one of the following (json-string):
- "reset", "shutdown", "poweroff", "pause", "debug", or "none"
-
-Example:
-
-{ "event": "WATCHDOG",
- "data": { "action": "reset" },
- "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
-
-Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is
-followed respectively by the RESET, SHUTDOWN, or STOP events.
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ff2d4a6..36d2f76 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2277,7 +2277,10 @@
##
# @BLOCK_IMAGE_CORRUPTED
#
-# Emitted when a corruption has been detected in a disk image
+# Emitted when a disk image is being marked corrupt. The image can be
+# identified by its device or node name. The 'device' field is always
+# present for compatibility reasons, but it can be empty ("") if the
+# image does not have a device name associated.
#
# @device: device name. This is always present for compatibility
# reasons, but it can be empty ("") if the image does not
@@ -2295,10 +2298,18 @@
# @size: #optional, if the corruption resulted from an image access, this is
# the access size
#
-# fatal: if set, the image is marked corrupt and therefore unusable after this
+# @fatal: if set, the image is marked corrupt and therefore unusable after this
# event and must be repaired (Since 2.2; before, every
# BLOCK_IMAGE_CORRUPTED event was fatal)
#
+# Example:
+#
+# <- { "event": "BLOCK_IMAGE_CORRUPTED",
+# "data": { "device": "ide0-hd0", "node-name": "node0",
+# "msg": "Prevented active L1 table overwrite", "offset": 196608,
+# "size": 65536 },
+# "timestamp": { "seconds": 1378126126, "microseconds": 966463 } }
+#
# Since: 1.7
##
{ 'event': 'BLOCK_IMAGE_CORRUPTED',
@@ -2333,6 +2344,15 @@
# BLOCK_IO_ERROR event
#
# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "BLOCK_IO_ERROR",
+# "data": { "device": "ide0-hd1",
+# "operation": "write",
+# "action": "stop" },
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
##
{ 'event': 'BLOCK_IO_ERROR',
'data': { 'device': 'str', 'operation': 'IoOperationType',
@@ -2361,6 +2381,15 @@
# interpret the error string
#
# Since: 1.1
+#
+# Example:
+#
+# <- { "event": "BLOCK_JOB_COMPLETED",
+# "data": { "type": "stream", "device": "virtio-disk0",
+# "len": 10737418240, "offset": 10737418240,
+# "speed": 0 },
+# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
+#
##
{ 'event': 'BLOCK_JOB_COMPLETED',
'data': { 'type' : 'BlockJobType',
@@ -2387,6 +2416,15 @@
# @speed: rate limit, bytes per second
#
# Since: 1.1
+#
+# Example:
+#
+# <- { "event": "BLOCK_JOB_CANCELLED",
+# "data": { "type": "stream", "device": "virtio-disk0",
+# "len": 10737418240, "offset": 134217728,
+# "speed": 0 },
+# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
+#
##
{ 'event': 'BLOCK_JOB_CANCELLED',
'data': { 'type' : 'BlockJobType',
@@ -2407,6 +2445,15 @@
# @action: action that has been taken
#
# Since: 1.3
+#
+# Example:
+#
+# <- { "event": "BLOCK_JOB_ERROR",
+# "data": { "device": "ide0-hd1",
+# "operation": "write",
+# "action": "stop" },
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
##
{ 'event': 'BLOCK_JOB_ERROR',
'data': { 'device' : 'str',
@@ -2433,6 +2480,14 @@
# event
#
# Since: 1.3
+#
+# Example:
+#
+# <- { "event": "BLOCK_JOB_READY",
+# "data": { "device": "drive0", "type": "mirror", "speed": 0,
+# "len": 2097152, "offset": 2097152 }
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
##
{ 'event': 'BLOCK_JOB_READY',
'data': { 'type' : 'BlockJobType',
diff --git a/qapi/block.json b/qapi/block.json
index 487abb2..3df72e9 100644
--- a/qapi/block.json
+++ b/qapi/block.json
@@ -208,6 +208,15 @@
# @tray-open: true if the tray has been opened or false if it has been closed
#
# Since: 1.1
+#
+# Example:
+#
+# <- { "event": "DEVICE_TRAY_MOVED",
+# "data": { "device": "ide1-cd0",
+# "tray-open": true
+# },
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
##
{ 'event': 'DEVICE_TRAY_MOVED',
'data': { 'device': 'str', 'tray-open': 'bool' } }
diff --git a/qapi/event.json b/qapi/event.json
index ce5853d..6144153 100644
--- a/qapi/event.json
+++ b/qapi/event.json
@@ -13,6 +13,12 @@
# not exit, and a STOP event will eventually follow the SHUTDOWN event
#
# Since: 0.12.0
+#
+# Example:
+#
+# <- { "event": "SHUTDOWN",
+# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
+#
##
{ 'event': 'SHUTDOWN' }
@@ -23,6 +29,12 @@
# system, such as via ACPI.
#
# Since: 0.12.0
+#
+# Example:
+#
+# <- { "event": "POWERDOWN",
+# "timestamp": { "seconds": 1267040730, "microseconds": 682951 } }
+#
##
{ 'event': 'POWERDOWN' }
@@ -32,6 +44,12 @@
# Emitted when the virtual machine is reset
#
# Since: 0.12.0
+#
+# Example:
+#
+# <- { "event": "RESET",
+# "timestamp": { "seconds": 1267041653, "microseconds": 9518 } }
+#
##
{ 'event': 'RESET' }
@@ -41,6 +59,12 @@
# Emitted when the virtual machine is stopped
#
# Since: 0.12.0
+#
+# Example:
+#
+# <- { "event": "STOP",
+# "timestamp": { "seconds": 1267041730, "microseconds": 281295 } }
+#
##
{ 'event': 'STOP' }
@@ -50,6 +74,12 @@
# Emitted when the virtual machine resumes execution
#
# Since: 0.12.0
+#
+# Example:
+#
+# <- { "event": "RESUME",
+# "timestamp": { "seconds": 1271770767, "microseconds": 582542 } }
+#
##
{ 'event': 'RESUME' }
@@ -60,6 +90,12 @@
# which is sometimes called standby state
#
# Since: 1.1
+#
+# Example:
+#
+# <- { "event": "SUSPEND",
+# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
+#
##
{ 'event': 'SUSPEND' }
@@ -72,6 +108,12 @@
# Note: QEMU shuts down (similar to event @SHUTDOWN) when entering this state
#
# Since: 1.2
+#
+# Example:
+#
+# <- { "event": "SUSPEND_DISK",
+# "timestamp": { "seconds": 1344456160, "microseconds": 309119 } }
+#
##
{ 'event': 'SUSPEND_DISK' }
@@ -81,6 +123,12 @@
# Emitted when the guest has woken up from suspend state and is running
#
# Since: 1.1
+#
+# Example:
+#
+# <- { "event": "WAKEUP",
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
##
{ 'event': 'WAKEUP' }
@@ -93,6 +141,13 @@
# new RTC clock value
#
# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "RTC_CHANGE",
+# "data": { "offset": 78 },
+# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
+#
##
{ 'event': 'RTC_CHANGE',
'data': { 'offset': 'int' } }
@@ -108,6 +163,13 @@
# followed respectively by the RESET, SHUTDOWN, or STOP events
#
# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "WATCHDOG",
+# "data": { "action": "reset" },
+# "timestamp": { "seconds": 1267061043, "microseconds": 959568 } }
+#
##
{ 'event': 'WATCHDOG',
'data': { 'action': 'WatchdogExpirationAction' } }
@@ -124,6 +186,14 @@
# @path: device path
#
# Since: 1.5
+#
+# Example:
+#
+# <- { "event": "DEVICE_DELETED",
+# "data": { "device": "virtio-net-pci-0",
+# "path": "/machine/peripheral/virtio-net-pci-0" },
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
##
{ 'event': 'DEVICE_DELETED',
'data': { '*device': 'str', 'path': 'str' } }
@@ -139,6 +209,15 @@
# @path: device path
#
# Since: 1.6
+#
+# Example:
+#
+# <- { "event": "NIC_RX_FILTER_CHANGED",
+# "data": { "name": "vnet0",
+# "path": "/machine/peripheral/vnet0/virtio-backend" },
+# "timestamp": { "seconds": 1368697518, "microseconds": 326866 } }
+# }
+#
##
{ 'event': 'NIC_RX_FILTER_CHANGED',
'data': { '*name': 'str', 'path': 'str' } }
@@ -156,6 +235,17 @@
# the authentication ID is not provided
#
# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "VNC_CONNECTED",
+# "data": {
+# "server": { "auth": "sasl", "family": "ipv4",
+# "service": "5901", "host": "0.0.0.0" },
+# "client": { "family": "ipv4", "service": "58425",
+# "host": "127.0.0.1" } },
+# "timestamp": { "seconds": 1262976601, "microseconds": 975795 } }
+#
##
{ 'event': 'VNC_CONNECTED',
'data': { 'server': 'VncServerInfo',
@@ -172,6 +262,17 @@
# @client: client information
#
# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "VNC_INITIALIZED",
+# "data": {
+# "server": { "auth": "sasl", "family": "ipv4",
+# "service": "5901", "host": "0.0.0.0"},
+# "client": { "family": "ipv4", "service": "46089",
+# "host": "127.0.0.1", "sasl_username": "luiz" } },
+# "timestamp": { "seconds": 1263475302, "microseconds": 150772 } }
+#
##
{ 'event': 'VNC_INITIALIZED',
'data': { 'server': 'VncServerInfo',
@@ -187,6 +288,17 @@
# @client: client information
#
# Since: 0.13.0
+#
+# Example:
+#
+# <- { "event": "VNC_DISCONNECTED",
+# "data": {
+# "server": { "auth": "sasl", "family": "ipv4",
+# "service": "5901", "host": "0.0.0.0" },
+# "client": { "family": "ipv4", "service": "58425",
+# "host": "127.0.0.1", "sasl_username": "luiz" } },
+# "timestamp": { "seconds": 1262976601, "microseconds": 975795 } }
+#
##
{ 'event': 'VNC_DISCONNECTED',
'data': { 'server': 'VncServerInfo',
@@ -202,6 +314,16 @@
# @client: client information
#
# Since: 0.14.0
+#
+# Example:
+#
+# <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707},
+# "event": "SPICE_CONNECTED",
+# "data": {
+# "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
+# "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
+# }}
+#
##
{ 'event': 'SPICE_CONNECTED',
'data': { 'server': 'SpiceBasicInfo',
@@ -218,6 +340,18 @@
# @client: client information
#
# Since: 0.14.0
+#
+# Example:
+#
+# <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172},
+# "event": "SPICE_INITIALIZED",
+# "data": {"server": {"auth": "spice", "port": "5921",
+# "family": "ipv4", "host": "127.0.0.1"},
+# "client": {"port": "49004", "family": "ipv4", "channel-type": 3,
+# "connection-id": 1804289383, "host": "127.0.0.1",
+# "channel-id": 0, "tls": true}
+# }}
+#
##
{ 'event': 'SPICE_INITIALIZED',
'data': { 'server': 'SpiceServerInfo',
@@ -233,6 +367,16 @@
# @client: client information
#
# Since: 0.14.0
+#
+# Example:
+#
+# <- { "timestamp": {"seconds": 1290688046, "microseconds": 388707},
+# "event": "SPICE_DISCONNECTED",
+# "data": {
+# "server": { "port": "5920", "family": "ipv4", "host": "127.0.0.1"},
+# "client": {"port": "52873", "family": "ipv4", "host": "127.0.0.1"}
+# }}
+#
##
{ 'event': 'SPICE_DISCONNECTED',
'data': { 'server': 'SpiceBasicInfo',
@@ -244,6 +388,12 @@
# Emitted when SPICE migration has completed
#
# Since: 1.3
+#
+# Example:
+#
+# <- { "timestamp": {"seconds": 1290688046, "microseconds": 417172},
+# "event": "SPICE_MIGRATE_COMPLETED" }
+#
##
{ 'event': 'SPICE_MIGRATE_COMPLETED' }
@@ -255,6 +405,13 @@
# @status: @MigrationStatus describing the current migration status.
#
# Since: 2.4
+#
+# Example:
+#
+# <- {"timestamp": {"seconds": 1432121972, "microseconds": 744001},
+# "event": "MIGRATION",
+# "data": {"status": "completed"} }
+#
##
{ 'event': 'MIGRATION',
'data': {'status': 'MigrationStatus'}}
@@ -267,6 +424,12 @@
# Since: 2.1
#
# @info: ACPIOSTInfo type as described in qapi-schema.json
+#
+# Example:
+#
+# <- { "event": "ACPI_DEVICE_OST",
+# "data": { "device": "d1", "slot": "0", "slot-type": "DIMM", "source": 1, "status": 0 } }
+#
##
{ 'event': 'ACPI_DEVICE_OST',
'data': { 'info': 'ACPIOSTInfo' } }
@@ -280,6 +443,13 @@
# @actual: actual level of the guest memory balloon in bytes
#
# Since: 1.2
+#
+# Example:
+#
+# <- { "event": "BALLOON_CHANGE",
+# "data": { "actual": 944766976 },
+# "timestamp": { "seconds": 1267020223, "microseconds": 435656 } }
+#
##
{ 'event': 'BALLOON_CHANGE',
'data': { 'actual': 'int' } }
@@ -292,6 +462,12 @@
# @action: action that has been taken, currently always "pause"
#
# Since: 1.5
+#
+# Example:
+#
+# <- { "event": "GUEST_PANICKED",
+# "data": { "action": "pause" } }
+#
##
{ 'event': 'GUEST_PANICKED',
'data': { 'action': 'GuestPanicAction' } }
@@ -308,6 +484,13 @@
# @sectors-count: failed read operation sector count
#
# Since: 2.0
+#
+# Example:
+#
+# <- { "event": "QUORUM_FAILURE",
+# "data": { "reference": "usr1", "sector-num": 345435, "sectors-count": 5 },
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
##
{ 'event': 'QUORUM_FAILURE',
'data': { 'reference': 'str', 'sector-num': 'int', 'sectors-count': 'int' } }
@@ -329,6 +512,13 @@
# @sectors-count: failed read operation sector count
#
# Since: 2.0
+#
+# Example:
+#
+# <- { "event": "QUORUM_REPORT_BAD",
+# "data": { "node-name": "1.raw", "sector-num": 345435, "sectors-count": 5 },
+# "timestamp": { "seconds": 1344522075, "microseconds": 745528 } }
+#
##
{ 'event': 'QUORUM_REPORT_BAD',
'data': { '*error': 'str', 'node-name': 'str',
@@ -344,6 +534,13 @@
# @open: true if the guest has opened the virtio-serial port
#
# Since: 2.1
+#
+# Example:
+#
+# <- { "event": "VSERPORT_CHANGE",
+# "data": { "id": "channel0", "open": true },
+# "timestamp": { "seconds": 1401385907, "microseconds": 422329 } }
+#
##
{ 'event': 'VSERPORT_CHANGE',
'data': { 'id': 'str', 'open': 'bool' } }
@@ -358,6 +555,15 @@
# @msg: Informative message
#
# Since: 2.4
+#
+# Example:
+#
+# <- { "event": "MEM_UNPLUG_ERROR"
+# "data": { "device": "dimm1",
+# "msg": "acpi: device unplug for unsupported device"
+# },
+# "timestamp": { "seconds": 1265044230, "microseconds": 450486 } }
+#
##
{ 'event': 'MEM_UNPLUG_ERROR',
'data': { 'device': 'str', 'msg': 'str' } }
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 10/36] texi2pod: learn quotation, deftp and deftypefn
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (8 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 09/36] qapi: remove qmp-events.txt marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:44 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 11/36] build-sys: generate QAPI doc based on json marcandre.lureau
` (27 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Learn a few more markups used for API documentation.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/texi2pod.pl | 44 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 43 insertions(+), 1 deletion(-)
diff --git a/scripts/texi2pod.pl b/scripts/texi2pod.pl
index 94097fb..3590a2d 100755
--- a/scripts/texi2pod.pl
+++ b/scripts/texi2pod.pl
@@ -37,6 +37,7 @@ $inf = "";
$ibase = "";
@ipath = ();
$encoding = undef;
+@args = ();
while ($_ = shift) {
if (/^-D(.*)$/) {
@@ -162,7 +163,8 @@ while(<$inf>) {
if ($ended =~ /^(?:ifset|ifclear|ignore|menu|iftex)$/) {
$skipping = pop @skstack;
next;
- } elsif ($ended =~ /^(?:example|smallexample|display)$/) {
+ } elsif ($ended =~ /^(?:example|smallexample|display
+ |quotation|deftp|deftypefn)$/x) {
$shift = "";
$_ = ""; # need a paragraph break
} elsif ($ended =~ /^(?:itemize|enumerate|[fv]?table)$/) {
@@ -323,6 +325,46 @@ while(<$inf>) {
$_ = "\n=item ".join (" : ", @columns)."\n";
};
+ /^\@(quotation)\s*(.+)?$/ and do {
+ push @endwstack, $endw;
+ $endw = $1;
+ $_ = "\n$2:"
+ };
+
+ /^{(.*)}$|^(.*)$/ and $#args > 0 and do {
+ $kind = $args[0];
+ $arguments = $1 // "";
+ if ($endw eq "deftypefn") {
+ $ret = $args[1];
+ $fname = "B<$args[2]>";
+ $_ = $ret ? "$ret " : "";
+ $_ .= "$fname $arguments ($kind)";
+ } else {
+ $_ = "B<$args[1]> ($kind)\n\n$arguments";
+ }
+ @args = ();
+ };
+
+ /^\@(deftp)\s*(.+)?$/ and do {
+ push @endwstack, $endw;
+ $endw = $1;
+ $arg = $2;
+ $arg =~ s/{([^}]*)}/$1/g;
+ $arg =~ s/\@$//;
+ @args = split (/ /, $arg);
+ $_ = "";
+ };
+
+ /^\@(deftypefn)\s*(.+)?$/ and do {
+ push @endwstack, $endw;
+ $endw = $1;
+ $arg = $2;
+ $arg =~ s/{([^}]*)}/$1/g;
+ $arg =~ s/\@$//;
+ @args = split (/ /, $arg);
+ $_ = "";
+ };
+
/^\@itemx?\s*(.+)?$/ and do {
if (defined $1) {
# Entity escapes prevent munging by the <> processing below.
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 11/36] build-sys: generate QAPI doc based on json
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (9 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 10/36] texi2pod: learn quotation, deftp and deftypefn marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:49 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 12/36] build-sys: generate qmp-commands.txt marcandre.lureau
` (26 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Learn to generate info/html/pdf/man documentation for QEMU and agent QMP
APIs.
This allows to provide missing agent documentation, and should help
getting rid of the duplicate documentation in qmp-commands.hx.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Makefile | 36 ++++++++++++++++++++++++++++++------
1 file changed, 30 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
index 68e2e1b..918ad4e 100644
--- a/Makefile
+++ b/Makefile
@@ -91,7 +91,7 @@ HELPERS-$(CONFIG_LINUX) = qemu-bridge-helper$(EXESUF)
ifdef BUILD_DOCS
DOCS=qemu-doc.html qemu-tech.html qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
-DOCS+=qmp-commands.txt
+DOCS+=qmp-commands.txt qemu-qapi.7 qemu-ga-qapi.7
ifdef CONFIG_LINUX
DOCS+=kvm_stat.1
endif
@@ -249,6 +249,7 @@ qemu-ga$(EXESUF): QEMU_CFLAGS += -I qga/qapi-generated
gen-out-type = $(subst .,-,$(suffix $@))
qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
+qapi-py += $(SRC_PATH)/scripts/qapi2texi.py
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
@@ -363,7 +364,7 @@ distclean: clean
rm -f qemu-doc.vr
rm -f config.log
rm -f linux-headers/asm
- rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
+ rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech..ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr qemu-qapi.info qemu-qapi.aux qemu-qapi.cp qemu-qapi.dvi qemu-qapi.fn qemu-qapi.info qemu-qapi..ky qemu-qapi.log qemu-qapi.pdf qemu-qapi.pg qemu-qapi.toc qemu-qapi.tp qemu-qapi.vr qemu-ga-qapi.info qemu-ga-qapi.aux qemu-ga-qapi.cp qemu-ga-qapi.dvi qemu-ga-qapi.fn qemu-ga-qapi.info qemu-ga-qapi..ky qemu-ga-qapi.log qemu-ga-qapi.pdf qemu-ga-qapi.pg qemu-ga-qapi.toc qemu-ga-qapi.tp qemu-ga-qapi.vr
for d in $(TARGET_DIRS); do \
rm -rf $$d || exit 1 ; \
done
@@ -408,6 +409,7 @@ ifneq ($(TOOLS),)
$(INSTALL_DATA) qemu-img.1 "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man8"
$(INSTALL_DATA) qemu-nbd.8 "$(DESTDIR)$(mandir)/man8"
+ $(INSTALL_DATA) qemu-qapi.7 qemu-ga-qapi.7 "$(DESTDIR)$(mandir)/man7"
endif
ifneq (,$(findstring qemu-ga,$(TOOLS)))
$(INSTALL_DATA) qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
@@ -529,6 +531,16 @@ qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx
qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
+qemu-qapi.texi: $(qapi-modules) $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi2texi.py \
+ "QEMU QAPI Reference Manual" $(VERSION) qemu-qapi \
+ $< > $@," GEN $@")
+
+qemu-ga-qapi.texi: $(SRC_PATH)/qga/qapi-schema.json $(qapi-py)
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi2texi.py \
+ "QEMU Guest Agent QAPI Reference Manual" $(VERSION) qemu-ga-qapi \
+ $< > $@," GEN $@")
+
qemu.1: qemu-doc.texi qemu-options.texi qemu-monitor.texi qemu-monitor-info.texi
$(call quiet-command, \
perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu.pod && \
@@ -559,16 +571,28 @@ qemu-ga.8: qemu-ga.texi
$(POD2MAN) --section=8 --center=" " --release=" " qemu-ga.pod > $@, \
" GEN $@")
+qemu-qapi.7: qemu-qapi.texi
+ $(call quiet-command, \
+ perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu-qapi.pod && \
+ $(POD2MAN) --section=7 --center=" " --release=" " qemu-qapi.pod > $@, \
+ " GEN $@")
+
+qemu-ga-qapi.7: qemu-ga-qapi.texi
+ $(call quiet-command, \
+ perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< qemu-ga-qapi.pod && \
+ $(POD2MAN) --section=7 --center=" " --release=" " qemu-ga-qapi.pod > $@, \
+ " GEN $@")
+
kvm_stat.1: scripts/kvm/kvm_stat.texi
$(call quiet-command, \
perl -Ww -- $(SRC_PATH)/scripts/texi2pod.pl $< kvm_stat.pod && \
$(POD2MAN) --section=1 --center=" " --release=" " kvm_stat.pod > $@, \
" GEN $@")
-dvi: qemu-doc.dvi qemu-tech.dvi
-html: qemu-doc.html qemu-tech.html
-info: qemu-doc.info qemu-tech.info
-pdf: qemu-doc.pdf qemu-tech.pdf
+dvi: qemu-doc.dvi qemu-tech.dvi qemu-qapi.dvi
+html: qemu-doc.html qemu-tech.html qemu-qapi.html
+info: qemu-doc.info qemu-tech.info qemu-qapi.info
+pdf: qemu-doc.pdf qemu-tech.pdf qemu-qapi.pdf
qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \
qemu-img.texi qemu-nbd.texi qemu-options.texi \
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 12/36] build-sys: generate qmp-commands.txt
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (10 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 11/36] build-sys: generate QAPI doc based on json marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 13/36] build-sys: do not generate qmp-commands-old.h marcandre.lureau
` (25 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Not sure this is really necessary, but it's easy to provide
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Makefile | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 918ad4e..5e09e88 100644
--- a/Makefile
+++ b/Makefile
@@ -525,8 +525,9 @@ qemu-monitor.texi: $(SRC_PATH)/hmp-commands.hx
qemu-monitor-info.texi: $(SRC_PATH)/hmp-commands-info.hx
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
-qmp-commands.txt: $(SRC_PATH)/qmp-commands.hx
- $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -q < $< > $@," GEN $@")
+qmp-commands.txt: qemu-qapi.texi
+ $(call quiet-command,LC_ALL=C $(MAKEINFO) $(MAKEINFOFLAGS) --plaintext $< -o $@, \
+ " GEN $@")
qemu-img-cmds.texi: $(SRC_PATH)/qemu-img-cmds.hx
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@," GEN $@")
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 13/36] build-sys: do not generate qmp-commands-old.h
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (11 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 12/36] build-sys: generate qmp-commands.txt marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 14/36] monitor: remove usage of generated marshal functions marcandre.lureau
` (24 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
It's static file now.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Makefile.target | 7 +-
qmp-commands-old.h | 683 +++++++++++++++++++++++++++++++++++++++++++++++++++++
qmp-commands.hx | 683 -----------------------------------------------------
3 files changed, 685 insertions(+), 688 deletions(-)
create mode 100644 qmp-commands-old.h
delete mode 100644 qmp-commands.hx
diff --git a/Makefile.target b/Makefile.target
index 962d004..a1cd219 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -154,7 +154,7 @@ else
obj-y += hw/$(TARGET_BASE_ARCH)/
endif
-GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h qmp-commands-old.h
+GENERATED_HEADERS += hmp-commands.h hmp-commands-info.h
endif # CONFIG_SOFTMMU
@@ -205,13 +205,10 @@ hmp-commands.h: $(SRC_PATH)/hmp-commands.hx
hmp-commands-info.h: $(SRC_PATH)/hmp-commands-info.hx
$(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
-qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx
- $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > $@," GEN $(TARGET_DIR)$@")
-
clean:
rm -f *.a *~ $(PROGS)
rm -f $(shell find . -name '*.[od]')
- rm -f hmp-commands.h qmp-commands-old.h gdbstub-xml.c
+ rm -f hmp-commands.h gdbstub-xml.c
ifdef CONFIG_TRACE_SYSTEMTAP
rm -f *.stp
endif
diff --git a/qmp-commands-old.h b/qmp-commands-old.h
new file mode 100644
index 0000000..3a7af18
--- /dev/null
+++ b/qmp-commands-old.h
@@ -0,0 +1,683 @@
+ {
+ .name = "quit",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_quit,
+ },
+ {
+ .name = "eject",
+ .args_type = "force:-f,device:B",
+ .mhandler.cmd_new = qmp_marshal_eject,
+ },
+ {
+ .name = "change",
+ .args_type = "device:B,target:F,arg:s?",
+ .mhandler.cmd_new = qmp_marshal_change,
+ },
+ {
+ .name = "screendump",
+ .args_type = "filename:F",
+ .mhandler.cmd_new = qmp_marshal_screendump,
+ },
+ {
+ .name = "stop",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_stop,
+ },
+ {
+ .name = "cont",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_cont,
+ },
+ {
+ .name = "system_wakeup",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_system_wakeup,
+ },
+ {
+ .name = "system_reset",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_system_reset,
+ },
+ {
+ .name = "system_powerdown",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_system_powerdown,
+ },
+ {
+ .name = "device_add",
+ .args_type = "device:O",
+ .params = "driver[,prop=value][,...]",
+ .help = "add device, like -device on the command line",
+ .mhandler.cmd_new = qmp_device_add,
+ },
+ {
+ .name = "device_del",
+ .args_type = "id:s",
+ .mhandler.cmd_new = qmp_marshal_device_del,
+ },
+ {
+ .name = "send-key",
+ .args_type = "keys:q,hold-time:i?",
+ .mhandler.cmd_new = qmp_marshal_send_key,
+ },
+ {
+ .name = "cpu",
+ .args_type = "index:i",
+ .mhandler.cmd_new = qmp_marshal_cpu,
+ },
+ {
+ .name = "cpu-add",
+ .args_type = "id:i",
+ .mhandler.cmd_new = qmp_marshal_cpu_add,
+ },
+ {
+ .name = "memsave",
+ .args_type = "val:l,size:i,filename:s,cpu:i?",
+ .mhandler.cmd_new = qmp_marshal_memsave,
+ },
+ {
+ .name = "pmemsave",
+ .args_type = "val:l,size:i,filename:s",
+ .mhandler.cmd_new = qmp_marshal_pmemsave,
+ },
+ {
+ .name = "inject-nmi",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_inject_nmi,
+ },
+ {
+ .name = "ringbuf-write",
+ .args_type = "device:s,data:s,format:s?",
+ .mhandler.cmd_new = qmp_marshal_ringbuf_write,
+ },
+ {
+ .name = "ringbuf-read",
+ .args_type = "device:s,size:i,format:s?",
+ .mhandler.cmd_new = qmp_marshal_ringbuf_read,
+ },
+ {
+ .name = "xen-save-devices-state",
+ .args_type = "filename:F",
+ .mhandler.cmd_new = qmp_marshal_xen_save_devices_state,
+ },
+ {
+ .name = "xen-set-global-dirty-log",
+ .args_type = "enable:b",
+ .mhandler.cmd_new = qmp_marshal_xen_set_global_dirty_log,
+ },
+ {
+ .name = "migrate",
+ .args_type = "detach:-d,blk:-b,inc:-i,uri:s",
+ .mhandler.cmd_new = qmp_marshal_migrate,
+ },
+ {
+ .name = "migrate_cancel",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_migrate_cancel,
+ },
+ {
+ .name = "migrate-incoming",
+ .args_type = "uri:s",
+ .mhandler.cmd_new = qmp_marshal_migrate_incoming,
+ },
+ {
+ .name = "migrate-set-cache-size",
+ .args_type = "value:o",
+ .mhandler.cmd_new = qmp_marshal_migrate_set_cache_size,
+ },
+ {
+ .name = "query-migrate-cache-size",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_migrate_cache_size,
+ },
+ {
+ .name = "migrate_set_speed",
+ .args_type = "value:o",
+ .mhandler.cmd_new = qmp_marshal_migrate_set_speed,
+ },
+ {
+ .name = "migrate_set_downtime",
+ .args_type = "value:T",
+ .mhandler.cmd_new = qmp_marshal_migrate_set_downtime,
+ },
+ {
+ .name = "client_migrate_info",
+ .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
+ .params = "protocol hostname port tls-port cert-subject",
+ .help = "set migration information for remote display",
+ .mhandler.cmd_new = qmp_marshal_client_migrate_info,
+ },
+ {
+ .name = "dump-guest-memory",
+ .args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
+ .params = "-p protocol [begin] [length] [format]",
+ .help = "dump guest memory to file",
+ .mhandler.cmd_new = qmp_marshal_dump_guest_memory,
+ },
+ {
+ .name = "query-dump-guest-memory-capability",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_dump_guest_memory_capability,
+ },
+#if defined TARGET_S390X
+ {
+ .name = "dump-skeys",
+ .args_type = "filename:F",
+ .mhandler.cmd_new = qmp_marshal_dump_skeys,
+ },
+#endif
+ {
+ .name = "netdev_add",
+ .args_type = "netdev:O",
+ .mhandler.cmd_new = qmp_marshal_netdev_add,
+ },
+ {
+ .name = "netdev_del",
+ .args_type = "id:s",
+ .mhandler.cmd_new = qmp_marshal_netdev_del,
+ },
+ {
+ .name = "object-add",
+ .args_type = "qom-type:s,id:s,props:q?",
+ .mhandler.cmd_new = qmp_marshal_object_add,
+ },
+ {
+ .name = "object-del",
+ .args_type = "id:s",
+ .mhandler.cmd_new = qmp_marshal_object_del,
+ },
+ {
+ .name = "block_resize",
+ .args_type = "device:s?,node-name:s?,size:o",
+ .mhandler.cmd_new = qmp_marshal_block_resize,
+ },
+ {
+ .name = "block-stream",
+ .args_type = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
+ .mhandler.cmd_new = qmp_marshal_block_stream,
+ },
+ {
+ .name = "block-commit",
+ .args_type = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
+ .mhandler.cmd_new = qmp_marshal_block_commit,
+ },
+ {
+ .name = "drive-backup",
+ .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
+ "bitmap:s?,on-source-error:s?,on-target-error:s?",
+ .mhandler.cmd_new = qmp_marshal_drive_backup,
+ },
+ {
+ .name = "blockdev-backup",
+ .args_type = "sync:s,device:B,target:B,speed:i?,"
+ "on-source-error:s?,on-target-error:s?",
+ .mhandler.cmd_new = qmp_marshal_blockdev_backup,
+ },
+ {
+ .name = "block-job-set-speed",
+ .args_type = "device:B,speed:o",
+ .mhandler.cmd_new = qmp_marshal_block_job_set_speed,
+ },
+
+ {
+ .name = "block-job-cancel",
+ .args_type = "device:B,force:b?",
+ .mhandler.cmd_new = qmp_marshal_block_job_cancel,
+ },
+ {
+ .name = "block-job-pause",
+ .args_type = "device:B",
+ .mhandler.cmd_new = qmp_marshal_block_job_pause,
+ },
+ {
+ .name = "block-job-resume",
+ .args_type = "device:B",
+ .mhandler.cmd_new = qmp_marshal_block_job_resume,
+ },
+ {
+ .name = "block-job-complete",
+ .args_type = "device:B",
+ .mhandler.cmd_new = qmp_marshal_block_job_complete,
+ },
+ {
+ .name = "transaction",
+ .args_type = "actions:q",
+ .mhandler.cmd_new = qmp_marshal_transaction,
+ },
+ {
+ .name = "block-dirty-bitmap-add",
+ .args_type = "node:B,name:s,granularity:i?",
+ .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_add,
+ },
+ {
+ .name = "block-dirty-bitmap-remove",
+ .args_type = "node:B,name:s",
+ .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_remove,
+ },
+ {
+ .name = "block-dirty-bitmap-clear",
+ .args_type = "node:B,name:s",
+ .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_clear,
+ },
+ {
+ .name = "blockdev-snapshot-sync",
+ .args_type = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
+ .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_sync,
+ },
+ {
+ .name = "blockdev-snapshot-internal-sync",
+ .args_type = "device:B,name:s",
+ .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_internal_sync,
+ },
+ {
+ .name = "blockdev-snapshot-delete-internal-sync",
+ .args_type = "device:B,id:s?,name:s?",
+ .mhandler.cmd_new =
+ qmp_marshal_blockdev_snapshot_delete_internal_sync,
+ },
+ {
+ .name = "drive-mirror",
+ .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
+ "node-name:s?,replaces:s?,"
+ "on-source-error:s?,on-target-error:s?,"
+ "unmap:b?,"
+ "granularity:i?,buf-size:i?",
+ .mhandler.cmd_new = qmp_marshal_drive_mirror,
+ },
+ {
+ .name = "change-backing-file",
+ .args_type = "device:s,image-node-name:s,backing-file:s",
+ .mhandler.cmd_new = qmp_marshal_change_backing_file,
+ },
+ {
+ .name = "balloon",
+ .args_type = "value:M",
+ .mhandler.cmd_new = qmp_marshal_balloon,
+ },
+ {
+ .name = "set_link",
+ .args_type = "name:s,up:b",
+ .mhandler.cmd_new = qmp_marshal_set_link,
+ },
+ {
+ .name = "getfd",
+ .args_type = "fdname:s",
+ .params = "getfd name",
+ .help = "receive a file descriptor via SCM rights and assign it a name",
+ .mhandler.cmd_new = qmp_marshal_getfd,
+ },
+ {
+ .name = "closefd",
+ .args_type = "fdname:s",
+ .params = "closefd name",
+ .help = "close a file descriptor previously passed via SCM rights",
+ .mhandler.cmd_new = qmp_marshal_closefd,
+ },
+ {
+ .name = "add-fd",
+ .args_type = "fdset-id:i?,opaque:s?",
+ .params = "add-fd fdset-id opaque",
+ .help = "Add a file descriptor, that was passed via SCM rights, to an fd set",
+ .mhandler.cmd_new = qmp_marshal_add_fd,
+ },
+ {
+ .name = "remove-fd",
+ .args_type = "fdset-id:i,fd:i?",
+ .params = "remove-fd fdset-id fd",
+ .help = "Remove a file descriptor from an fd set",
+ .mhandler.cmd_new = qmp_marshal_remove_fd,
+ },
+ {
+ .name = "query-fdsets",
+ .args_type = "",
+ .help = "Return information describing all fd sets",
+ .mhandler.cmd_new = qmp_marshal_query_fdsets,
+ },
+ {
+ .name = "block_passwd",
+ .args_type = "device:s?,node-name:s?,password:s",
+ .mhandler.cmd_new = qmp_marshal_block_passwd,
+ },
+ {
+ .name = "block_set_io_throttle",
+ .args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l,bps_max:l?,bps_rd_max:l?,bps_wr_max:l?,iops_max:l?,iops_rd_max:l?,iops_wr_max:l?,iops_size:l?,group:s?",
+ .mhandler.cmd_new = qmp_marshal_block_set_io_throttle,
+ },
+ {
+ .name = "set_password",
+ .args_type = "protocol:s,password:s,connected:s?",
+ .mhandler.cmd_new = qmp_marshal_set_password,
+ },
+ {
+ .name = "expire_password",
+ .args_type = "protocol:s,time:s",
+ .mhandler.cmd_new = qmp_marshal_expire_password,
+ },
+ {
+ .name = "add_client",
+ .args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
+ .mhandler.cmd_new = qmp_marshal_add_client,
+ },
+ {
+ .name = "qmp_capabilities",
+ .args_type = "",
+ .help = "enable QMP capabilities",
+ .mhandler.cmd_new = qmp_marshal_qmp_capabilities,
+ },
+ {
+ .name = "human-monitor-command",
+ .args_type = "command-line:s,cpu-index:i?",
+ .mhandler.cmd_new = qmp_marshal_human_monitor_command,
+ },
+ {
+ .name = "query-version",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_version,
+ },
+ {
+ .name = "query-commands",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_commands,
+ },
+ {
+ .name = "query-events",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_events,
+ },
+ {
+ .name = "query-qmp-schema",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_query_qmp_schema,
+ },
+ {
+ .name = "query-chardev",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_chardev,
+ },
+ {
+ .name = "query-chardev-backends",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_chardev_backends,
+ },
+ {
+ .name = "query-block",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_block,
+ },
+ {
+ .name = "query-blockstats",
+ .args_type = "query-nodes:b?",
+ .mhandler.cmd_new = qmp_marshal_query_blockstats,
+ },
+ {
+ .name = "query-cpus",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_cpus,
+ },
+ {
+ .name = "query-iothreads",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_iothreads,
+ },
+ {
+ .name = "query-pci",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_pci,
+ },
+ {
+ .name = "query-kvm",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_kvm,
+ },
+ {
+ .name = "query-status",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_status,
+ },
+ {
+ .name = "query-mice",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_mice,
+ },
+ {
+ .name = "query-vnc",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_vnc,
+ },
+ {
+ .name = "query-vnc-servers",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_vnc_servers,
+ },
+#if defined(CONFIG_SPICE)
+ {
+ .name = "query-spice",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_spice,
+ },
+#endif
+ {
+ .name = "query-name",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_name,
+ },
+ {
+ .name = "query-uuid",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_uuid,
+ },
+ {
+ .name = "query-command-line-options",
+ .args_type = "option:s?",
+ .mhandler.cmd_new = qmp_marshal_query_command_line_options,
+ },
+ {
+ .name = "query-migrate",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_migrate,
+ },
+ {
+ .name = "migrate-set-capabilities",
+ .args_type = "capabilities:q",
+ .params = "capability:s,state:b",
+ .mhandler.cmd_new = qmp_marshal_migrate_set_capabilities,
+ },
+ {
+ .name = "query-migrate-capabilities",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_migrate_capabilities,
+ },
+ {
+ .name = "migrate-set-parameters",
+ .args_type =
+ "compress-level:i?,compress-threads:i?,decompress-threads:i?",
+ .mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
+ },
+ {
+ .name = "query-migrate-parameters",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_migrate_parameters,
+ },
+ {
+ .name = "query-balloon",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_balloon,
+ },
+
+ {
+ .name = "query-block-jobs",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_block_jobs,
+ },
+
+ {
+ .name = "qom-list",
+ .args_type = "path:s",
+ .mhandler.cmd_new = qmp_marshal_qom_list,
+ },
+
+ {
+ .name = "qom-set",
+ .args_type = "path:s,property:s,value:q",
+ .mhandler.cmd_new = qmp_marshal_qom_set,
+ },
+
+ {
+ .name = "qom-get",
+ .args_type = "path:s,property:s",
+ .mhandler.cmd_new = qmp_marshal_qom_get,
+ },
+
+ {
+ .name = "nbd-server-start",
+ .args_type = "addr:q",
+ .mhandler.cmd_new = qmp_marshal_nbd_server_start,
+ },
+ {
+ .name = "nbd-server-add",
+ .args_type = "device:B,writable:b?",
+ .mhandler.cmd_new = qmp_marshal_nbd_server_add,
+ },
+ {
+ .name = "nbd-server-stop",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_nbd_server_stop,
+ },
+
+ {
+ .name = "change-vnc-password",
+ .args_type = "password:s",
+ .mhandler.cmd_new = qmp_marshal_change_vnc_password,
+ },
+ {
+ .name = "qom-list-types",
+ .args_type = "implements:s?,abstract:b?",
+ .mhandler.cmd_new = qmp_marshal_qom_list_types,
+ },
+
+ {
+ .name = "device-list-properties",
+ .args_type = "typename:s",
+ .mhandler.cmd_new = qmp_marshal_device_list_properties,
+ },
+
+ {
+ .name = "query-machines",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_machines,
+ },
+
+ {
+ .name = "query-cpu-definitions",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_cpu_definitions,
+ },
+
+ {
+ .name = "query-target",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_target,
+ },
+
+ {
+ .name = "query-tpm",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_tpm,
+ },
+ {
+ .name = "query-tpm-models",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_tpm_models,
+ },
+ {
+ .name = "query-tpm-types",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_tpm_types,
+ },
+ {
+ .name = "chardev-add",
+ .args_type = "id:s,backend:q",
+ .mhandler.cmd_new = qmp_marshal_chardev_add,
+ },
+ {
+ .name = "chardev-remove",
+ .args_type = "id:s",
+ .mhandler.cmd_new = qmp_marshal_chardev_remove,
+ },
+ {
+ .name = "query-rx-filter",
+ .args_type = "name:s?",
+ .mhandler.cmd_new = qmp_marshal_query_rx_filter,
+ },
+ {
+ .name = "blockdev-add",
+ .args_type = "options:q",
+ .mhandler.cmd_new = qmp_marshal_blockdev_add,
+ },
+ {
+ .name = "query-named-block-nodes",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_named_block_nodes,
+ },
+ {
+ .name = "query-memdev",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_memdev,
+ },
+ {
+ .name = "query-memory-devices",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_memory_devices,
+ },
+ {
+ .name = "query-acpi-ospm-status",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_query_acpi_ospm_status,
+ },
+#if defined TARGET_I386
+ {
+ .name = "rtc-reset-reinjection",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_rtc_reset_reinjection,
+ },
+#endif
+ {
+ .name = "trace-event-get-state",
+ .args_type = "name:s",
+ .mhandler.cmd_new = qmp_marshal_trace_event_get_state,
+ },
+ {
+ .name = "trace-event-set-state",
+ .args_type = "name:s,enable:b,ignore-unavailable:b?",
+ .mhandler.cmd_new = qmp_marshal_trace_event_set_state,
+ },
+ {
+ .name = "x-input-send-event",
+ .args_type = "console:i?,events:q",
+ .mhandler.cmd_new = qmp_marshal_x_input_send_event,
+ },
+ {
+ .name = "block-set-write-threshold",
+ .args_type = "node-name:s,write-threshold:l",
+ .mhandler.cmd_new = qmp_marshal_block_set_write_threshold,
+ },
+ {
+ .name = "query-rocker",
+ .args_type = "name:s",
+ .mhandler.cmd_new = qmp_marshal_query_rocker,
+ },
+ {
+ .name = "query-rocker-ports",
+ .args_type = "name:s",
+ .mhandler.cmd_new = qmp_marshal_query_rocker_ports,
+ },
+ {
+ .name = "query-rocker-of-dpa-flows",
+ .args_type = "name:s,tbl-id:i?",
+ .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_flows,
+ },
+ {
+ .name = "query-rocker-of-dpa-groups",
+ .args_type = "name:s,type:i?",
+ .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_groups,
+ },
diff --git a/qmp-commands.hx b/qmp-commands.hx
deleted file mode 100644
index 3a7af18..0000000
--- a/qmp-commands.hx
+++ /dev/null
@@ -1,683 +0,0 @@
- {
- .name = "quit",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_quit,
- },
- {
- .name = "eject",
- .args_type = "force:-f,device:B",
- .mhandler.cmd_new = qmp_marshal_eject,
- },
- {
- .name = "change",
- .args_type = "device:B,target:F,arg:s?",
- .mhandler.cmd_new = qmp_marshal_change,
- },
- {
- .name = "screendump",
- .args_type = "filename:F",
- .mhandler.cmd_new = qmp_marshal_screendump,
- },
- {
- .name = "stop",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_stop,
- },
- {
- .name = "cont",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_cont,
- },
- {
- .name = "system_wakeup",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_system_wakeup,
- },
- {
- .name = "system_reset",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_system_reset,
- },
- {
- .name = "system_powerdown",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_system_powerdown,
- },
- {
- .name = "device_add",
- .args_type = "device:O",
- .params = "driver[,prop=value][,...]",
- .help = "add device, like -device on the command line",
- .mhandler.cmd_new = qmp_device_add,
- },
- {
- .name = "device_del",
- .args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_device_del,
- },
- {
- .name = "send-key",
- .args_type = "keys:q,hold-time:i?",
- .mhandler.cmd_new = qmp_marshal_send_key,
- },
- {
- .name = "cpu",
- .args_type = "index:i",
- .mhandler.cmd_new = qmp_marshal_cpu,
- },
- {
- .name = "cpu-add",
- .args_type = "id:i",
- .mhandler.cmd_new = qmp_marshal_cpu_add,
- },
- {
- .name = "memsave",
- .args_type = "val:l,size:i,filename:s,cpu:i?",
- .mhandler.cmd_new = qmp_marshal_memsave,
- },
- {
- .name = "pmemsave",
- .args_type = "val:l,size:i,filename:s",
- .mhandler.cmd_new = qmp_marshal_pmemsave,
- },
- {
- .name = "inject-nmi",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_inject_nmi,
- },
- {
- .name = "ringbuf-write",
- .args_type = "device:s,data:s,format:s?",
- .mhandler.cmd_new = qmp_marshal_ringbuf_write,
- },
- {
- .name = "ringbuf-read",
- .args_type = "device:s,size:i,format:s?",
- .mhandler.cmd_new = qmp_marshal_ringbuf_read,
- },
- {
- .name = "xen-save-devices-state",
- .args_type = "filename:F",
- .mhandler.cmd_new = qmp_marshal_xen_save_devices_state,
- },
- {
- .name = "xen-set-global-dirty-log",
- .args_type = "enable:b",
- .mhandler.cmd_new = qmp_marshal_xen_set_global_dirty_log,
- },
- {
- .name = "migrate",
- .args_type = "detach:-d,blk:-b,inc:-i,uri:s",
- .mhandler.cmd_new = qmp_marshal_migrate,
- },
- {
- .name = "migrate_cancel",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_migrate_cancel,
- },
- {
- .name = "migrate-incoming",
- .args_type = "uri:s",
- .mhandler.cmd_new = qmp_marshal_migrate_incoming,
- },
- {
- .name = "migrate-set-cache-size",
- .args_type = "value:o",
- .mhandler.cmd_new = qmp_marshal_migrate_set_cache_size,
- },
- {
- .name = "query-migrate-cache-size",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate_cache_size,
- },
- {
- .name = "migrate_set_speed",
- .args_type = "value:o",
- .mhandler.cmd_new = qmp_marshal_migrate_set_speed,
- },
- {
- .name = "migrate_set_downtime",
- .args_type = "value:T",
- .mhandler.cmd_new = qmp_marshal_migrate_set_downtime,
- },
- {
- .name = "client_migrate_info",
- .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
- .params = "protocol hostname port tls-port cert-subject",
- .help = "set migration information for remote display",
- .mhandler.cmd_new = qmp_marshal_client_migrate_info,
- },
- {
- .name = "dump-guest-memory",
- .args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
- .params = "-p protocol [begin] [length] [format]",
- .help = "dump guest memory to file",
- .mhandler.cmd_new = qmp_marshal_dump_guest_memory,
- },
- {
- .name = "query-dump-guest-memory-capability",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_dump_guest_memory_capability,
- },
-#if defined TARGET_S390X
- {
- .name = "dump-skeys",
- .args_type = "filename:F",
- .mhandler.cmd_new = qmp_marshal_dump_skeys,
- },
-#endif
- {
- .name = "netdev_add",
- .args_type = "netdev:O",
- .mhandler.cmd_new = qmp_marshal_netdev_add,
- },
- {
- .name = "netdev_del",
- .args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_netdev_del,
- },
- {
- .name = "object-add",
- .args_type = "qom-type:s,id:s,props:q?",
- .mhandler.cmd_new = qmp_marshal_object_add,
- },
- {
- .name = "object-del",
- .args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_object_del,
- },
- {
- .name = "block_resize",
- .args_type = "device:s?,node-name:s?,size:o",
- .mhandler.cmd_new = qmp_marshal_block_resize,
- },
- {
- .name = "block-stream",
- .args_type = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
- .mhandler.cmd_new = qmp_marshal_block_stream,
- },
- {
- .name = "block-commit",
- .args_type = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
- .mhandler.cmd_new = qmp_marshal_block_commit,
- },
- {
- .name = "drive-backup",
- .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
- "bitmap:s?,on-source-error:s?,on-target-error:s?",
- .mhandler.cmd_new = qmp_marshal_drive_backup,
- },
- {
- .name = "blockdev-backup",
- .args_type = "sync:s,device:B,target:B,speed:i?,"
- "on-source-error:s?,on-target-error:s?",
- .mhandler.cmd_new = qmp_marshal_blockdev_backup,
- },
- {
- .name = "block-job-set-speed",
- .args_type = "device:B,speed:o",
- .mhandler.cmd_new = qmp_marshal_block_job_set_speed,
- },
-
- {
- .name = "block-job-cancel",
- .args_type = "device:B,force:b?",
- .mhandler.cmd_new = qmp_marshal_block_job_cancel,
- },
- {
- .name = "block-job-pause",
- .args_type = "device:B",
- .mhandler.cmd_new = qmp_marshal_block_job_pause,
- },
- {
- .name = "block-job-resume",
- .args_type = "device:B",
- .mhandler.cmd_new = qmp_marshal_block_job_resume,
- },
- {
- .name = "block-job-complete",
- .args_type = "device:B",
- .mhandler.cmd_new = qmp_marshal_block_job_complete,
- },
- {
- .name = "transaction",
- .args_type = "actions:q",
- .mhandler.cmd_new = qmp_marshal_transaction,
- },
- {
- .name = "block-dirty-bitmap-add",
- .args_type = "node:B,name:s,granularity:i?",
- .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_add,
- },
- {
- .name = "block-dirty-bitmap-remove",
- .args_type = "node:B,name:s",
- .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_remove,
- },
- {
- .name = "block-dirty-bitmap-clear",
- .args_type = "node:B,name:s",
- .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_clear,
- },
- {
- .name = "blockdev-snapshot-sync",
- .args_type = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
- .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_sync,
- },
- {
- .name = "blockdev-snapshot-internal-sync",
- .args_type = "device:B,name:s",
- .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_internal_sync,
- },
- {
- .name = "blockdev-snapshot-delete-internal-sync",
- .args_type = "device:B,id:s?,name:s?",
- .mhandler.cmd_new =
- qmp_marshal_blockdev_snapshot_delete_internal_sync,
- },
- {
- .name = "drive-mirror",
- .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
- "node-name:s?,replaces:s?,"
- "on-source-error:s?,on-target-error:s?,"
- "unmap:b?,"
- "granularity:i?,buf-size:i?",
- .mhandler.cmd_new = qmp_marshal_drive_mirror,
- },
- {
- .name = "change-backing-file",
- .args_type = "device:s,image-node-name:s,backing-file:s",
- .mhandler.cmd_new = qmp_marshal_change_backing_file,
- },
- {
- .name = "balloon",
- .args_type = "value:M",
- .mhandler.cmd_new = qmp_marshal_balloon,
- },
- {
- .name = "set_link",
- .args_type = "name:s,up:b",
- .mhandler.cmd_new = qmp_marshal_set_link,
- },
- {
- .name = "getfd",
- .args_type = "fdname:s",
- .params = "getfd name",
- .help = "receive a file descriptor via SCM rights and assign it a name",
- .mhandler.cmd_new = qmp_marshal_getfd,
- },
- {
- .name = "closefd",
- .args_type = "fdname:s",
- .params = "closefd name",
- .help = "close a file descriptor previously passed via SCM rights",
- .mhandler.cmd_new = qmp_marshal_closefd,
- },
- {
- .name = "add-fd",
- .args_type = "fdset-id:i?,opaque:s?",
- .params = "add-fd fdset-id opaque",
- .help = "Add a file descriptor, that was passed via SCM rights, to an fd set",
- .mhandler.cmd_new = qmp_marshal_add_fd,
- },
- {
- .name = "remove-fd",
- .args_type = "fdset-id:i,fd:i?",
- .params = "remove-fd fdset-id fd",
- .help = "Remove a file descriptor from an fd set",
- .mhandler.cmd_new = qmp_marshal_remove_fd,
- },
- {
- .name = "query-fdsets",
- .args_type = "",
- .help = "Return information describing all fd sets",
- .mhandler.cmd_new = qmp_marshal_query_fdsets,
- },
- {
- .name = "block_passwd",
- .args_type = "device:s?,node-name:s?,password:s",
- .mhandler.cmd_new = qmp_marshal_block_passwd,
- },
- {
- .name = "block_set_io_throttle",
- .args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l,bps_max:l?,bps_rd_max:l?,bps_wr_max:l?,iops_max:l?,iops_rd_max:l?,iops_wr_max:l?,iops_size:l?,group:s?",
- .mhandler.cmd_new = qmp_marshal_block_set_io_throttle,
- },
- {
- .name = "set_password",
- .args_type = "protocol:s,password:s,connected:s?",
- .mhandler.cmd_new = qmp_marshal_set_password,
- },
- {
- .name = "expire_password",
- .args_type = "protocol:s,time:s",
- .mhandler.cmd_new = qmp_marshal_expire_password,
- },
- {
- .name = "add_client",
- .args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
- .mhandler.cmd_new = qmp_marshal_add_client,
- },
- {
- .name = "qmp_capabilities",
- .args_type = "",
- .help = "enable QMP capabilities",
- .mhandler.cmd_new = qmp_marshal_qmp_capabilities,
- },
- {
- .name = "human-monitor-command",
- .args_type = "command-line:s,cpu-index:i?",
- .mhandler.cmd_new = qmp_marshal_human_monitor_command,
- },
- {
- .name = "query-version",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_version,
- },
- {
- .name = "query-commands",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_commands,
- },
- {
- .name = "query-events",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_events,
- },
- {
- .name = "query-qmp-schema",
- .args_type = "",
- .mhandler.cmd_new = qmp_query_qmp_schema,
- },
- {
- .name = "query-chardev",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_chardev,
- },
- {
- .name = "query-chardev-backends",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_chardev_backends,
- },
- {
- .name = "query-block",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_block,
- },
- {
- .name = "query-blockstats",
- .args_type = "query-nodes:b?",
- .mhandler.cmd_new = qmp_marshal_query_blockstats,
- },
- {
- .name = "query-cpus",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_cpus,
- },
- {
- .name = "query-iothreads",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_iothreads,
- },
- {
- .name = "query-pci",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_pci,
- },
- {
- .name = "query-kvm",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_kvm,
- },
- {
- .name = "query-status",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_status,
- },
- {
- .name = "query-mice",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_mice,
- },
- {
- .name = "query-vnc",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_vnc,
- },
- {
- .name = "query-vnc-servers",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_vnc_servers,
- },
-#if defined(CONFIG_SPICE)
- {
- .name = "query-spice",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_spice,
- },
-#endif
- {
- .name = "query-name",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_name,
- },
- {
- .name = "query-uuid",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_uuid,
- },
- {
- .name = "query-command-line-options",
- .args_type = "option:s?",
- .mhandler.cmd_new = qmp_marshal_query_command_line_options,
- },
- {
- .name = "query-migrate",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate,
- },
- {
- .name = "migrate-set-capabilities",
- .args_type = "capabilities:q",
- .params = "capability:s,state:b",
- .mhandler.cmd_new = qmp_marshal_migrate_set_capabilities,
- },
- {
- .name = "query-migrate-capabilities",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate_capabilities,
- },
- {
- .name = "migrate-set-parameters",
- .args_type =
- "compress-level:i?,compress-threads:i?,decompress-threads:i?",
- .mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
- },
- {
- .name = "query-migrate-parameters",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate_parameters,
- },
- {
- .name = "query-balloon",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_balloon,
- },
-
- {
- .name = "query-block-jobs",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_block_jobs,
- },
-
- {
- .name = "qom-list",
- .args_type = "path:s",
- .mhandler.cmd_new = qmp_marshal_qom_list,
- },
-
- {
- .name = "qom-set",
- .args_type = "path:s,property:s,value:q",
- .mhandler.cmd_new = qmp_marshal_qom_set,
- },
-
- {
- .name = "qom-get",
- .args_type = "path:s,property:s",
- .mhandler.cmd_new = qmp_marshal_qom_get,
- },
-
- {
- .name = "nbd-server-start",
- .args_type = "addr:q",
- .mhandler.cmd_new = qmp_marshal_nbd_server_start,
- },
- {
- .name = "nbd-server-add",
- .args_type = "device:B,writable:b?",
- .mhandler.cmd_new = qmp_marshal_nbd_server_add,
- },
- {
- .name = "nbd-server-stop",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_nbd_server_stop,
- },
-
- {
- .name = "change-vnc-password",
- .args_type = "password:s",
- .mhandler.cmd_new = qmp_marshal_change_vnc_password,
- },
- {
- .name = "qom-list-types",
- .args_type = "implements:s?,abstract:b?",
- .mhandler.cmd_new = qmp_marshal_qom_list_types,
- },
-
- {
- .name = "device-list-properties",
- .args_type = "typename:s",
- .mhandler.cmd_new = qmp_marshal_device_list_properties,
- },
-
- {
- .name = "query-machines",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_machines,
- },
-
- {
- .name = "query-cpu-definitions",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_cpu_definitions,
- },
-
- {
- .name = "query-target",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_target,
- },
-
- {
- .name = "query-tpm",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_tpm,
- },
- {
- .name = "query-tpm-models",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_tpm_models,
- },
- {
- .name = "query-tpm-types",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_tpm_types,
- },
- {
- .name = "chardev-add",
- .args_type = "id:s,backend:q",
- .mhandler.cmd_new = qmp_marshal_chardev_add,
- },
- {
- .name = "chardev-remove",
- .args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_chardev_remove,
- },
- {
- .name = "query-rx-filter",
- .args_type = "name:s?",
- .mhandler.cmd_new = qmp_marshal_query_rx_filter,
- },
- {
- .name = "blockdev-add",
- .args_type = "options:q",
- .mhandler.cmd_new = qmp_marshal_blockdev_add,
- },
- {
- .name = "query-named-block-nodes",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_named_block_nodes,
- },
- {
- .name = "query-memdev",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_memdev,
- },
- {
- .name = "query-memory-devices",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_memory_devices,
- },
- {
- .name = "query-acpi-ospm-status",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_acpi_ospm_status,
- },
-#if defined TARGET_I386
- {
- .name = "rtc-reset-reinjection",
- .args_type = "",
- .mhandler.cmd_new = qmp_marshal_rtc_reset_reinjection,
- },
-#endif
- {
- .name = "trace-event-get-state",
- .args_type = "name:s",
- .mhandler.cmd_new = qmp_marshal_trace_event_get_state,
- },
- {
- .name = "trace-event-set-state",
- .args_type = "name:s,enable:b,ignore-unavailable:b?",
- .mhandler.cmd_new = qmp_marshal_trace_event_set_state,
- },
- {
- .name = "x-input-send-event",
- .args_type = "console:i?,events:q",
- .mhandler.cmd_new = qmp_marshal_x_input_send_event,
- },
- {
- .name = "block-set-write-threshold",
- .args_type = "node-name:s,write-threshold:l",
- .mhandler.cmd_new = qmp_marshal_block_set_write_threshold,
- },
- {
- .name = "query-rocker",
- .args_type = "name:s",
- .mhandler.cmd_new = qmp_marshal_query_rocker,
- },
- {
- .name = "query-rocker-ports",
- .args_type = "name:s",
- .mhandler.cmd_new = qmp_marshal_query_rocker_ports,
- },
- {
- .name = "query-rocker-of-dpa-flows",
- .args_type = "name:s,tbl-id:i?",
- .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_flows,
- },
- {
- .name = "query-rocker-of-dpa-groups",
- .args_type = "name:s,type:i?",
- .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_groups,
- },
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 14/36] monitor: remove usage of generated marshal functions
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (12 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 13/36] build-sys: do not generate qmp-commands-old.h marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 15/36] monitor: register gen:false commands manually marcandre.lureau
` (23 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Once the middle mode is removed, the generated marshal functions will no
longer be exported.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/monitor.c b/monitor.c
index 7e8ad0c..410c3a5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -76,6 +76,7 @@
#include "qapi-event.h"
#include "qmp-introspect.h"
#include "sysemu/block-backend.h"
+#include "qapi/qmp/dispatch.h"
/* for hmp_info_irq/pic */
#if defined(TARGET_SPARC)
@@ -3536,21 +3537,21 @@ static int monitor_can_read(void *opaque)
return (mon->suspend_cnt == 0) ? 1 : 0;
}
-static bool invalid_qmp_mode(const Monitor *mon, const mon_cmd_t *cmd,
+static bool invalid_qmp_mode(const Monitor *mon, const gchar *cmd,
Error **errp)
{
- bool is_cap = cmd->mhandler.cmd_new == qmp_marshal_qmp_capabilities;
+ bool is_cap = !g_strcmp0(cmd, "qmp_capabilities");
if (is_cap && mon->qmp.in_command_mode) {
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
"Capabilities negotiation is already complete, command "
- "'%s' ignored", cmd->name);
+ "'%s' ignored", cmd);
return true;
}
if (!is_cap && !mon->qmp.in_command_mode) {
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
"Expecting capabilities negotiation with "
- "'qmp_capabilities' before command '%s'", cmd->name);
+ "'qmp_capabilities' before command '%s'", cmd);
return true;
}
return false;
@@ -3841,7 +3842,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
"The command %s has not been found", cmd_name);
goto err_out;
}
- if (invalid_qmp_mode(mon, cmd, &local_err)) {
+ if (invalid_qmp_mode(mon, cmd_name, &local_err)) {
goto err_out;
}
@@ -3926,9 +3927,13 @@ void monitor_resume(Monitor *mon)
static QObject *get_qmp_greeting(void)
{
+ QmpCommand *cmd;
QObject *ver = NULL;
- qmp_marshal_query_version(NULL, &ver, NULL);
+ cmd = qmp_find_command("query-version");
+ assert(cmd && cmd->fn);
+ cmd->fn(NULL, &ver, NULL);
+
return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
}
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 15/36] monitor: register gen:false commands manually
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (13 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 14/36] monitor: remove usage of generated marshal functions marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 15:56 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 16/36] qmp: register qapi commands (no middle mode) marcandre.lureau
` (22 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Since some commands are using 'gen': false, they are not registered
automatically by the generator. Register manually instead.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/monitor.c b/monitor.c
index 410c3a5..a979924 100644
--- a/monitor.c
+++ b/monitor.c
@@ -945,6 +945,16 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
*ret_data = qobject_from_json(qmp_schema_json);
}
+static void qmp_init_marshal(void)
+{
+ qmp_register_command("query-qmp-schema", qmp_query_qmp_schema,
+ QCO_NO_OPTIONS);
+ qmp_register_command("device_add", qmp_device_add,
+ QCO_NO_OPTIONS);
+}
+
+qapi_init(qmp_init_marshal);
+
/* set the current CPU defined by the user */
int monitor_set_cpu(int cpu_index)
{
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 16/36] qmp: register qapi commands (no middle mode)
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (14 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 15/36] monitor: register gen:false commands manually marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 16:01 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 17/36] qmp: use qmp_dispatch() marcandre.lureau
` (21 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
The marshal functions are no longer exported, they are registered in the
dispatch table instead. The following patches will make use of
qmp_dispatch(). This patch temporarily breaks qmp/hmp commands.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
Makefile | 2 +-
qmp-commands-old.h | 129 -----------------------------------------------------
vl.c | 1 +
3 files changed, 2 insertions(+), 130 deletions(-)
diff --git a/Makefile b/Makefile
index 5e09e88..9750b71 100644
--- a/Makefile
+++ b/Makefile
@@ -289,7 +289,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
qmp-commands.h qmp-marshal.c :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
- $(gen-out-type) -o "." -m $<, \
+ $(gen-out-type) -o "." $<, \
" GEN $@")
qmp-introspect.h qmp-introspect.c :\
$(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
diff --git a/qmp-commands-old.h b/qmp-commands-old.h
index 3a7af18..956157d 100644
--- a/qmp-commands-old.h
+++ b/qmp-commands-old.h
@@ -1,279 +1,225 @@
{
.name = "quit",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_quit,
},
{
.name = "eject",
.args_type = "force:-f,device:B",
- .mhandler.cmd_new = qmp_marshal_eject,
},
{
.name = "change",
.args_type = "device:B,target:F,arg:s?",
- .mhandler.cmd_new = qmp_marshal_change,
},
{
.name = "screendump",
.args_type = "filename:F",
- .mhandler.cmd_new = qmp_marshal_screendump,
},
{
.name = "stop",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_stop,
},
{
.name = "cont",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_cont,
},
{
.name = "system_wakeup",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_system_wakeup,
},
{
.name = "system_reset",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_system_reset,
},
{
.name = "system_powerdown",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_system_powerdown,
},
{
.name = "device_add",
.args_type = "device:O",
.params = "driver[,prop=value][,...]",
.help = "add device, like -device on the command line",
- .mhandler.cmd_new = qmp_device_add,
},
{
.name = "device_del",
.args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_device_del,
},
{
.name = "send-key",
.args_type = "keys:q,hold-time:i?",
- .mhandler.cmd_new = qmp_marshal_send_key,
},
{
.name = "cpu",
.args_type = "index:i",
- .mhandler.cmd_new = qmp_marshal_cpu,
},
{
.name = "cpu-add",
.args_type = "id:i",
- .mhandler.cmd_new = qmp_marshal_cpu_add,
},
{
.name = "memsave",
.args_type = "val:l,size:i,filename:s,cpu:i?",
- .mhandler.cmd_new = qmp_marshal_memsave,
},
{
.name = "pmemsave",
.args_type = "val:l,size:i,filename:s",
- .mhandler.cmd_new = qmp_marshal_pmemsave,
},
{
.name = "inject-nmi",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_inject_nmi,
},
{
.name = "ringbuf-write",
.args_type = "device:s,data:s,format:s?",
- .mhandler.cmd_new = qmp_marshal_ringbuf_write,
},
{
.name = "ringbuf-read",
.args_type = "device:s,size:i,format:s?",
- .mhandler.cmd_new = qmp_marshal_ringbuf_read,
},
{
.name = "xen-save-devices-state",
.args_type = "filename:F",
- .mhandler.cmd_new = qmp_marshal_xen_save_devices_state,
},
{
.name = "xen-set-global-dirty-log",
.args_type = "enable:b",
- .mhandler.cmd_new = qmp_marshal_xen_set_global_dirty_log,
},
{
.name = "migrate",
.args_type = "detach:-d,blk:-b,inc:-i,uri:s",
- .mhandler.cmd_new = qmp_marshal_migrate,
},
{
.name = "migrate_cancel",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_migrate_cancel,
},
{
.name = "migrate-incoming",
.args_type = "uri:s",
- .mhandler.cmd_new = qmp_marshal_migrate_incoming,
},
{
.name = "migrate-set-cache-size",
.args_type = "value:o",
- .mhandler.cmd_new = qmp_marshal_migrate_set_cache_size,
},
{
.name = "query-migrate-cache-size",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate_cache_size,
},
{
.name = "migrate_set_speed",
.args_type = "value:o",
- .mhandler.cmd_new = qmp_marshal_migrate_set_speed,
},
{
.name = "migrate_set_downtime",
.args_type = "value:T",
- .mhandler.cmd_new = qmp_marshal_migrate_set_downtime,
},
{
.name = "client_migrate_info",
.args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
.params = "protocol hostname port tls-port cert-subject",
.help = "set migration information for remote display",
- .mhandler.cmd_new = qmp_marshal_client_migrate_info,
},
{
.name = "dump-guest-memory",
.args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
.params = "-p protocol [begin] [length] [format]",
.help = "dump guest memory to file",
- .mhandler.cmd_new = qmp_marshal_dump_guest_memory,
},
{
.name = "query-dump-guest-memory-capability",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_dump_guest_memory_capability,
},
#if defined TARGET_S390X
{
.name = "dump-skeys",
.args_type = "filename:F",
- .mhandler.cmd_new = qmp_marshal_dump_skeys,
},
#endif
{
.name = "netdev_add",
.args_type = "netdev:O",
- .mhandler.cmd_new = qmp_marshal_netdev_add,
},
{
.name = "netdev_del",
.args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_netdev_del,
},
{
.name = "object-add",
.args_type = "qom-type:s,id:s,props:q?",
- .mhandler.cmd_new = qmp_marshal_object_add,
},
{
.name = "object-del",
.args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_object_del,
},
{
.name = "block_resize",
.args_type = "device:s?,node-name:s?,size:o",
- .mhandler.cmd_new = qmp_marshal_block_resize,
},
{
.name = "block-stream",
.args_type = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
- .mhandler.cmd_new = qmp_marshal_block_stream,
},
{
.name = "block-commit",
.args_type = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
- .mhandler.cmd_new = qmp_marshal_block_commit,
},
{
.name = "drive-backup",
.args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
"bitmap:s?,on-source-error:s?,on-target-error:s?",
- .mhandler.cmd_new = qmp_marshal_drive_backup,
},
{
.name = "blockdev-backup",
.args_type = "sync:s,device:B,target:B,speed:i?,"
"on-source-error:s?,on-target-error:s?",
- .mhandler.cmd_new = qmp_marshal_blockdev_backup,
},
{
.name = "block-job-set-speed",
.args_type = "device:B,speed:o",
- .mhandler.cmd_new = qmp_marshal_block_job_set_speed,
},
{
.name = "block-job-cancel",
.args_type = "device:B,force:b?",
- .mhandler.cmd_new = qmp_marshal_block_job_cancel,
},
{
.name = "block-job-pause",
.args_type = "device:B",
- .mhandler.cmd_new = qmp_marshal_block_job_pause,
},
{
.name = "block-job-resume",
.args_type = "device:B",
- .mhandler.cmd_new = qmp_marshal_block_job_resume,
},
{
.name = "block-job-complete",
.args_type = "device:B",
- .mhandler.cmd_new = qmp_marshal_block_job_complete,
},
{
.name = "transaction",
.args_type = "actions:q",
- .mhandler.cmd_new = qmp_marshal_transaction,
},
{
.name = "block-dirty-bitmap-add",
.args_type = "node:B,name:s,granularity:i?",
- .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_add,
},
{
.name = "block-dirty-bitmap-remove",
.args_type = "node:B,name:s",
- .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_remove,
},
{
.name = "block-dirty-bitmap-clear",
.args_type = "node:B,name:s",
- .mhandler.cmd_new = qmp_marshal_block_dirty_bitmap_clear,
},
{
.name = "blockdev-snapshot-sync",
.args_type = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
- .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_sync,
},
{
.name = "blockdev-snapshot-internal-sync",
.args_type = "device:B,name:s",
- .mhandler.cmd_new = qmp_marshal_blockdev_snapshot_internal_sync,
},
{
.name = "blockdev-snapshot-delete-internal-sync",
.args_type = "device:B,id:s?,name:s?",
- .mhandler.cmd_new =
- qmp_marshal_blockdev_snapshot_delete_internal_sync,
},
{
.name = "drive-mirror",
@@ -282,402 +228,327 @@
"on-source-error:s?,on-target-error:s?,"
"unmap:b?,"
"granularity:i?,buf-size:i?",
- .mhandler.cmd_new = qmp_marshal_drive_mirror,
},
{
.name = "change-backing-file",
.args_type = "device:s,image-node-name:s,backing-file:s",
- .mhandler.cmd_new = qmp_marshal_change_backing_file,
},
{
.name = "balloon",
.args_type = "value:M",
- .mhandler.cmd_new = qmp_marshal_balloon,
},
{
.name = "set_link",
.args_type = "name:s,up:b",
- .mhandler.cmd_new = qmp_marshal_set_link,
},
{
.name = "getfd",
.args_type = "fdname:s",
.params = "getfd name",
.help = "receive a file descriptor via SCM rights and assign it a name",
- .mhandler.cmd_new = qmp_marshal_getfd,
},
{
.name = "closefd",
.args_type = "fdname:s",
.params = "closefd name",
.help = "close a file descriptor previously passed via SCM rights",
- .mhandler.cmd_new = qmp_marshal_closefd,
},
{
.name = "add-fd",
.args_type = "fdset-id:i?,opaque:s?",
.params = "add-fd fdset-id opaque",
.help = "Add a file descriptor, that was passed via SCM rights, to an fd set",
- .mhandler.cmd_new = qmp_marshal_add_fd,
},
{
.name = "remove-fd",
.args_type = "fdset-id:i,fd:i?",
.params = "remove-fd fdset-id fd",
.help = "Remove a file descriptor from an fd set",
- .mhandler.cmd_new = qmp_marshal_remove_fd,
},
{
.name = "query-fdsets",
.args_type = "",
.help = "Return information describing all fd sets",
- .mhandler.cmd_new = qmp_marshal_query_fdsets,
},
{
.name = "block_passwd",
.args_type = "device:s?,node-name:s?,password:s",
- .mhandler.cmd_new = qmp_marshal_block_passwd,
},
{
.name = "block_set_io_throttle",
.args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l,bps_max:l?,bps_rd_max:l?,bps_wr_max:l?,iops_max:l?,iops_rd_max:l?,iops_wr_max:l?,iops_size:l?,group:s?",
- .mhandler.cmd_new = qmp_marshal_block_set_io_throttle,
},
{
.name = "set_password",
.args_type = "protocol:s,password:s,connected:s?",
- .mhandler.cmd_new = qmp_marshal_set_password,
},
{
.name = "expire_password",
.args_type = "protocol:s,time:s",
- .mhandler.cmd_new = qmp_marshal_expire_password,
},
{
.name = "add_client",
.args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
- .mhandler.cmd_new = qmp_marshal_add_client,
},
{
.name = "qmp_capabilities",
.args_type = "",
.help = "enable QMP capabilities",
- .mhandler.cmd_new = qmp_marshal_qmp_capabilities,
},
{
.name = "human-monitor-command",
.args_type = "command-line:s,cpu-index:i?",
- .mhandler.cmd_new = qmp_marshal_human_monitor_command,
},
{
.name = "query-version",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_version,
},
{
.name = "query-commands",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_commands,
},
{
.name = "query-events",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_events,
},
{
.name = "query-qmp-schema",
.args_type = "",
- .mhandler.cmd_new = qmp_query_qmp_schema,
},
{
.name = "query-chardev",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_chardev,
},
{
.name = "query-chardev-backends",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_chardev_backends,
},
{
.name = "query-block",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_block,
},
{
.name = "query-blockstats",
.args_type = "query-nodes:b?",
- .mhandler.cmd_new = qmp_marshal_query_blockstats,
},
{
.name = "query-cpus",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_cpus,
},
{
.name = "query-iothreads",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_iothreads,
},
{
.name = "query-pci",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_pci,
},
{
.name = "query-kvm",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_kvm,
},
{
.name = "query-status",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_status,
},
{
.name = "query-mice",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_mice,
},
{
.name = "query-vnc",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_vnc,
},
{
.name = "query-vnc-servers",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_vnc_servers,
},
#if defined(CONFIG_SPICE)
{
.name = "query-spice",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_spice,
},
#endif
{
.name = "query-name",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_name,
},
{
.name = "query-uuid",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_uuid,
},
{
.name = "query-command-line-options",
.args_type = "option:s?",
- .mhandler.cmd_new = qmp_marshal_query_command_line_options,
},
{
.name = "query-migrate",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate,
},
{
.name = "migrate-set-capabilities",
.args_type = "capabilities:q",
.params = "capability:s,state:b",
- .mhandler.cmd_new = qmp_marshal_migrate_set_capabilities,
},
{
.name = "query-migrate-capabilities",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate_capabilities,
},
{
.name = "migrate-set-parameters",
.args_type =
"compress-level:i?,compress-threads:i?,decompress-threads:i?",
- .mhandler.cmd_new = qmp_marshal_migrate_set_parameters,
},
{
.name = "query-migrate-parameters",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_migrate_parameters,
},
{
.name = "query-balloon",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_balloon,
},
{
.name = "query-block-jobs",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_block_jobs,
},
{
.name = "qom-list",
.args_type = "path:s",
- .mhandler.cmd_new = qmp_marshal_qom_list,
},
{
.name = "qom-set",
.args_type = "path:s,property:s,value:q",
- .mhandler.cmd_new = qmp_marshal_qom_set,
},
{
.name = "qom-get",
.args_type = "path:s,property:s",
- .mhandler.cmd_new = qmp_marshal_qom_get,
},
{
.name = "nbd-server-start",
.args_type = "addr:q",
- .mhandler.cmd_new = qmp_marshal_nbd_server_start,
},
{
.name = "nbd-server-add",
.args_type = "device:B,writable:b?",
- .mhandler.cmd_new = qmp_marshal_nbd_server_add,
},
{
.name = "nbd-server-stop",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_nbd_server_stop,
},
{
.name = "change-vnc-password",
.args_type = "password:s",
- .mhandler.cmd_new = qmp_marshal_change_vnc_password,
},
{
.name = "qom-list-types",
.args_type = "implements:s?,abstract:b?",
- .mhandler.cmd_new = qmp_marshal_qom_list_types,
},
{
.name = "device-list-properties",
.args_type = "typename:s",
- .mhandler.cmd_new = qmp_marshal_device_list_properties,
},
{
.name = "query-machines",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_machines,
},
{
.name = "query-cpu-definitions",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_cpu_definitions,
},
{
.name = "query-target",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_target,
},
{
.name = "query-tpm",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_tpm,
},
{
.name = "query-tpm-models",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_tpm_models,
},
{
.name = "query-tpm-types",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_tpm_types,
},
{
.name = "chardev-add",
.args_type = "id:s,backend:q",
- .mhandler.cmd_new = qmp_marshal_chardev_add,
},
{
.name = "chardev-remove",
.args_type = "id:s",
- .mhandler.cmd_new = qmp_marshal_chardev_remove,
},
{
.name = "query-rx-filter",
.args_type = "name:s?",
- .mhandler.cmd_new = qmp_marshal_query_rx_filter,
},
{
.name = "blockdev-add",
.args_type = "options:q",
- .mhandler.cmd_new = qmp_marshal_blockdev_add,
},
{
.name = "query-named-block-nodes",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_named_block_nodes,
},
{
.name = "query-memdev",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_memdev,
},
{
.name = "query-memory-devices",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_memory_devices,
},
{
.name = "query-acpi-ospm-status",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_query_acpi_ospm_status,
},
#if defined TARGET_I386
{
.name = "rtc-reset-reinjection",
.args_type = "",
- .mhandler.cmd_new = qmp_marshal_rtc_reset_reinjection,
},
#endif
{
.name = "trace-event-get-state",
.args_type = "name:s",
- .mhandler.cmd_new = qmp_marshal_trace_event_get_state,
},
{
.name = "trace-event-set-state",
.args_type = "name:s,enable:b,ignore-unavailable:b?",
- .mhandler.cmd_new = qmp_marshal_trace_event_set_state,
},
{
.name = "x-input-send-event",
.args_type = "console:i?,events:q",
- .mhandler.cmd_new = qmp_marshal_x_input_send_event,
},
{
.name = "block-set-write-threshold",
.args_type = "node-name:s,write-threshold:l",
- .mhandler.cmd_new = qmp_marshal_block_set_write_threshold,
},
{
.name = "query-rocker",
.args_type = "name:s",
- .mhandler.cmd_new = qmp_marshal_query_rocker,
},
{
.name = "query-rocker-ports",
.args_type = "name:s",
- .mhandler.cmd_new = qmp_marshal_query_rocker_ports,
},
{
.name = "query-rocker-of-dpa-flows",
.args_type = "name:s,tbl-id:i?",
- .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_flows,
},
{
.name = "query-rocker-of-dpa-groups",
.args_type = "name:s,type:i?",
- .mhandler.cmd_new = qmp_marshal_query_rocker_of_dpa_groups,
},
diff --git a/vl.c b/vl.c
index e211f6a..c8f1ad5 100644
--- a/vl.c
+++ b/vl.c
@@ -2966,6 +2966,7 @@ int main(int argc, char **argv, char **envp)
g_mem_set_vtable(&mem_trace);
module_call_init(MODULE_INIT_QOM);
+ module_call_init(MODULE_INIT_QAPI);
qemu_add_opts(&qemu_drive_opts);
qemu_add_drive_opts(&qemu_legacy_drive_opts);
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 17/36] qmp: use qmp_dispatch()
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (15 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 16/36] qmp: register qapi commands (no middle mode) marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 18/36] qapi: remove "middle" mode marcandre.lureau
` (20 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Replace the old "middle mode" dispatch code using the manually
maintained table by the one generated by qapi scripts.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 316 +++++++-------------------------------------------------------
1 file changed, 34 insertions(+), 282 deletions(-)
diff --git a/monitor.c b/monitor.c
index a979924..bfa0329 100644
--- a/monitor.c
+++ b/monitor.c
@@ -166,7 +166,6 @@ struct MonFdset {
};
typedef struct {
- QObject *id;
JSONMessageParser parser;
/*
* When a client connects, we're in capabilities negotiation mode.
@@ -397,49 +396,6 @@ static void monitor_json_emitter(Monitor *mon, const QObject *data)
QDECREF(json);
}
-static QDict *build_qmp_error_dict(Error *err)
-{
- QObject *obj;
-
- obj = qobject_from_jsonf("{ 'error': { 'class': %s, 'desc': %s } }",
- ErrorClass_lookup[error_get_class(err)],
- error_get_pretty(err));
-
- return qobject_to_qdict(obj);
-}
-
-static void monitor_protocol_emitter(Monitor *mon, QObject *data,
- Error *err)
-{
- QDict *qmp;
-
- trace_monitor_protocol_emitter(mon);
-
- if (!err) {
- /* success response */
- qmp = qdict_new();
- if (data) {
- qobject_incref(data);
- qdict_put_obj(qmp, "return", data);
- } else {
- /* return an empty QDict by default */
- qdict_put(qmp, "return", qdict_new());
- }
- } else {
- /* error response */
- qmp = build_qmp_error_dict(err);
- }
-
- if (mon->qmp.id) {
- qdict_put_obj(qmp, "id", mon->qmp.id);
- mon->qmp.id = NULL;
- }
-
- monitor_json_emitter(mon, QOBJECT(qmp));
- QDECREF(qmp);
-}
-
-
static MonitorQAPIEventState monitor_qapi_event_state[QAPI_EVENT_MAX];
/*
@@ -2436,11 +2392,6 @@ static const mon_cmd_t *search_dispatch_table(const mon_cmd_t *disp_table,
return NULL;
}
-static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
-{
- return search_dispatch_table(qmp_cmds, cmdname);
-}
-
/*
* Parse command name from @cmdp according to command table @table.
* If blank, return NULL.
@@ -3568,199 +3519,6 @@ static bool invalid_qmp_mode(const Monitor *mon, const gchar *cmd,
}
/*
- * Argument validation rules:
- *
- * 1. The argument must exist in cmd_args qdict
- * 2. The argument type must be the expected one
- *
- * Special case: If the argument doesn't exist in cmd_args and
- * the QMP_ACCEPT_UNKNOWNS flag is set, then the
- * checking is skipped for it.
- */
-static void check_client_args_type(const QDict *client_args,
- const QDict *cmd_args, int flags,
- Error **errp)
-{
- const QDictEntry *ent;
-
- for (ent = qdict_first(client_args); ent;ent = qdict_next(client_args,ent)){
- QObject *obj;
- QString *arg_type;
- const QObject *client_arg = qdict_entry_value(ent);
- const char *client_arg_name = qdict_entry_key(ent);
-
- obj = qdict_get(cmd_args, client_arg_name);
- if (!obj) {
- if (flags & QMP_ACCEPT_UNKNOWNS) {
- /* handler accepts unknowns */
- continue;
- }
- /* client arg doesn't exist */
- error_setg(errp, QERR_INVALID_PARAMETER, client_arg_name);
- return;
- }
-
- arg_type = qobject_to_qstring(obj);
- assert(arg_type != NULL);
-
- /* check if argument's type is correct */
- switch (qstring_get_str(arg_type)[0]) {
- case 'F':
- case 'B':
- case 's':
- if (qobject_type(client_arg) != QTYPE_QSTRING) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
- client_arg_name, "string");
- return;
- }
- break;
- case 'i':
- case 'l':
- case 'M':
- case 'o':
- if (qobject_type(client_arg) != QTYPE_QINT) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
- client_arg_name, "int");
- return;
- }
- break;
- case 'T':
- if (qobject_type(client_arg) != QTYPE_QINT &&
- qobject_type(client_arg) != QTYPE_QFLOAT) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
- client_arg_name, "number");
- return;
- }
- break;
- case 'b':
- case '-':
- if (qobject_type(client_arg) != QTYPE_QBOOL) {
- error_setg(errp, QERR_INVALID_PARAMETER_TYPE,
- client_arg_name, "bool");
- return;
- }
- break;
- case 'O':
- assert(flags & QMP_ACCEPT_UNKNOWNS);
- break;
- case 'q':
- /* Any QObject can be passed. */
- break;
- case '/':
- case '.':
- /*
- * These types are not supported by QMP and thus are not
- * handled here. Fall through.
- */
- default:
- abort();
- }
- }
-}
-
-/*
- * - Check if the client has passed all mandatory args
- * - Set special flags for argument validation
- */
-static void check_mandatory_args(const QDict *cmd_args,
- const QDict *client_args, int *flags,
- Error **errp)
-{
- const QDictEntry *ent;
-
- for (ent = qdict_first(cmd_args); ent; ent = qdict_next(cmd_args, ent)) {
- const char *cmd_arg_name = qdict_entry_key(ent);
- QString *type = qobject_to_qstring(qdict_entry_value(ent));
- assert(type != NULL);
-
- if (qstring_get_str(type)[0] == 'O') {
- assert((*flags & QMP_ACCEPT_UNKNOWNS) == 0);
- *flags |= QMP_ACCEPT_UNKNOWNS;
- } else if (qstring_get_str(type)[0] != '-' &&
- qstring_get_str(type)[1] != '?' &&
- !qdict_haskey(client_args, cmd_arg_name)) {
- error_setg(errp, QERR_MISSING_PARAMETER, cmd_arg_name);
- return;
- }
- }
-}
-
-static QDict *qdict_from_args_type(const char *args_type)
-{
- int i;
- QDict *qdict;
- QString *key, *type, *cur_qs;
-
- assert(args_type != NULL);
-
- qdict = qdict_new();
-
- if (args_type == NULL || args_type[0] == '\0') {
- /* no args, empty qdict */
- goto out;
- }
-
- key = qstring_new();
- type = qstring_new();
-
- cur_qs = key;
-
- for (i = 0;; i++) {
- switch (args_type[i]) {
- case ',':
- case '\0':
- qdict_put(qdict, qstring_get_str(key), type);
- QDECREF(key);
- if (args_type[i] == '\0') {
- goto out;
- }
- type = qstring_new(); /* qdict has ref */
- cur_qs = key = qstring_new();
- break;
- case ':':
- cur_qs = type;
- break;
- default:
- qstring_append_chr(cur_qs, args_type[i]);
- break;
- }
- }
-
-out:
- return qdict;
-}
-
-/*
- * Client argument checking rules:
- *
- * 1. Client must provide all mandatory arguments
- * 2. Each argument provided by the client must be expected
- * 3. Each argument provided by the client must have the type expected
- * by the command
- */
-static void qmp_check_client_args(const mon_cmd_t *cmd, QDict *client_args,
- Error **errp)
-{
- Error *err = NULL;
- int flags;
- QDict *cmd_args;
-
- cmd_args = qdict_from_args_type(cmd->args_type);
-
- flags = 0;
- check_mandatory_args(cmd_args, client_args, &flags, &err);
- if (err) {
- goto out;
- }
-
- check_client_args_type(client_args, cmd_args, flags, &err);
-
-out:
- error_propagate(errp, err);
- QDECREF(cmd_args);
-}
-
-/*
* Input object checking rules
*
* 1. Input object must be a dict
@@ -3818,64 +3576,58 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
{
- Error *local_err = NULL;
- QObject *obj, *data;
- QDict *input, *args;
- const mon_cmd_t *cmd;
+ QObject *req, *rsp = NULL, *id = NULL;
+ QDict *qdict = NULL;
const char *cmd_name;
Monitor *mon = cur_mon;
+ Error *err = NULL;
- args = input = NULL;
- data = NULL;
-
- obj = json_parser_parse(tokens, NULL);
- if (!obj) {
- // FIXME: should be triggered in json_parser_parse()
- error_setg(&local_err, QERR_JSON_PARSING);
+ req = json_parser_parse_err(tokens, NULL, &err);
+ if (err || !req || qobject_type(req) != QTYPE_QDICT) {
+ if (!err) {
+ error_setg(&err, QERR_JSON_PARSING);
+ }
goto err_out;
}
- input = qmp_check_input_obj(obj, &local_err);
- if (!input) {
- qobject_decref(obj);
+ qdict = qmp_check_input_obj(req, &err);
+ if (!qdict) {
goto err_out;
}
- mon->qmp.id = qdict_get(input, "id");
- qobject_incref(mon->qmp.id);
+ id = qdict_get(qdict, "id");
+ qobject_incref(id);
+ qdict_del(qdict, "id");
- cmd_name = qdict_get_str(input, "execute");
+ cmd_name = qdict_get_str(qdict, "execute");
trace_handle_qmp_command(mon, cmd_name);
- cmd = qmp_find_cmd(cmd_name);
- if (!cmd) {
- error_set(&local_err, ERROR_CLASS_COMMAND_NOT_FOUND,
- "The command %s has not been found", cmd_name);
- goto err_out;
- }
- if (invalid_qmp_mode(mon, cmd_name, &local_err)) {
+
+ if (invalid_qmp_mode(mon, cmd_name, &err)) {
goto err_out;
}
- obj = qdict_get(input, "arguments");
- if (!obj) {
- args = qdict_new();
- } else {
- args = qobject_to_qdict(obj);
- QINCREF(args);
- }
+ rsp = qmp_dispatch(req);
- qmp_check_client_args(cmd, args, &local_err);
- if (local_err) {
- goto err_out;
+err_out:
+ if (err) {
+ qdict = qdict_new();
+ qdict_put_obj(qdict, "error", qmp_build_error_object(err));
+ error_free(err);
+ rsp = QOBJECT(qdict);
}
- cmd->mhandler.cmd_new(args, &data, &local_err);
+ if (rsp) {
+ if (id) {
+ qdict_put_obj(qobject_to_qdict(rsp), "id", id);
+ id = NULL;
+ }
-err_out:
- monitor_protocol_emitter(mon, data, local_err);
- qobject_decref(data);
- QDECREF(input);
- QDECREF(args);
+ monitor_json_emitter(mon, rsp);
+ }
+
+ qobject_decref(id);
+ qobject_decref(rsp);
+ qobject_decref(req);
}
static void monitor_qmp_read(void *opaque, const uint8_t *buf, int size)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 18/36] qapi: remove "middle" mode
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (16 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 17/36] qmp: use qmp_dispatch() marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 16:03 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 19/36] qmp: implement qmp_query_commands without qmp_cmds marcandre.lureau
` (19 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Now that the register function is always generated, we can
remove the so-called "middle" mode to the generator script.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi-commands.py | 29 +++++------------------------
1 file changed, 5 insertions(+), 24 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 9d2708f..4db1ae3 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -179,17 +179,8 @@ out:
def gen_marshal_proto(name):
- ret = 'void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)' % c_name(name)
- if not middle_mode:
- ret = 'static ' + ret
- return ret
-
-
-def gen_marshal_decl(name):
- return mcgen('''
-%(proto)s;
-''',
- proto=gen_marshal_proto(name))
+ return 'static void qmp_marshal_%s' % c_name(name) + \
+ '(QDict *args, QObject **ret, Error **errp)'
def gen_marshal(name, arg_type, box, ret_type):
@@ -263,8 +254,7 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
self._visited_ret_types = set()
def visit_end(self):
- if not middle_mode:
- self.defn += gen_registry(self._regy)
+ self.defn += gen_registry(self._regy)
self._regy = None
self._visited_ret_types = None
@@ -276,21 +266,12 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
if ret_type and ret_type not in self._visited_ret_types:
self._visited_ret_types.add(ret_type)
self.defn += gen_marshal_output(ret_type)
- if middle_mode:
- self.decl += gen_marshal_decl(name)
self.defn += gen_marshal(name, arg_type, box, ret_type)
- if not middle_mode:
- self._regy += gen_register_command(name, success_response)
-
+ self._regy += gen_register_command(name, success_response)
-middle_mode = False
(input_file, output_dir, do_c, do_h, prefix, opts) = \
- parse_command_line("m", ["middle"])
-
-for o, a in opts:
- if o in ("-m", "--middle"):
- middle_mode = True
+ parse_command_line()
c_comment = '''
/*
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 19/36] qmp: implement qmp_query_commands without qmp_cmds
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (17 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 18/36] qapi: remove "middle" mode marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 16:06 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 20/36] qmp: remove old qmp-commands table marcandre.lureau
` (18 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
So we can get rid of the static qmp_cmds table.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/monitor.c b/monitor.c
index bfa0329..a2eb228 100644
--- a/monitor.c
+++ b/monitor.c
@@ -850,21 +850,24 @@ static void hmp_info_help(Monitor *mon, const QDict *qdict)
help_cmd(mon, "info");
}
-CommandInfoList *qmp_query_commands(Error **errp)
+static void query_commands_cb(QmpCommand *cmd, void *opaque)
{
- CommandInfoList *info, *cmd_list = NULL;
- const mon_cmd_t *cmd;
+ CommandInfoList *info, **list = opaque;
- for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
- info = g_malloc0(sizeof(*info));
- info->value = g_malloc0(sizeof(*info->value));
- info->value->name = g_strdup(cmd->name);
+ info = g_malloc0(sizeof(*info));
+ info->value = g_malloc0(sizeof(*info->value));
+ info->value->name = g_strdup(cmd->name);
+ info->next = *list;
+ *list = info;
+}
- info->next = cmd_list;
- cmd_list = info;
- }
+CommandInfoList *qmp_query_commands(Error **errp)
+{
+ CommandInfoList *list = NULL;
+
+ qmp_for_each_command(query_commands_cb, &list);
- return cmd_list;
+ return list;
}
EventInfoList *qmp_query_events(Error **errp)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 20/36] qmp: remove old qmp-commands table
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (18 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 19/36] qmp: implement qmp_query_commands without qmp_cmds marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 16:08 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 21/36] misc: spelling marcandre.lureau
` (17 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
The table is no longer used.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 7 -
qmp-commands-old.h | 554 -----------------------------------------------------
2 files changed, 561 deletions(-)
delete mode 100644 qmp-commands-old.h
diff --git a/monitor.c b/monitor.c
index a2eb228..4deef29 100644
--- a/monitor.c
+++ b/monitor.c
@@ -225,8 +225,6 @@ static int mon_refcount;
static mon_cmd_t mon_cmds[];
static mon_cmd_t info_cmds[];
-static const mon_cmd_t qmp_cmds[];
-
Monitor *cur_mon;
static void monitor_command_cb(void *opaque, const char *cmdline,
@@ -2048,11 +2046,6 @@ static mon_cmd_t mon_cmds[] = {
{ NULL, NULL, },
};
-static const mon_cmd_t qmp_cmds[] = {
-#include "qmp-commands-old.h"
- { /* NULL */ },
-};
-
/*******************************************************************/
static const char *pch;
diff --git a/qmp-commands-old.h b/qmp-commands-old.h
deleted file mode 100644
index 956157d..0000000
--- a/qmp-commands-old.h
+++ /dev/null
@@ -1,554 +0,0 @@
- {
- .name = "quit",
- .args_type = "",
- },
- {
- .name = "eject",
- .args_type = "force:-f,device:B",
- },
- {
- .name = "change",
- .args_type = "device:B,target:F,arg:s?",
- },
- {
- .name = "screendump",
- .args_type = "filename:F",
- },
- {
- .name = "stop",
- .args_type = "",
- },
- {
- .name = "cont",
- .args_type = "",
- },
- {
- .name = "system_wakeup",
- .args_type = "",
- },
- {
- .name = "system_reset",
- .args_type = "",
- },
- {
- .name = "system_powerdown",
- .args_type = "",
- },
- {
- .name = "device_add",
- .args_type = "device:O",
- .params = "driver[,prop=value][,...]",
- .help = "add device, like -device on the command line",
- },
- {
- .name = "device_del",
- .args_type = "id:s",
- },
- {
- .name = "send-key",
- .args_type = "keys:q,hold-time:i?",
- },
- {
- .name = "cpu",
- .args_type = "index:i",
- },
- {
- .name = "cpu-add",
- .args_type = "id:i",
- },
- {
- .name = "memsave",
- .args_type = "val:l,size:i,filename:s,cpu:i?",
- },
- {
- .name = "pmemsave",
- .args_type = "val:l,size:i,filename:s",
- },
- {
- .name = "inject-nmi",
- .args_type = "",
- },
- {
- .name = "ringbuf-write",
- .args_type = "device:s,data:s,format:s?",
- },
- {
- .name = "ringbuf-read",
- .args_type = "device:s,size:i,format:s?",
- },
- {
- .name = "xen-save-devices-state",
- .args_type = "filename:F",
- },
- {
- .name = "xen-set-global-dirty-log",
- .args_type = "enable:b",
- },
- {
- .name = "migrate",
- .args_type = "detach:-d,blk:-b,inc:-i,uri:s",
- },
- {
- .name = "migrate_cancel",
- .args_type = "",
- },
- {
- .name = "migrate-incoming",
- .args_type = "uri:s",
- },
- {
- .name = "migrate-set-cache-size",
- .args_type = "value:o",
- },
- {
- .name = "query-migrate-cache-size",
- .args_type = "",
- },
- {
- .name = "migrate_set_speed",
- .args_type = "value:o",
- },
- {
- .name = "migrate_set_downtime",
- .args_type = "value:T",
- },
- {
- .name = "client_migrate_info",
- .args_type = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
- .params = "protocol hostname port tls-port cert-subject",
- .help = "set migration information for remote display",
- },
- {
- .name = "dump-guest-memory",
- .args_type = "paging:b,protocol:s,begin:i?,end:i?,format:s?",
- .params = "-p protocol [begin] [length] [format]",
- .help = "dump guest memory to file",
- },
- {
- .name = "query-dump-guest-memory-capability",
- .args_type = "",
- },
-#if defined TARGET_S390X
- {
- .name = "dump-skeys",
- .args_type = "filename:F",
- },
-#endif
- {
- .name = "netdev_add",
- .args_type = "netdev:O",
- },
- {
- .name = "netdev_del",
- .args_type = "id:s",
- },
- {
- .name = "object-add",
- .args_type = "qom-type:s,id:s,props:q?",
- },
- {
- .name = "object-del",
- .args_type = "id:s",
- },
- {
- .name = "block_resize",
- .args_type = "device:s?,node-name:s?,size:o",
- },
- {
- .name = "block-stream",
- .args_type = "device:B,base:s?,speed:o?,backing-file:s?,on-error:s?",
- },
- {
- .name = "block-commit",
- .args_type = "device:B,base:s?,top:s?,backing-file:s?,speed:o?",
- },
- {
- .name = "drive-backup",
- .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
- "bitmap:s?,on-source-error:s?,on-target-error:s?",
- },
- {
- .name = "blockdev-backup",
- .args_type = "sync:s,device:B,target:B,speed:i?,"
- "on-source-error:s?,on-target-error:s?",
- },
- {
- .name = "block-job-set-speed",
- .args_type = "device:B,speed:o",
- },
-
- {
- .name = "block-job-cancel",
- .args_type = "device:B,force:b?",
- },
- {
- .name = "block-job-pause",
- .args_type = "device:B",
- },
- {
- .name = "block-job-resume",
- .args_type = "device:B",
- },
- {
- .name = "block-job-complete",
- .args_type = "device:B",
- },
- {
- .name = "transaction",
- .args_type = "actions:q",
- },
- {
- .name = "block-dirty-bitmap-add",
- .args_type = "node:B,name:s,granularity:i?",
- },
- {
- .name = "block-dirty-bitmap-remove",
- .args_type = "node:B,name:s",
- },
- {
- .name = "block-dirty-bitmap-clear",
- .args_type = "node:B,name:s",
- },
- {
- .name = "blockdev-snapshot-sync",
- .args_type = "device:s?,node-name:s?,snapshot-file:s,snapshot-node-name:s?,format:s?,mode:s?",
- },
- {
- .name = "blockdev-snapshot-internal-sync",
- .args_type = "device:B,name:s",
- },
- {
- .name = "blockdev-snapshot-delete-internal-sync",
- .args_type = "device:B,id:s?,name:s?",
- },
- {
- .name = "drive-mirror",
- .args_type = "sync:s,device:B,target:s,speed:i?,mode:s?,format:s?,"
- "node-name:s?,replaces:s?,"
- "on-source-error:s?,on-target-error:s?,"
- "unmap:b?,"
- "granularity:i?,buf-size:i?",
- },
- {
- .name = "change-backing-file",
- .args_type = "device:s,image-node-name:s,backing-file:s",
- },
- {
- .name = "balloon",
- .args_type = "value:M",
- },
- {
- .name = "set_link",
- .args_type = "name:s,up:b",
- },
- {
- .name = "getfd",
- .args_type = "fdname:s",
- .params = "getfd name",
- .help = "receive a file descriptor via SCM rights and assign it a name",
- },
- {
- .name = "closefd",
- .args_type = "fdname:s",
- .params = "closefd name",
- .help = "close a file descriptor previously passed via SCM rights",
- },
- {
- .name = "add-fd",
- .args_type = "fdset-id:i?,opaque:s?",
- .params = "add-fd fdset-id opaque",
- .help = "Add a file descriptor, that was passed via SCM rights, to an fd set",
- },
- {
- .name = "remove-fd",
- .args_type = "fdset-id:i,fd:i?",
- .params = "remove-fd fdset-id fd",
- .help = "Remove a file descriptor from an fd set",
- },
- {
- .name = "query-fdsets",
- .args_type = "",
- .help = "Return information describing all fd sets",
- },
- {
- .name = "block_passwd",
- .args_type = "device:s?,node-name:s?,password:s",
- },
- {
- .name = "block_set_io_throttle",
- .args_type = "device:B,bps:l,bps_rd:l,bps_wr:l,iops:l,iops_rd:l,iops_wr:l,bps_max:l?,bps_rd_max:l?,bps_wr_max:l?,iops_max:l?,iops_rd_max:l?,iops_wr_max:l?,iops_size:l?,group:s?",
- },
- {
- .name = "set_password",
- .args_type = "protocol:s,password:s,connected:s?",
- },
- {
- .name = "expire_password",
- .args_type = "protocol:s,time:s",
- },
- {
- .name = "add_client",
- .args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
- },
- {
- .name = "qmp_capabilities",
- .args_type = "",
- .help = "enable QMP capabilities",
- },
- {
- .name = "human-monitor-command",
- .args_type = "command-line:s,cpu-index:i?",
- },
- {
- .name = "query-version",
- .args_type = "",
- },
- {
- .name = "query-commands",
- .args_type = "",
- },
- {
- .name = "query-events",
- .args_type = "",
- },
- {
- .name = "query-qmp-schema",
- .args_type = "",
- },
- {
- .name = "query-chardev",
- .args_type = "",
- },
- {
- .name = "query-chardev-backends",
- .args_type = "",
- },
- {
- .name = "query-block",
- .args_type = "",
- },
- {
- .name = "query-blockstats",
- .args_type = "query-nodes:b?",
- },
- {
- .name = "query-cpus",
- .args_type = "",
- },
- {
- .name = "query-iothreads",
- .args_type = "",
- },
- {
- .name = "query-pci",
- .args_type = "",
- },
- {
- .name = "query-kvm",
- .args_type = "",
- },
- {
- .name = "query-status",
- .args_type = "",
- },
- {
- .name = "query-mice",
- .args_type = "",
- },
- {
- .name = "query-vnc",
- .args_type = "",
- },
- {
- .name = "query-vnc-servers",
- .args_type = "",
- },
-#if defined(CONFIG_SPICE)
- {
- .name = "query-spice",
- .args_type = "",
- },
-#endif
- {
- .name = "query-name",
- .args_type = "",
- },
- {
- .name = "query-uuid",
- .args_type = "",
- },
- {
- .name = "query-command-line-options",
- .args_type = "option:s?",
- },
- {
- .name = "query-migrate",
- .args_type = "",
- },
- {
- .name = "migrate-set-capabilities",
- .args_type = "capabilities:q",
- .params = "capability:s,state:b",
- },
- {
- .name = "query-migrate-capabilities",
- .args_type = "",
- },
- {
- .name = "migrate-set-parameters",
- .args_type =
- "compress-level:i?,compress-threads:i?,decompress-threads:i?",
- },
- {
- .name = "query-migrate-parameters",
- .args_type = "",
- },
- {
- .name = "query-balloon",
- .args_type = "",
- },
-
- {
- .name = "query-block-jobs",
- .args_type = "",
- },
-
- {
- .name = "qom-list",
- .args_type = "path:s",
- },
-
- {
- .name = "qom-set",
- .args_type = "path:s,property:s,value:q",
- },
-
- {
- .name = "qom-get",
- .args_type = "path:s,property:s",
- },
-
- {
- .name = "nbd-server-start",
- .args_type = "addr:q",
- },
- {
- .name = "nbd-server-add",
- .args_type = "device:B,writable:b?",
- },
- {
- .name = "nbd-server-stop",
- .args_type = "",
- },
-
- {
- .name = "change-vnc-password",
- .args_type = "password:s",
- },
- {
- .name = "qom-list-types",
- .args_type = "implements:s?,abstract:b?",
- },
-
- {
- .name = "device-list-properties",
- .args_type = "typename:s",
- },
-
- {
- .name = "query-machines",
- .args_type = "",
- },
-
- {
- .name = "query-cpu-definitions",
- .args_type = "",
- },
-
- {
- .name = "query-target",
- .args_type = "",
- },
-
- {
- .name = "query-tpm",
- .args_type = "",
- },
- {
- .name = "query-tpm-models",
- .args_type = "",
- },
- {
- .name = "query-tpm-types",
- .args_type = "",
- },
- {
- .name = "chardev-add",
- .args_type = "id:s,backend:q",
- },
- {
- .name = "chardev-remove",
- .args_type = "id:s",
- },
- {
- .name = "query-rx-filter",
- .args_type = "name:s?",
- },
- {
- .name = "blockdev-add",
- .args_type = "options:q",
- },
- {
- .name = "query-named-block-nodes",
- .args_type = "",
- },
- {
- .name = "query-memdev",
- .args_type = "",
- },
- {
- .name = "query-memory-devices",
- .args_type = "",
- },
- {
- .name = "query-acpi-ospm-status",
- .args_type = "",
- },
-#if defined TARGET_I386
- {
- .name = "rtc-reset-reinjection",
- .args_type = "",
- },
-#endif
- {
- .name = "trace-event-get-state",
- .args_type = "name:s",
- },
- {
- .name = "trace-event-set-state",
- .args_type = "name:s,enable:b,ignore-unavailable:b?",
- },
- {
- .name = "x-input-send-event",
- .args_type = "console:i?,events:q",
- },
- {
- .name = "block-set-write-threshold",
- .args_type = "node-name:s,write-threshold:l",
- },
- {
- .name = "query-rocker",
- .args_type = "name:s",
- },
- {
- .name = "query-rocker-ports",
- .args_type = "name:s",
- },
- {
- .name = "query-rocker-of-dpa-flows",
- .args_type = "name:s,tbl-id:i?",
- },
- {
- .name = "query-rocker-of-dpa-groups",
- .args_type = "name:s,type:i?",
- },
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 21/36] misc: spelling
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (19 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 20/36] qmp: remove old qmp-commands table marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 16:08 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 22/36] qmp: teach qmp_dispatch() to take a pre-filled QDict marcandre.lureau
` (16 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/monitor.c b/monitor.c
index 4deef29..25f9608 100644
--- a/monitor.c
+++ b/monitor.c
@@ -306,7 +306,7 @@ static void monitor_flush_locked(Monitor *mon)
return;
}
if (rc > 0) {
- /* partinal write */
+ /* partial write */
QString *tmp = qstring_from_str(buf + rc);
QDECREF(mon->outbuf);
mon->outbuf = tmp;
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 22/36] qmp: teach qmp_dispatch() to take a pre-filled QDict
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (20 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 21/36] misc: spelling marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 23/36] qmp: use a return callback for the command reply marcandre.lureau
` (15 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
In order to prepare for the async support, give an optionnal qdict for
the dispatch call to be used for the reply. The qemu monitor will have
the request "id" pre-filled.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/dispatch.h | 2 +-
monitor.c | 24 ++++++++++--------------
qapi/qmp-dispatch.c | 5 ++---
qga/main.c | 2 +-
tests/test-qmp-commands.c | 6 +++---
5 files changed, 17 insertions(+), 22 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index e389697..96de3bf 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -44,7 +44,7 @@ typedef struct QmpCommand
void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
QmpCommand *qmp_find_command(const char *name);
-QObject *qmp_dispatch(QObject *request);
+QObject *qmp_dispatch(QObject *request, QDict *rsp);
void qmp_disable_command(const char *name);
void qmp_enable_command(const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);
diff --git a/monitor.c b/monitor.c
index 25f9608..d7ee509 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3572,12 +3572,13 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
{
- QObject *req, *rsp = NULL, *id = NULL;
- QDict *qdict = NULL;
+ QObject *req, *rsp, *id = NULL;
+ QDict *qdict, *rqdict = qdict_new();
const char *cmd_name;
Monitor *mon = cur_mon;
Error *err = NULL;
+ rsp = QOBJECT(rqdict);
req = json_parser_parse_err(tokens, NULL, &err);
if (err || !req || qobject_type(req) != QTYPE_QDICT) {
if (!err) {
@@ -3592,8 +3593,11 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
}
id = qdict_get(qdict, "id");
- qobject_incref(id);
- qdict_del(qdict, "id");
+ if (id) {
+ qobject_incref(id);
+ qdict_del(qdict, "id");
+ qdict_put_obj(rqdict, "id", id);
+ }
cmd_name = qdict_get_str(qdict, "execute");
trace_handle_qmp_command(mon, cmd_name);
@@ -3602,26 +3606,18 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
- rsp = qmp_dispatch(req);
+ rsp = qmp_dispatch(req, rqdict);
err_out:
if (err) {
- qdict = qdict_new();
- qdict_put_obj(qdict, "error", qmp_build_error_object(err));
+ qdict_put_obj(rqdict, "error", qmp_build_error_object(err));
error_free(err);
- rsp = QOBJECT(qdict);
}
if (rsp) {
- if (id) {
- qdict_put_obj(qobject_to_qdict(rsp), "id", id);
- id = NULL;
- }
-
monitor_json_emitter(mon, rsp);
}
- qobject_decref(id);
qobject_decref(rsp);
qobject_decref(req);
}
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 7bcc860..d2ae5f0 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -118,15 +118,14 @@ QObject *qmp_build_error_object(Error *err)
error_get_pretty(err));
}
-QObject *qmp_dispatch(QObject *request)
+QObject *qmp_dispatch(QObject *request, QDict *rsp)
{
Error *err = NULL;
QObject *ret;
- QDict *rsp;
ret = do_qmp_dispatch(request, &err);
- rsp = qdict_new();
+ rsp = rsp ?: qdict_new();
if (err) {
qdict_put_obj(rsp, "error", qmp_build_error_object(err));
error_free(err);
diff --git a/qga/main.c b/qga/main.c
index d8e063a..bfcde0b 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -553,7 +553,7 @@ static void process_command(GAState *s, QDict *req)
g_assert(req);
g_debug("processing command");
- rsp = qmp_dispatch(QOBJECT(req));
+ rsp = qmp_dispatch(QOBJECT(req), NULL);
if (rsp) {
ret = send_response(s, rsp);
if (ret) {
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 886de98..068db21 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -85,7 +85,7 @@ static void test_dispatch_cmd(void)
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
- resp = qmp_dispatch(QOBJECT(req));
+ resp = qmp_dispatch(QOBJECT(req), NULL);
assert(resp != NULL);
assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -101,7 +101,7 @@ static void test_dispatch_cmd_error(void)
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
- resp = qmp_dispatch(QOBJECT(req));
+ resp = qmp_dispatch(QOBJECT(req), NULL);
assert(resp != NULL);
assert(qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -115,7 +115,7 @@ static QObject *test_qmp_dispatch(QDict *req)
QDict *resp;
QObject *ret;
- resp_obj = qmp_dispatch(QOBJECT(req));
+ resp_obj = qmp_dispatch(QOBJECT(req), NULL);
assert(resp_obj);
resp = qobject_to_qdict(resp_obj);
assert(resp && !qdict_haskey(resp, "error"));
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 23/36] qmp: use a return callback for the command reply
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (21 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 22/36] qmp: teach qmp_dispatch() to take a pre-filled QDict marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 24/36] qmp: add QmpClient marcandre.lureau
` (14 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Introduce QmpDispatchReturn, a callback called when a command reply is
ready to be sent. Future patches will extend the concept to allow async
replies.
QmpReturn and associated functions is used internally for sync
fonctions, but will be the basis of a async context (the dispatch return
callback and the top response dict).
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/dispatch.h | 14 +++++++++++--
monitor.c | 13 ++++++++----
qapi/qmp-dispatch.c | 51 ++++++++++++++++++++++++++++++++++-----------
qga/main.c | 22 +++++++++----------
tests/test-qmp-commands.c | 42 ++++++++++++++++++++-----------------
5 files changed, 94 insertions(+), 48 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 96de3bf..b62acba 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -18,6 +18,14 @@
#include "qapi/qmp/qdict.h"
#include "qapi/error.h"
+typedef void (QmpDispatchReturn) (QObject *rsp, void *opaque);
+
+typedef struct QmpReturn {
+ QDict *rsp;
+ QmpDispatchReturn *return_cb;
+ void *opaque;
+} QmpReturn;
+
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
typedef enum QmpCommandType
@@ -44,7 +52,8 @@ typedef struct QmpCommand
void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
QmpCommand *qmp_find_command(const char *name);
-QObject *qmp_dispatch(QObject *request, QDict *rsp);
+void qmp_dispatch(QObject *request, QDict *rsp,
+ QmpDispatchReturn *return_cb, void *opaque);
void qmp_disable_command(const char *name);
void qmp_enable_command(const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);
@@ -53,6 +62,7 @@ bool qmp_has_success_response(const QmpCommand *cmd);
QObject *qmp_build_error_object(Error *err);
typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
void qmp_for_each_command(qmp_cmd_callback_fn fn, void *opaque);
+void qmp_return(QmpReturn *qret, QObject *cmd_rsp);
+void qmp_return_error(QmpReturn *qret, Error *err);
#endif
-
diff --git a/monitor.c b/monitor.c
index d7ee509..677061d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3570,6 +3570,13 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
return input_dict;
}
+static void qmp_dispatch_return(QObject *rsp, void *opaque)
+{
+ Monitor *mon = opaque;
+
+ monitor_json_emitter(mon, rsp);
+}
+
static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
{
QObject *req, *rsp, *id = NULL;
@@ -3606,15 +3613,13 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
- rsp = qmp_dispatch(req, rqdict);
+ qmp_dispatch(req, rqdict, qmp_dispatch_return, mon);
+ rsp = NULL;
err_out:
if (err) {
qdict_put_obj(rqdict, "error", qmp_build_error_object(err));
error_free(err);
- }
-
- if (rsp) {
monitor_json_emitter(mon, rsp);
}
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index d2ae5f0..263ab65 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -60,7 +60,7 @@ static QDict *qmp_dispatch_check_obj(const QObject *request, Error **errp)
return dict;
}
-static QObject *do_qmp_dispatch(QObject *request, Error **errp)
+static QObject *do_qmp_dispatch(QObject *request, QmpReturn *qret, Error **errp)
{
Error *local_err = NULL;
const char *command;
@@ -118,23 +118,50 @@ QObject *qmp_build_error_object(Error *err)
error_get_pretty(err));
}
-QObject *qmp_dispatch(QObject *request, QDict *rsp)
+static void do_qmp_return(QmpReturn *qret)
+{
+ QDict *rsp = qret->rsp;
+
+ qret->return_cb(QOBJECT(rsp), qret->opaque);
+
+ qobject_decref(QOBJECT(rsp));
+ g_free(qret);
+}
+
+void qmp_return(QmpReturn *qret, QObject *cmd_rsp)
+{
+ qdict_put_obj(qret->rsp, "return", cmd_rsp);
+
+ do_qmp_return(qret);
+}
+
+void qmp_return_error(QmpReturn *qret, Error *err)
+{
+ qdict_put_obj(qret->rsp, "error", qmp_build_error_object(err));
+ error_free(err);
+
+ do_qmp_return(qret);
+}
+
+void qmp_dispatch(QObject *request, QDict *rsp,
+ QmpDispatchReturn *return_cb, void *opaque)
{
Error *err = NULL;
+ QmpReturn *qret = g_new0(QmpReturn, 1);
QObject *ret;
- ret = do_qmp_dispatch(request, &err);
+ assert(return_cb);
+
+ qret->rsp = rsp ?: qdict_new();
+ qret->return_cb = return_cb;
+ qret->opaque = opaque;
+
+ ret = do_qmp_dispatch(request, qret, &err);
- rsp = rsp ?: qdict_new();
if (err) {
- qdict_put_obj(rsp, "error", qmp_build_error_object(err));
- error_free(err);
+ assert(!ret);
+ qmp_return_error(qret, err);
} else if (ret) {
- qdict_put_obj(rsp, "return", ret);
- } else {
- QDECREF(rsp);
- return NULL;
+ qmp_return(qret, ret);
}
-
- return QOBJECT(rsp);
}
diff --git a/qga/main.c b/qga/main.c
index bfcde0b..21dba8f 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -546,21 +546,21 @@ static int send_response(GAState *s, QObject *payload)
return 0;
}
-static void process_command(GAState *s, QDict *req)
+static void dispatch_return_cb(QObject *rsp, void *opaque)
{
- QObject *rsp = NULL;
- int ret;
+ GAState *s = opaque;
+ int ret = send_response(s, rsp);
+
+ if (ret) {
+ g_warning("error sending response: %s", strerror(ret));
+ }
+}
+static void process_command(GAState *s, QDict *req)
+{
g_assert(req);
g_debug("processing command");
- rsp = qmp_dispatch(QOBJECT(req), NULL);
- if (rsp) {
- ret = send_response(s, rsp);
- if (ret) {
- g_warning("error sending response: %s", strerror(ret));
- }
- qobject_decref(rsp);
- }
+ qmp_dispatch(QOBJECT(req), NULL, dispatch_return_cb, s);
}
/* handle requests/control events coming in over the channel */
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 068db21..64d26af 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -76,53 +76,57 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
return ret;
}
+static void dispatch_cmd_return(QObject *resp, void *opaque)
+{
+ assert(resp != NULL);
+ assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
+}
/* test commands with no input and no return value */
static void test_dispatch_cmd(void)
{
QDict *req = qdict_new();
- QObject *resp;
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
- resp = qmp_dispatch(QOBJECT(req), NULL);
- assert(resp != NULL);
- assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
+ qmp_dispatch(QOBJECT(req), NULL, dispatch_cmd_return, NULL);
- qobject_decref(resp);
QDECREF(req);
}
+static void dispatch_cmd_error_return(QObject *resp, void *opaque)
+{
+ assert(resp != NULL);
+ assert(qdict_haskey(qobject_to_qdict(resp), "error"));
+}
+
/* test commands that return an error due to invalid parameters */
static void test_dispatch_cmd_error(void)
{
QDict *req = qdict_new();
- QObject *resp;
qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
- resp = qmp_dispatch(QOBJECT(req), NULL);
- assert(resp != NULL);
- assert(qdict_haskey(qobject_to_qdict(resp), "error"));
+ qmp_dispatch(QOBJECT(req), NULL, dispatch_cmd_error_return, NULL);
- qobject_decref(resp);
QDECREF(req);
}
-static QObject *test_qmp_dispatch(QDict *req)
-{
- QObject *resp_obj;
- QDict *resp;
- QObject *ret;
+static QObject *ret;
- resp_obj = qmp_dispatch(QOBJECT(req), NULL);
- assert(resp_obj);
- resp = qobject_to_qdict(resp_obj);
+static void qmp_dispatch_return(QObject *resp_obj, void *opaque)
+{
+ QDict *resp = qobject_to_qdict(resp_obj);
assert(resp && !qdict_haskey(resp, "error"));
ret = qdict_get(resp, "return");
assert(ret);
qobject_incref(ret);
- qobject_decref(resp_obj);
+}
+
+static QObject *test_qmp_dispatch(QDict *req)
+{
+ qmp_dispatch(QOBJECT(req), NULL, qmp_dispatch_return, NULL);
+
return ret;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 24/36] qmp: add QmpClient
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (22 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 23/36] qmp: use a return callback for the command reply marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 25/36] qmp: introduce async command type marcandre.lureau
` (13 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Add a new QmpClient structure holding the dispatch return callback
and the list of pending QmpReturns.
When a client disconnects, call qmp_client_destroy(). This will remove
all pending returns from the client list, and prevent a reply from being
sent later to new clients. That way clients will only receive reply they
expect, and not one from a previous client.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/dispatch.h | 20 +++++++++++++++-----
monitor.c | 9 ++++++---
qapi/qmp-dispatch.c | 33 +++++++++++++++++++++++++++------
qga/main.c | 10 ++++++----
tests/test-qmp-commands.c | 31 ++++++++++++++++++++++---------
5 files changed, 76 insertions(+), 27 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index b62acba..747fff9 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -18,14 +18,23 @@
#include "qapi/qmp/qdict.h"
#include "qapi/error.h"
-typedef void (QmpDispatchReturn) (QObject *rsp, void *opaque);
+typedef struct QmpClient QmpClient;
+
+typedef void (QmpDispatchReturn) (QmpClient *client, QObject *rsp);
typedef struct QmpReturn {
QDict *rsp;
- QmpDispatchReturn *return_cb;
- void *opaque;
+ QmpClient *client;
+
+ QLIST_ENTRY(QmpReturn) link;
} QmpReturn;
+struct QmpClient {
+ QmpDispatchReturn *return_cb;
+
+ QLIST_HEAD(, QmpReturn) pending;
+};
+
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
typedef enum QmpCommandType
@@ -52,8 +61,9 @@ typedef struct QmpCommand
void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
QmpCommand *qmp_find_command(const char *name);
-void qmp_dispatch(QObject *request, QDict *rsp,
- QmpDispatchReturn *return_cb, void *opaque);
+void qmp_client_init(QmpClient *client, QmpDispatchReturn *return_cb);
+void qmp_client_destroy(QmpClient *client);
+void qmp_dispatch(QmpClient *client, QObject *request, QDict *rsp);
void qmp_disable_command(const char *name);
void qmp_enable_command(const char *name);
bool qmp_command_is_enabled(const QmpCommand *cmd);
diff --git a/monitor.c b/monitor.c
index 677061d..ca3db31 100644
--- a/monitor.c
+++ b/monitor.c
@@ -173,6 +173,7 @@ typedef struct {
* mode.
*/
bool in_command_mode; /* are we in command mode? */
+ QmpClient client;
} MonitorQMP;
/*
@@ -3570,9 +3571,9 @@ static QDict *qmp_check_input_obj(QObject *input_obj, Error **errp)
return input_dict;
}
-static void qmp_dispatch_return(QObject *rsp, void *opaque)
+static void qmp_dispatch_return(QmpClient *client, QObject *rsp)
{
- Monitor *mon = opaque;
+ Monitor *mon = container_of(client, Monitor, qmp.client);
monitor_json_emitter(mon, rsp);
}
@@ -3613,7 +3614,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
- qmp_dispatch(req, rqdict, qmp_dispatch_return, mon);
+ qmp_dispatch(&mon->qmp.client, req, rqdict);
rsp = NULL;
err_out:
@@ -3714,6 +3715,7 @@ static void monitor_qmp_event(void *opaque, int event)
json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
mon_refcount--;
monitor_fdsets_cleanup();
+ qmp_client_destroy(&mon->qmp.client);
break;
}
}
@@ -3848,6 +3850,7 @@ void monitor_init(CharDriverState *chr, int flags)
monitor_qmp_event, mon);
qemu_chr_fe_set_echo(chr, true);
json_message_parser_init(&mon->qmp.parser, handle_qmp_command);
+ qmp_client_init(&mon->qmp.client, qmp_dispatch_return);
} else {
qemu_chr_add_handlers(chr, monitor_can_read, monitor_read,
monitor_event, mon);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 263ab65..d2cc300 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -121,9 +121,13 @@ QObject *qmp_build_error_object(Error *err)
static void do_qmp_return(QmpReturn *qret)
{
QDict *rsp = qret->rsp;
+ QmpClient *client = qret->client;
- qret->return_cb(QOBJECT(rsp), qret->opaque);
+ if (client) {
+ client->return_cb(client, QOBJECT(rsp));
+ }
+ QLIST_REMOVE(qret, link);
qobject_decref(QOBJECT(rsp));
g_free(qret);
}
@@ -143,25 +147,42 @@ void qmp_return_error(QmpReturn *qret, Error *err)
do_qmp_return(qret);
}
-void qmp_dispatch(QObject *request, QDict *rsp,
- QmpDispatchReturn *return_cb, void *opaque)
+void qmp_client_init(QmpClient *client, QmpDispatchReturn *return_cb)
+{
+ client->return_cb = return_cb;
+ QLIST_INIT(&client->pending);
+}
+
+void qmp_client_destroy(QmpClient *client)
+{
+ QmpReturn *ret, *next;
+
+ QLIST_FOREACH_SAFE(ret, &client->pending, link, next) {
+ ret->client = NULL;
+ QLIST_REMOVE(ret, link);
+ }
+}
+
+void qmp_dispatch(QmpClient *client, QObject *request, QDict *rsp)
{
Error *err = NULL;
QmpReturn *qret = g_new0(QmpReturn, 1);
QObject *ret;
- assert(return_cb);
+ assert(client);
qret->rsp = rsp ?: qdict_new();
- qret->return_cb = return_cb;
- qret->opaque = opaque;
+ qret->client = client;
+ QLIST_INSERT_HEAD(&client->pending, qret, link);
ret = do_qmp_dispatch(request, qret, &err);
if (err) {
assert(!ret);
qmp_return_error(qret, err);
+ return;
} else if (ret) {
qmp_return(qret, ret);
+ return;
}
}
diff --git a/qga/main.c b/qga/main.c
index 21dba8f..9cd9764 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -93,6 +93,7 @@ struct GAState {
#endif
gchar *pstate_filepath;
GAPersistentState pstate;
+ QmpClient client;
};
struct GAState *ga_state;
@@ -546,9 +547,9 @@ static int send_response(GAState *s, QObject *payload)
return 0;
}
-static void dispatch_return_cb(QObject *rsp, void *opaque)
+static void dispatch_return_cb(QmpClient *client, QObject *rsp)
{
- GAState *s = opaque;
+ GAState *s = container_of(client, GAState, client);
int ret = send_response(s, rsp);
if (ret) {
@@ -560,7 +561,7 @@ static void process_command(GAState *s, QDict *req)
{
g_assert(req);
g_debug("processing command");
- qmp_dispatch(QOBJECT(req), NULL, dispatch_return_cb, s);
+ qmp_dispatch(&ga_state->client, QOBJECT(req), NULL);
}
/* handle requests/control events coming in over the channel */
@@ -1293,6 +1294,7 @@ static int run_agent(GAState *s, GAConfig *config)
ga_command_state_init_all(s->command_state);
json_message_parser_init(&s->parser, process_event);
ga_state = s;
+ qmp_client_init(&s->client, dispatch_return_cb);
#ifndef _WIN32
if (!register_signal_handlers()) {
g_critical("failed to register signal handlers");
@@ -1390,7 +1392,7 @@ end:
g_list_foreach(config->blacklist, free_blacklist_entry, NULL);
g_free(s->pstate_filepath);
g_free(s->state_filepath_isfrozen);
-
+ qmp_client_destroy(&s->client);
if (config->daemonize) {
unlink(config->pid_filepath);
}
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 64d26af..4f49a6e 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -76,7 +76,7 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
return ret;
}
-static void dispatch_cmd_return(QObject *resp, void *opaque)
+static void dispatch_cmd_return(QmpClient *client, QObject *resp)
{
assert(resp != NULL);
assert(!qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -85,16 +85,20 @@ static void dispatch_cmd_return(QObject *resp, void *opaque)
/* test commands with no input and no return value */
static void test_dispatch_cmd(void)
{
+ QmpClient client;
QDict *req = qdict_new();
- qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
+ qmp_client_init(&client, dispatch_cmd_return);
- qmp_dispatch(QOBJECT(req), NULL, dispatch_cmd_return, NULL);
+ qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd")));
+ qmp_dispatch(&client, QOBJECT(req), NULL);
QDECREF(req);
+
+ qmp_client_destroy(&client);
}
-static void dispatch_cmd_error_return(QObject *resp, void *opaque)
+static void dispatch_cmd_error_return(QmpClient *client, QObject *resp)
{
assert(resp != NULL);
assert(qdict_haskey(qobject_to_qdict(resp), "error"));
@@ -103,18 +107,22 @@ static void dispatch_cmd_error_return(QObject *resp, void *opaque)
/* test commands that return an error due to invalid parameters */
static void test_dispatch_cmd_error(void)
{
+ QmpClient client;
QDict *req = qdict_new();
- qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
+ qmp_client_init(&client, dispatch_cmd_error_return);
- qmp_dispatch(QOBJECT(req), NULL, dispatch_cmd_error_return, NULL);
+ qdict_put_obj(req, "execute", QOBJECT(qstring_from_str("user_def_cmd2")));
+ qmp_dispatch(&client, QOBJECT(req), NULL);
QDECREF(req);
+
+ qmp_client_destroy(&client);
}
static QObject *ret;
-static void qmp_dispatch_return(QObject *resp_obj, void *opaque)
+static void qmp_dispatch_return(QmpClient *client, QObject *resp_obj)
{
QDict *resp = qobject_to_qdict(resp_obj);
assert(resp && !qdict_haskey(resp, "error"));
@@ -125,7 +133,13 @@ static void qmp_dispatch_return(QObject *resp_obj, void *opaque)
static QObject *test_qmp_dispatch(QDict *req)
{
- qmp_dispatch(QOBJECT(req), NULL, qmp_dispatch_return, NULL);
+ QmpClient client;
+
+ qmp_client_init(&client, qmp_dispatch_return);
+
+ qmp_dispatch(&client, QOBJECT(req), NULL);
+
+ qmp_client_destroy(&client);
return ret;
}
@@ -243,7 +257,6 @@ static void test_dealloc_partial(void)
qapi_free_UserDefTwo(ud2);
}
-
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 25/36] qmp: introduce async command type
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (23 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 24/36] qmp: add QmpClient marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 26/36] qmp: check that async command have an 'id' marcandre.lureau
` (12 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Learn a new type of command, QmpCommandFuncAsync. They can return later
thanks to QmpReturn. This commit introduces the new types and register
functions.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/qapi/qmp/dispatch.h | 5 +++++
qapi/qmp-dispatch.c | 3 +++
qapi/qmp-registry.c | 26 ++++++++++++++++++++++----
3 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 747fff9..e45ab9f 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -36,10 +36,12 @@ struct QmpClient {
};
typedef void (QmpCommandFunc)(QDict *, QObject **, Error **);
+typedef void (QmpCommandFuncAsync)(QDict *, QmpReturn *);
typedef enum QmpCommandType
{
QCT_NORMAL,
+ QCT_ASYNC,
} QmpCommandType;
typedef enum QmpCommandOptions
@@ -53,6 +55,7 @@ typedef struct QmpCommand
const char *name;
QmpCommandType type;
QmpCommandFunc *fn;
+ QmpCommandFuncAsync *fn_async;
QmpCommandOptions options;
QTAILQ_ENTRY(QmpCommand) node;
bool enabled;
@@ -60,6 +63,8 @@ typedef struct QmpCommand
void qmp_register_command(const char *name, QmpCommandFunc *fn,
QmpCommandOptions options);
+void qmp_register_async_command(const char *name, QmpCommandFuncAsync *fn,
+ QmpCommandOptions options);
QmpCommand *qmp_find_command(const char *name);
void qmp_client_init(QmpClient *client, QmpDispatchReturn *return_cb);
void qmp_client_destroy(QmpClient *client);
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index d2cc300..83ecab5 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -104,6 +104,9 @@ static QObject *do_qmp_dispatch(QObject *request, QmpReturn *qret, Error **errp)
ret = QOBJECT(qdict_new());
}
break;
+ case QCT_ASYNC:
+ cmd->fn_async(args, qret);
+ break;
}
QDECREF(args);
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 3e4498a..90f6a8c 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -19,17 +19,35 @@
static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
QTAILQ_HEAD_INITIALIZER(qmp_commands);
-void qmp_register_command(const char *name, QmpCommandFunc *fn,
- QmpCommandOptions options)
+static QmpCommand *qmp_command_new(const char *name,
+ QmpCommandOptions options)
{
QmpCommand *cmd = g_malloc0(sizeof(*cmd));
cmd->name = name;
- cmd->type = QCT_NORMAL;
- cmd->fn = fn;
cmd->enabled = true;
cmd->options = options;
QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node);
+
+ return cmd;
+}
+
+void qmp_register_command(const char *name, QmpCommandFunc *fn,
+ QmpCommandOptions options)
+{
+ QmpCommand *cmd = qmp_command_new(name, options);
+
+ cmd->type = QCT_NORMAL;
+ cmd->fn = fn;
+}
+
+void qmp_register_async_command(const char *name, QmpCommandFuncAsync *fn,
+ QmpCommandOptions options)
+{
+ QmpCommand *cmd = qmp_command_new(name, options);
+
+ cmd->type = QCT_ASYNC;
+ cmd->fn_async = fn;
}
QmpCommand *qmp_find_command(const char *name)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 26/36] qmp: check that async command have an 'id'
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (24 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 25/36] qmp: introduce async command type marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 27/36] scripts: learn 'async' qapi commands marcandre.lureau
` (11 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
The async support mandates that request have an 'id' (see documentation
in following patch).
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/qmp-dispatch.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 83ecab5..73ba3ad 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -105,6 +105,11 @@ static QObject *do_qmp_dispatch(QObject *request, QmpReturn *qret, Error **errp)
}
break;
case QCT_ASYNC:
+ if (!qdict_haskey(qret->rsp, "id")) {
+ error_setg(errp, "An async command requires an 'id'");
+ break;
+ }
+
cmd->fn_async(args, qret);
break;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 27/36] scripts: learn 'async' qapi commands
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (25 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 26/36] qmp: check that async command have an 'id' marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 28/36] scripts: ensure -async commands are declared async marcandre.lureau
` (10 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Commands with the 'async' key will be registered as async type (see
previous commit), and will allow a synchronous (in command cb) or
asynchronous return (when ready, in idle etc).
Ex:
{ 'command': 'foo-async, 'data': {'arg': 'str'}, async: true }
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/introspect.json | 2 +-
scripts/qapi-commands.py | 133 +++++++++++++++++++++++++++++++++--------
scripts/qapi-introspect.py | 7 ++-
scripts/qapi.py | 14 +++--
tests/Makefile | 1 +
tests/qapi-schema/async.err | 0
tests/qapi-schema/async.exit | 1 +
tests/qapi-schema/async.json | 1 +
tests/qapi-schema/async.out | 5 ++
tests/qapi-schema/test-qapi.py | 6 +-
10 files changed, 133 insertions(+), 37 deletions(-)
create mode 100644 tests/qapi-schema/async.err
create mode 100644 tests/qapi-schema/async.exit
create mode 100644 tests/qapi-schema/async.json
create mode 100644 tests/qapi-schema/async.out
diff --git a/qapi/introspect.json b/qapi/introspect.json
index 5a3bd3e..5b878ff 100644
--- a/qapi/introspect.json
+++ b/qapi/introspect.json
@@ -259,7 +259,7 @@
# Since: 2.5
##
{ 'struct': 'SchemaInfoCommand',
- 'data': { 'arg-type': 'str', 'ret-type': 'str' } }
+ 'data': { 'arg-type': 'str', 'ret-type': 'str', 'async': 'bool' } }
##
# @SchemaInfoEvent
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index 4db1ae3..b0b922d 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -16,18 +16,30 @@ from qapi import *
import re
-def gen_command_decl(name, arg_type, box, ret_type):
- return mcgen('''
+def gen_command_decl(name, arg_type, box, ret_type, async):
+ if async:
+ extra = "QmpReturn *qret"
+ else:
+ extra = 'Error **errp'
+ if async:
+ return mcgen('''
+void qmp_%(name)s(%(params)s);
+void qmp_%(name)s_return(QmpReturn *qret%(c_type)s);
+''',
+ c_type=(", " + ret_type.c_type() if ret_type else ""),
+ name=c_name(name),
+ params=gen_params(arg_type, box, extra))
+ else:
+
+ return mcgen('''
%(c_type)s qmp_%(c_name)s(%(params)s);
''',
- c_type=(ret_type and ret_type.c_type()) or 'void',
- c_name=c_name(name),
- params=gen_params(arg_type, box, 'Error **errp'))
+ c_type=(ret_type and ret_type.c_type()) or 'void',
+ c_name=c_name(name),
+ params=gen_params(arg_type, box, extra))
-def gen_call(name, arg_type, box, ret_type):
- ret = ''
-
+def gen_argstr(arg_type, box):
argstr = ''
if box:
argstr = 'arg, '
@@ -38,6 +50,13 @@ def gen_call(name, arg_type, box, ret_type):
argstr += 'has_%s, ' % c_name(memb.name)
argstr += '%s, ' % c_name(memb.name)
+ return argstr
+
+
+def gen_call(name, arg_type, box, ret_type):
+ ret = ''
+
+ argstr = gen_argstr(arg_type, box)
lhs = ''
if ret_type:
lhs = 'retval = '
@@ -59,14 +78,57 @@ qmp_marshal_output_%(c_name)s(retval, ret, &err);
return ret
-def gen_marshal_vars(arg_type, box, ret_type):
+def gen_async_call(name, arg_type, box):
+ argstr = gen_argstr(arg_type, box)
+
+ push_indent()
+ ret = mcgen('''
+
+qmp_%(c_name)s(%(args)sqret);
+''',
+ c_name=c_name(name), args=argstr)
+
+ pop_indent()
+ return ret
+
+
+def gen_async_return(name, arg_type, ret_type):
+ if ret_type:
+ return mcgen('''
+void qmp_%(c_name)s_return(QmpReturn *qret, %(ret_type)s ret_in)
+{
+ Error *err = NULL;
+ QObject *ret_out = NULL;
+
+ qmp_marshal_output_%(ret_c_name)s(ret_in, &ret_out, &err);
+
+ if (err) {
+ qmp_return_error(qret, err);
+ } else {
+ qmp_return(qret, ret_out);
+ }
+}
+''',
+ c_name=c_name(name),
+ ret_type=ret_type.c_type(), ret_c_name=ret_type.c_name())
+ else:
+ return mcgen('''
+void qmp_%(c_name)s_return(QmpReturn *qret)
+{
+ qmp_return(qret, QOBJECT(qdict_new()));
+}
+''',
+ c_name=c_name(name))
+
+
+def gen_marshal_vars(arg_type, box, ret_type, async):
ret = mcgen('''
Error *err = NULL;
''')
push_indent()
- if ret_type:
+ if ret_type and not async:
ret += mcgen('''
%(c_type)s retval;
''',
@@ -178,29 +240,42 @@ out:
c_type=ret_type.c_type(), c_name=ret_type.c_name())
-def gen_marshal_proto(name):
- return 'static void qmp_marshal_%s' % c_name(name) + \
- '(QDict *args, QObject **ret, Error **errp)'
+def gen_marshal_proto(name, async):
+ if async:
+ tmpl = 'static void qmp_marshal_%s(QDict *args, QmpReturn *qret)'
+ else:
+ tmpl = 'static void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)'
+ return tmpl % c_name(name)
-def gen_marshal(name, arg_type, box, ret_type):
+def gen_marshal(name, arg_type, box, ret_type, async):
ret = mcgen('''
%(proto)s
{
''',
- proto=gen_marshal_proto(name))
+ proto=gen_marshal_proto(name, async))
- ret += gen_marshal_vars(arg_type, box, ret_type)
+ ret += gen_marshal_vars(arg_type, box, ret_type, async)
ret += gen_marshal_input_visit(arg_type, box)
- ret += gen_call(name, arg_type, box, ret_type)
+ if async:
+ ret += gen_async_call(name, arg_type, box)
+ else:
+ ret += gen_call(name, arg_type, box, ret_type)
if re.search('^ *goto out;', ret, re.MULTILINE):
ret += mcgen('''
out:
''')
- ret += mcgen('''
+ if async:
+ ret += mcgen('''
+ if (err) {
+ qmp_return_error(qret, err);
+ }
+''')
+ else:
+ ret += mcgen('''
error_propagate(errp, err);
''')
ret += gen_marshal_input_visit(arg_type, box, dealloc=True)
@@ -210,16 +285,18 @@ out:
return ret
-def gen_register_command(name, success_response):
+def gen_register_command(name, success_response, async):
push_indent()
options = 'QCO_NO_OPTIONS'
if not success_response:
options = 'QCO_NO_SUCCESS_RESP'
-
+ func = 'qmp_register_command'
+ if async:
+ func = 'qmp_register_async_command'
ret = mcgen('''
-qmp_register_command("%(name)s", qmp_marshal_%(c_name)s, %(opts)s);
+%(func)s("%(name)s", qmp_marshal_%(c_name)s, %(opts)s);
''',
- name=name, c_name=c_name(name),
+ func=func, name=name, c_name=c_name(name),
opts=options)
pop_indent()
return ret
@@ -259,15 +336,18 @@ class QAPISchemaGenCommandVisitor(QAPISchemaVisitor):
self._visited_ret_types = None
def visit_command(self, name, info, arg_type, ret_type,
- gen, success_response, box):
+ gen, success_response, box, async):
if not gen:
return
- self.decl += gen_command_decl(name, arg_type, box, ret_type)
+ self.decl += gen_command_decl(name, arg_type, box,
+ ret_type, async)
if ret_type and ret_type not in self._visited_ret_types:
self._visited_ret_types.add(ret_type)
self.defn += gen_marshal_output(ret_type)
- self.defn += gen_marshal(name, arg_type, box, ret_type)
- self._regy += gen_register_command(name, success_response)
+ if async:
+ self.defn += gen_async_return(name, arg_type, ret_type)
+ self.defn += gen_marshal(name, arg_type, box, ret_type, async)
+ self._regy += gen_register_command(name, success_response, async)
(input_file, output_dir, do_c, do_h, prefix, opts) = \
@@ -325,6 +405,7 @@ fdef.write(mcgen('''
fdecl.write(mcgen('''
#include "%(prefix)sqapi-types.h"
#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/dispatch.h"
#include "qapi/error.h"
''',
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 8023f1b..6add6a0 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -29,6 +29,8 @@ def to_json(obj, level=0):
to_json(obj[key], level + 1))
for key in sorted(obj.keys())]
ret = '{' + ', '.join(elts) + '}'
+ elif isinstance(obj, bool):
+ ret = 'true' if obj else 'false'
else:
assert False # not implemented
if level == 1:
@@ -154,12 +156,13 @@ const char %(c_name)s[] = %(c_string)s;
for m in variants.variants]})
def visit_command(self, name, info, arg_type, ret_type,
- gen, success_response, box):
+ gen, success_response, box, async):
arg_type = arg_type or self._schema.the_empty_object_type
ret_type = ret_type or self._schema.the_empty_object_type
self._gen_json(name, 'command',
{'arg-type': self._use_type(arg_type),
- 'ret-type': self._use_type(ret_type)})
+ 'ret-type': self._use_type(ret_type),
+ 'async': async})
def visit_event(self, name, info, arg_type, box):
arg_type = arg_type or self._schema.the_empty_object_type
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 2a9b6e5..96901ab 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -822,7 +822,8 @@ def check_exprs(exprs):
add_struct(expr, info)
elif 'command' in expr:
check_keys(expr_elem, 'command', [],
- ['data', 'returns', 'gen', 'success-response', 'box'])
+ ['data', 'returns', 'gen', 'success-response', 'box',
+ 'async'])
add_name(expr['command'], info, 'command')
elif 'event' in expr:
check_keys(expr_elem, 'event', [], ['data', 'box'])
@@ -911,7 +912,7 @@ class QAPISchemaVisitor(object):
pass
def visit_command(self, name, info, arg_type, ret_type,
- gen, success_response, box):
+ gen, success_response, box, async):
pass
def visit_event(self, name, info, arg_type, box):
@@ -1194,7 +1195,7 @@ class QAPISchemaAlternateType(QAPISchemaType):
class QAPISchemaCommand(QAPISchemaEntity):
def __init__(self, name, info, arg_type, ret_type, gen, success_response,
- box):
+ box, async):
QAPISchemaEntity.__init__(self, name, info)
assert not arg_type or isinstance(arg_type, str)
assert not ret_type or isinstance(ret_type, str)
@@ -1205,6 +1206,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
self.gen = gen
self.success_response = success_response
self.box = box
+ self.async = async
def check(self, schema):
if self._arg_type_name:
@@ -1219,7 +1221,8 @@ class QAPISchemaCommand(QAPISchemaEntity):
def visit(self, visitor):
visitor.visit_command(self.name, self._info,
self.arg_type, self.ret_type,
- self.gen, self.success_response, self.box)
+ self.gen, self.success_response, self.box,
+ self.async)
class QAPISchemaEvent(QAPISchemaEntity):
@@ -1399,6 +1402,7 @@ class QAPISchema(object):
data = expr.get('data')
rets = expr.get('returns')
gen = expr.get('gen', True)
+ async = expr.get('async', False)
success_response = expr.get('success-response', True)
box = expr.get('box', False)
if isinstance(data, dict):
@@ -1410,7 +1414,7 @@ class QAPISchema(object):
assert len(rets) == 1
rets = self._make_array_type(rets[0])
self._def_entity(QAPISchemaCommand(name, info, data, rets, gen,
- success_response, box))
+ success_response, box, async))
def _def_event(self, expr, info):
name = expr['event']
diff --git a/tests/Makefile b/tests/Makefile
index 7276b54..e5cdbbe 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -245,6 +245,7 @@ qapi-schema += args-member-unknown.json
qapi-schema += args-name-clash.json
qapi-schema += args-union.json
qapi-schema += args-unknown.json
+qapi-schema += async.json
qapi-schema += bad-base.json
qapi-schema += bad-data.json
qapi-schema += bad-ident.json
diff --git a/tests/qapi-schema/async.err b/tests/qapi-schema/async.err
new file mode 100644
index 0000000..e69de29
diff --git a/tests/qapi-schema/async.exit b/tests/qapi-schema/async.exit
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/tests/qapi-schema/async.exit
@@ -0,0 +1 @@
+0
diff --git a/tests/qapi-schema/async.json b/tests/qapi-schema/async.json
new file mode 100644
index 0000000..3b719e3
--- /dev/null
+++ b/tests/qapi-schema/async.json
@@ -0,0 +1 @@
+{ 'command': 'screendump-async', 'data': {'filename': 'str'}, 'async': true }
diff --git a/tests/qapi-schema/async.out b/tests/qapi-schema/async.out
new file mode 100644
index 0000000..c83bea5
--- /dev/null
+++ b/tests/qapi-schema/async.out
@@ -0,0 +1,5 @@
+object :empty
+object :obj-screendump-async-arg
+ member filename: str optional=False
+command screendump-async :obj-screendump-async-arg -> None
+ gen=True success_response=True box=False async
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 559f0e8..f99a980 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -36,11 +36,11 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor):
self._print_variants(variants)
def visit_command(self, name, info, arg_type, ret_type,
- gen, success_response, box):
+ gen, success_response, box, async):
print 'command %s %s -> %s' % \
(name, arg_type and arg_type.name, ret_type and ret_type.name)
- print ' gen=%s success_response=%s box=%s' % (gen, success_response,
- box)
+ print ' gen=%s success_response=%s box=%s%s' % \
+ (gen, success_response, box, ' async' if async else '')
def visit_event(self, name, info, arg_type, box):
print 'event %s %s' % (name, arg_type and arg_type.name)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 28/36] scripts: ensure -async commands are declared async
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (26 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 27/36] scripts: learn 'async' qapi commands marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 29/36] qapi: take 'id' from request marcandre.lureau
` (9 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
We could have arbitrary async command name, but it make sense to use a
specific name to avoid confusion.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
scripts/qapi.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 96901ab..d614673 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -1209,6 +1209,7 @@ class QAPISchemaCommand(QAPISchemaEntity):
self.async = async
def check(self, schema):
+ assert self.name.endswith("-async") == self.async
if self._arg_type_name:
self.arg_type = schema.lookup_type(self._arg_type_name)
assert isinstance(self.arg_type, QAPISchemaObjectType)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 29/36] qapi: take 'id' from request
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (27 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 28/36] scripts: ensure -async commands are declared async marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 30/36] tests: change /0.15/* tests to /qmp/* marcandre.lureau
` (8 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Copy 'id' from request to reply dict. This can be done earlier, such as
done by the monitor (because the qemu monitor may reply directly without
qmp_dispatch), but is now done as well in qmp_dispatch() as convenience
for other users such as QGA and tests.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi/qmp-dispatch.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 73ba3ad..44bd1e8 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -175,7 +175,8 @@ void qmp_dispatch(QmpClient *client, QObject *request, QDict *rsp)
{
Error *err = NULL;
QmpReturn *qret = g_new0(QmpReturn, 1);
- QObject *ret;
+ QObject *ret, *id;
+ QDict *req;
assert(client);
@@ -183,6 +184,14 @@ void qmp_dispatch(QmpClient *client, QObject *request, QDict *rsp)
qret->client = client;
QLIST_INSERT_HEAD(&client->pending, qret, link);
+ req = qobject_to_qdict(request);
+ id = qdict_get(req, "id");
+ if (id) {
+ qobject_incref(id);
+ qdict_del(req, "id");
+ qdict_put_obj(qret->rsp, "id", id);
+ }
+
ret = do_qmp_dispatch(request, qret, &err);
if (err) {
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 30/36] tests: change /0.15/* tests to /qmp/*
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (28 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 29/36] qapi: take 'id' from request marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 16:10 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 31/36] tests: add /qmp/dispatch_cmd_async test marcandre.lureau
` (7 subsequent siblings)
37 siblings, 1 reply; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Presumably 0.15 was the version it was first introduced, but
qmp keeps evolving. There is no point in having that version
has test prefix, qmp makes more sense.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/test-qmp-commands.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 4f49a6e..e9fc02d 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -261,11 +261,11 @@ int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
- g_test_add_func("/0.15/dispatch_cmd", test_dispatch_cmd);
- g_test_add_func("/0.15/dispatch_cmd_error", test_dispatch_cmd_error);
- g_test_add_func("/0.15/dispatch_cmd_io", test_dispatch_cmd_io);
- g_test_add_func("/0.15/dealloc_types", test_dealloc_types);
- g_test_add_func("/0.15/dealloc_partial", test_dealloc_partial);
+ g_test_add_func("/qmp/dispatch_cmd", test_dispatch_cmd);
+ g_test_add_func("/qmp/dispatch_cmd_error", test_dispatch_cmd_error);
+ g_test_add_func("/qmp/dispatch_cmd_io", test_dispatch_cmd_io);
+ g_test_add_func("/qmp/dealloc_types", test_dealloc_types);
+ g_test_add_func("/qmp/dealloc_partial", test_dealloc_partial);
module_call_init(MODULE_INIT_QAPI);
g_test_run();
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 31/36] tests: add /qmp/dispatch_cmd_async test
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (29 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 30/36] tests: change /0.15/* tests to /qmp/* marcandre.lureau
@ 2015-09-25 14:03 ` marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 32/36] qmp: update qmp-spec about async capability marcandre.lureau
` (6 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:03 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Check that async disaptch works.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
tests/qapi-schema/qapi-schema-test.json | 2 ++
tests/qapi-schema/qapi-schema-test.out | 5 +++
tests/test-qmp-commands.c | 61 +++++++++++++++++++++++++++++++++
3 files changed, 68 insertions(+)
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 10b8f3e..6e6b57f 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -107,6 +107,8 @@
{ 'command': 'guest-sync', 'data': { 'arg': 'any' }, 'returns': 'any' }
{ 'command': 'boxed', 'box': true, 'data': 'UserDefZero' }
{ 'command': 'boxed2', 'data': 'UserDefNativeListUnion', 'box': true }
+{ 'command': 'user-async', 'data': { 'a': 'int', '*b': 'int' },
+ 'returns': 'UserDefB', 'async': true }
# For testing integer range flattening in opts-visitor. The following schema
# corresponds to the option format:
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index b3b4cb8..4530e3d 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -48,6 +48,9 @@ object :obj-uint64List-wrapper
member data: uint64List optional=False
object :obj-uint8List-wrapper
member data: uint8List optional=False
+object :obj-user-async-arg
+ member a: int optional=False
+ member b: int optional=True
object :obj-user_def_cmd1-arg
member ud1a: UserDefOne optional=False
object :obj-user_def_cmd2-arg
@@ -196,6 +199,8 @@ command boxed2 UserDefNativeListUnion -> None
gen=True success_response=True box=True
command guest-sync :obj-guest-sync-arg -> any
gen=True success_response=True box=False
+command user-async :obj-user-async-arg -> UserDefB
+ gen=True success_response=True box=False async
command user_def_cmd None -> None
gen=True success_response=True box=False
command user_def_cmd1 :obj-user_def_cmd1-arg -> None
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index e9fc02d..dd2662d 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -76,6 +76,35 @@ __org_qemu_x_Union1 *qmp___org_qemu_x_command(__org_qemu_x_EnumList *a,
return ret;
}
+static GMainLoop *loop;
+
+static struct AsyncRet {
+ QmpReturn *qret;
+ UserDefB *ret;
+} async_ret;
+
+static gboolean qmp_user_async_idle(gpointer data)
+{
+ struct AsyncRet *ret = (struct AsyncRet *)data;
+
+ qmp_user_async_return(ret->qret, ret->ret);
+
+ g_main_loop_quit(loop);
+
+ return FALSE;
+}
+
+void qmp_user_async(int64_t a, bool has_b, int64_t b, QmpReturn *qret)
+{
+ UserDefB *ret = g_new0(UserDefB, 1);
+
+ ret->intb = a + (has_b ? b : 0);
+
+ async_ret.qret = qret;
+ async_ret.ret = ret;
+ g_idle_add(qmp_user_async_idle, &async_ret);
+}
+
static void dispatch_cmd_return(QmpClient *client, QObject *resp)
{
assert(resp != NULL);
@@ -121,12 +150,15 @@ static void test_dispatch_cmd_error(void)
}
static QObject *ret;
+static char *ret_id;
static void qmp_dispatch_return(QmpClient *client, QObject *resp_obj)
{
QDict *resp = qobject_to_qdict(resp_obj);
assert(resp && !qdict_haskey(resp, "error"));
ret = qdict_get(resp, "return");
+ g_free(ret_id);
+ ret_id = g_strdup(qdict_get_try_str(resp, "id"));
assert(ret);
qobject_incref(ret);
}
@@ -193,6 +225,34 @@ static void test_dispatch_cmd_io(void)
QDECREF(req);
}
+static void test_dispatch_cmd_async(void)
+{
+ QmpClient client;
+ QDict *dret, *req = qdict_new();
+ QDict *args = qdict_new();
+
+ loop = g_main_loop_new(NULL, FALSE);
+ qmp_client_init(&client, qmp_dispatch_return);
+
+ qdict_put(args, "a", qint_from_int(99));
+ qdict_put(req, "arguments", args);
+ qdict_put(req, "id", qstring_from_str("foo99"));
+ qdict_put(req, "execute", qstring_from_str("user-async"));
+
+ qmp_dispatch(&client, QOBJECT(req), NULL);
+
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+
+ g_assert_cmpstr(ret_id, ==, "foo99");
+ dret = qobject_to_qdict(ret);
+ assert(qdict_get_int(dret, "intb") == 99);
+ QDECREF(dret);
+
+ qmp_client_destroy(&client);
+ QDECREF(req);
+}
+
/* test generated dealloc functions for generated types */
static void test_dealloc_types(void)
{
@@ -264,6 +324,7 @@ int main(int argc, char **argv)
g_test_add_func("/qmp/dispatch_cmd", test_dispatch_cmd);
g_test_add_func("/qmp/dispatch_cmd_error", test_dispatch_cmd_error);
g_test_add_func("/qmp/dispatch_cmd_io", test_dispatch_cmd_io);
+ g_test_add_func("/qmp/dispatch_cmd_async", test_dispatch_cmd_async);
g_test_add_func("/qmp/dealloc_types", test_dealloc_types);
g_test_add_func("/qmp/dealloc_partial", test_dealloc_partial);
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 32/36] qmp: update qmp-spec about async capability
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (30 preceding siblings ...)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 31/36] tests: add /qmp/dispatch_cmd_async test marcandre.lureau
@ 2015-09-25 14:04 ` marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 33/36] monitor: add 'async' capability marcandre.lureau
` (5 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
docs/qmp/qmp-spec.txt | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/docs/qmp/qmp-spec.txt b/docs/qmp/qmp-spec.txt
index 4c28cd9..f1af7f7 100644
--- a/docs/qmp/qmp-spec.txt
+++ b/docs/qmp/qmp-spec.txt
@@ -83,9 +83,22 @@ The greeting message format is:
2.2.1 Capabilities
------------------
-As of the date this document was last revised, no server or client
-capability strings have been defined.
+- "async"
+If both the server and the client have the "async" capability, then
+the client is allowed to send async commands. An async command is a
+regular command with the "id" member mandatory (see 2.3), but the
+response may be delayed.
+
+The client must match the incoming responses with the "id" member
+associated with the command.
+
+The client is allowed to make requests while previous requests are
+pending. The responses may come out of order.
+
+When a client is disconnected, the pending commands are not
+necessarily cancelled. However, future clients will not get replies
+from commands they didn't make.
2.3 Issuing Commands
--------------------
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 33/36] monitor: add 'async' capability
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (31 preceding siblings ...)
2015-09-25 14:04 ` [Qemu-devel] [PATCH 32/36] qmp: update qmp-spec about async capability marcandre.lureau
@ 2015-09-25 14:04 ` marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 34/36] console: graphic_hw_update return true if async marcandre.lureau
` (4 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Existing clients may not handle async replies very well. In order
to avoid the potential issues, let's introduce a capability that
the client must declare in order to make use of async commands.
Eventually, client should already handle unexpected events after a
command is sent, instead of the reply. It shouldn't be much more
complicated to handle unmatched returns from previous async commands.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
monitor.c | 28 ++++++++++++++++++++++++++--
qapi-schema.json | 16 ++++++++++++++--
2 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/monitor.c b/monitor.c
index ca3db31..fda1ddd 100644
--- a/monitor.c
+++ b/monitor.c
@@ -524,8 +524,31 @@ static void monitor_qapi_event_init(void)
qmp_event_set_func_emit(monitor_qapi_event_queue);
}
-void qmp_qmp_capabilities(Error **errp)
+static void disable_async(QmpCommand *cmd, void *opaque)
{
+ if (cmd->type == QCT_ASYNC) {
+ cmd->enabled = FALSE;
+ }
+}
+
+void qmp_qmp_capabilities(bool has_capabilities,
+ QMPCapabilityList *capabilities, Error **errp)
+{
+ bool has_async = false;
+
+ if (has_capabilities) {
+ while (capabilities) {
+ if (capabilities->value == QMP_CAPABILITY_ASYNC) {
+ has_async = true;
+ }
+ capabilities = capabilities->next;
+ }
+ }
+
+ if (!has_async) {
+ qmp_for_each_command(disable_async, NULL);
+ }
+
cur_mon->qmp.in_command_mode = true;
}
@@ -3694,7 +3717,8 @@ static QObject *get_qmp_greeting(void)
assert(cmd && cmd->fn);
cmd->fn(NULL, &ver, NULL);
- return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': []}}",ver);
+ return qobject_from_jsonf("{'QMP':{'version': %p,'capabilities': ["
+ "'async']}}", ver);
}
static void monitor_qmp_event(void *opaque, int event)
diff --git a/qapi-schema.json b/qapi-schema.json
index b01de49..99c986d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -70,11 +70,23 @@
# = QMP commands
##
+# @QMPCapability
+#
+# QMP protocol capabilities
+#
+# @async: enables async messages
+#
+# Since: 2.5
+##
+{ 'enum': 'QMPCapability',
+ 'data': ['async'] }
+
+##
# @qmp_capabilities:
#
# Enable QMP capabilities.
#
-# Arguments: None.
+# @capabilities: #optional an array of QMPCapability
#
# Example:
#
@@ -84,7 +96,7 @@
# Notes: This command must be issued before issuing any other command.
#
##
-{ 'command': 'qmp_capabilities' }
+{ 'command': 'qmp_capabilities', 'data': { '*capabilities': ['QMPCapability'] } }
##
# @LostTickPolicy:
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 34/36] console: graphic_hw_update return true if async
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (32 preceding siblings ...)
2015-09-25 14:04 ` [Qemu-devel] [PATCH 33/36] monitor: add 'async' capability marcandre.lureau
@ 2015-09-25 14:04 ` marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 35/36] console: add graphic_hw_update_done() marcandre.lureau
` (3 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Let the caller know if the update is immediate or async.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/display/qxl-render.c | 5 +++--
hw/display/qxl.c | 8 ++++----
hw/display/qxl.h | 2 +-
include/ui/console.h | 3 ++-
ui/console.c | 14 ++++++++++++--
5 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index 7e4ef1e..54bbf01 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -162,7 +162,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
* callbacks are called by spice_server thread, deferring to bh called from the
* io thread.
*/
-void qxl_render_update(PCIQXLDevice *qxl)
+bool qxl_render_update(PCIQXLDevice *qxl)
{
QXLCookie *cookie;
@@ -171,7 +171,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
if (!runstate_is_running() || !qxl->guest_primary.commands) {
qxl_render_update_area_unlocked(qxl);
qemu_mutex_unlock(&qxl->ssd.lock);
- return;
+ return false;
}
qxl->guest_primary.commands = 0;
@@ -182,6 +182,7 @@ void qxl_render_update(PCIQXLDevice *qxl)
qxl_set_rect_to_surface(qxl, &cookie->u.render.area);
qxl_spice_update_area(qxl, 0, &cookie->u.render.area, NULL,
0, 1 /* clear_dirty_region */, QXL_ASYNC, cookie);
+ return true;
}
void qxl_render_update_area_bh(void *opaque)
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 9c961da..e76ea24 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -134,7 +134,7 @@ static void qxl_reset_memslots(PCIQXLDevice *d);
static void qxl_reset_surfaces(PCIQXLDevice *d);
static void qxl_ring_set_dirty(PCIQXLDevice *qxl);
-static void qxl_hw_update(void *opaque);
+static bool qxl_hw_update_async(void *opaque);
void qxl_set_guest_bug(PCIQXLDevice *qxl, const char *msg, ...)
{
@@ -1086,7 +1086,7 @@ static const QXLInterface qxl_interface = {
};
static const GraphicHwOps qxl_ops = {
- .gfx_update = qxl_hw_update,
+ .gfx_update_async = qxl_hw_update_async,
};
static void qxl_enter_vga_mode(PCIQXLDevice *d)
@@ -1775,11 +1775,11 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
/* graphics console */
-static void qxl_hw_update(void *opaque)
+static bool qxl_hw_update_async(void *opaque)
{
PCIQXLDevice *qxl = opaque;
- qxl_render_update(qxl);
+ return qxl_render_update(qxl);
}
static void qxl_dirty_surfaces(PCIQXLDevice *qxl)
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
index 2ddf065..5249adb 100644
--- a/hw/display/qxl.h
+++ b/hw/display/qxl.h
@@ -166,7 +166,7 @@ int qxl_log_command(PCIQXLDevice *qxl, const char *ring, QXLCommandExt *ext);
/* qxl-render.c */
void qxl_render_resize(PCIQXLDevice *qxl);
-void qxl_render_update(PCIQXLDevice *qxl);
+bool qxl_render_update(PCIQXLDevice *qxl);
int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext);
void qxl_render_update_area_done(PCIQXLDevice *qxl, QXLCookie *cookie);
void qxl_render_update_area_bh(void *opaque);
diff --git a/include/ui/console.h b/include/ui/console.h
index 047a2b4..a14a619 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -297,6 +297,7 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
typedef struct GraphicHwOps {
void (*invalidate)(void *opaque);
void (*gfx_update)(void *opaque);
+ bool (*gfx_update_async)(void *opaque);
void (*text_update)(void *opaque, console_ch_t *text);
void (*update_interval)(void *opaque, uint64_t interval);
int (*ui_info)(void *opaque, uint32_t head, QemuUIInfo *info);
@@ -309,7 +310,7 @@ void graphic_console_set_hwops(QemuConsole *con,
const GraphicHwOps *hw_ops,
void *opaque);
-void graphic_hw_update(QemuConsole *con);
+bool graphic_hw_update(QemuConsole *con);
void graphic_hw_invalidate(QemuConsole *con);
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
diff --git a/ui/console.c b/ui/console.c
index 75fc492..47352ef 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -250,14 +250,24 @@ static void gui_setup_refresh(DisplayState *ds)
ds->have_text = have_text;
}
-void graphic_hw_update(QemuConsole *con)
+bool graphic_hw_update(QemuConsole *con)
{
if (!con) {
con = active_console;
}
- if (con && con->hw_ops->gfx_update) {
+
+ if (!con) {
+ return false;
+ }
+
+ if (con->hw_ops->gfx_update_async) {
+ return con->hw_ops->gfx_update_async(con->hw);
+ } else if (con->hw_ops->gfx_update) {
con->hw_ops->gfx_update(con->hw);
+ return false;
}
+
+ return false;
}
void graphic_hw_invalidate(QemuConsole *con)
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 35/36] console: add graphic_hw_update_done()
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (33 preceding siblings ...)
2015-09-25 14:04 ` [Qemu-devel] [PATCH 34/36] console: graphic_hw_update return true if async marcandre.lureau
@ 2015-09-25 14:04 ` marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 36/36] console: add screendump-async marcandre.lureau
` (2 subsequent siblings)
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Add a function to be called when an async graphic update is done.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
hw/display/qxl-render.c | 9 +++++++--
include/ui/console.h | 1 +
ui/console.c | 4 ++++
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index 54bbf01..a5c9abc 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -105,7 +105,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.surface.mem,
MEMSLOT_GROUP_GUEST);
if (!qxl->guest_primary.data) {
- return;
+ goto end;
}
qxl_set_rect_to_surface(qxl, &qxl->dirty[0]);
qxl->num_dirty_rects = 1;
@@ -133,7 +133,7 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
}
if (!qxl->guest_primary.data) {
- return;
+ goto end;
}
for (i = 0; i < qxl->num_dirty_rects; i++) {
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
@@ -154,6 +154,11 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->dirty[i].bottom - qxl->dirty[i].top);
}
qxl->num_dirty_rects = 0;
+
+end:
+ if (qxl->render_update_cookie_num == 0) {
+ graphic_hw_update_done(qxl->ssd.dcl.con);
+ }
}
/*
diff --git a/include/ui/console.h b/include/ui/console.h
index a14a619..cb41d22 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -311,6 +311,7 @@ void graphic_console_set_hwops(QemuConsole *con,
void *opaque);
bool graphic_hw_update(QemuConsole *con);
+void graphic_hw_update_done(QemuConsole *con);
void graphic_hw_invalidate(QemuConsole *con);
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
diff --git a/ui/console.c b/ui/console.c
index 47352ef..1f800ef 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -250,6 +250,10 @@ static void gui_setup_refresh(DisplayState *ds)
ds->have_text = have_text;
}
+void graphic_hw_update_done(QemuConsole *con)
+{
+}
+
bool graphic_hw_update(QemuConsole *con)
{
if (!con) {
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [Qemu-devel] [PATCH 36/36] console: add screendump-async
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (34 preceding siblings ...)
2015-09-25 14:04 ` [Qemu-devel] [PATCH 35/36] console: add graphic_hw_update_done() marcandre.lureau
@ 2015-09-25 14:04 ` marcandre.lureau
2015-09-25 15:58 ` [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements Eric Blake
2015-09-25 16:21 ` Markus Armbruster
37 siblings, 0 replies; 64+ messages in thread
From: marcandre.lureau @ 2015-09-25 14:04 UTC (permalink / raw)
To: qemu-devel; +Cc: Marc-André Lureau, armbru, mdroth
From: Marc-André Lureau <marcandre.lureau@redhat.com>
Learn a new async command to make a correct screendump.
Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1230527
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
qapi-schema.json | 21 +++++++++++++++++++-
ui/console.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/qapi-schema.json b/qapi-schema.json
index 99c986d..cf2bd3a 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3899,7 +3899,7 @@
##
# @screendump:
#
-# Write a PPM of the VGA screen to a file.
+# Write a PPM of the first console to a file.
#
# @filename: the path of a new PPM file to store the image
#
@@ -3916,6 +3916,25 @@
{ 'command': 'screendump', 'data': {'filename': 'str'} }
##
+# @screendump-async:
+#
+# Write a PPM of the first console to a file.
+#
+# @filename: the path of a new PPM file to store the image
+#
+# Returns: Nothing on success
+#
+# Since: 2.5
+#
+# Example:
+#
+# -> { "execute": "screendump-async", "arguments": { "filename": "/tmp/image" }, id: X }
+# <- { "return": {}, id: X }
+#
+##
+{ 'command': 'screendump-async', 'data': {'filename': 'str'}, 'async': true }
+
+##
# @ChardevFile:
#
# Configuration info for file chardevs.
diff --git a/ui/console.c b/ui/console.c
index 1f800ef..5b4d1e8 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -113,6 +113,12 @@ typedef enum {
TEXT_CONSOLE_FIXED_SIZE
} console_type_t;
+struct qmp_screendump {
+ gchar *filename;
+ QmpReturn *ret;
+ QLIST_ENTRY(qmp_screendump) link;
+};
+
struct QemuConsole {
Object parent;
@@ -159,6 +165,8 @@ struct QemuConsole {
QEMUFIFO out_fifo;
uint8_t out_fifo_buf[16];
QEMUTimer *kbd_timer;
+
+ QLIST_HEAD(, qmp_screendump) qmp_screendumps;
};
struct DisplayState {
@@ -184,6 +192,8 @@ static void dpy_refresh(DisplayState *s);
static DisplayState *get_alloc_displaystate(void);
static void text_console_update_cursor_timer(void);
static void text_console_update_cursor(void *opaque);
+static void ppm_save(const char *filename, DisplaySurface *ds,
+ Error **errp);
static void gui_update(void *opaque)
{
@@ -250,8 +260,33 @@ static void gui_setup_refresh(DisplayState *ds)
ds->have_text = have_text;
}
+static void qmp_screendump_return(QemuConsole *con, const char *filename,
+ QmpReturn *ret)
+{
+ Error *err = NULL;
+ DisplaySurface *surface;
+
+ surface = qemu_console_surface(con);
+
+ ppm_save(filename, surface, &err);
+
+ if (err) {
+ qmp_return_error(ret, err);
+ } else {
+ qmp_screendump_async_return(ret);
+ }
+}
+
void graphic_hw_update_done(QemuConsole *con)
{
+ struct qmp_screendump *dump, *next;
+
+ QLIST_FOREACH_SAFE(dump, &con->qmp_screendumps, link, next) {
+ qmp_screendump_return(con, dump->filename, dump->ret);
+ g_free(dump->filename);
+ QLIST_REMOVE(dump, link);
+ g_free(dump);
+ }
}
bool graphic_hw_update(QemuConsole *con)
@@ -347,6 +382,29 @@ void qmp_screendump(const char *filename, Error **errp)
ppm_save(filename, surface, errp);
}
+void qmp_screendump_async(const char *filename, QmpReturn *qret)
+{
+ QemuConsole *con = qemu_console_lookup_by_index(0);
+ bool async;
+ Error *err;
+
+ if (con == NULL) {
+ error_setg(&err, "There is no QemuConsole I can screendump from.");
+ qmp_return_error(qret, err);
+ return;
+ }
+
+ async = graphic_hw_update(con);
+ if (async) {
+ struct qmp_screendump *dump = g_new(struct qmp_screendump, 1);
+ dump->filename = g_strdup(filename);
+ dump->ret = qret;
+ QLIST_INSERT_HEAD(&con->qmp_screendumps, dump, link);
+ } else {
+ qmp_screendump_return(con, filename, qret);
+ }
+}
+
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
{
if (!con) {
@@ -1206,6 +1264,7 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
obj = object_new(TYPE_QEMU_CONSOLE);
s = QEMU_CONSOLE(obj);
s->head = head;
+ QLIST_INIT(&s->qmp_screendumps);
object_property_add_link(obj, "device", TYPE_DEVICE,
(Object **)&s->device,
object_property_allow_set_link,
--
2.4.3
^ permalink raw reply related [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy
2015-09-25 14:03 ` [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy marcandre.lureau
@ 2015-09-25 15:03 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:03 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: qemu-trivial, armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1253 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> This is mainly to please the doc generation that requires comment block
> before the declaration.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
Reviewed-by: Eric Blake <eblake@redhat.com>
Could be taken through trivial branch now without waiting for pending
qapi patches, hence I've added a cc.
>
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 516c95b..3e2e53d 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -3042,13 +3042,17 @@
> { 'struct': 'ChardevRingbuf', 'data': { '*size' : 'int' } }
>
> ##
> +# @ChardevDummy
> +##
> +{ 'struct': 'ChardevDummy', 'data': { } }
I might eventually reach the point where we could use:
{ 'union': 'ChardevBackend', 'data': { ...
'pty': {},
... } }
instead of needing 'pty': 'ChardevDummy'. But my current pending series
doesn't get us quite there yet, so it would be a separate cleanup anyways.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 02/36] qapi: add missing @
2015-09-25 14:03 ` [Qemu-devel] [PATCH 02/36] qapi: add missing @ marcandre.lureau
@ 2015-09-25 15:03 ` Eric Blake
2015-10-03 16:57 ` Michael Tokarev
1 sibling, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:03 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: qemu-trivial, armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 541 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi/block.json | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Adding qemu-trivial; this can be taken now through trivial tree without
waiting for pending qapi patches.
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 04/36] monitor: use qapi for qmp_capabilities command
2015-09-25 14:03 ` [Qemu-devel] [PATCH 04/36] monitor: use qapi for qmp_capabilities command marcandre.lureau
@ 2015-09-25 15:09 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:09 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1318 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> This was initially done to add qmp_capabilities documentation to the
> schema. Then I figured it would also help to get rid of the "middle
> mode" monitor dispatch code.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> monitor.c | 4 ++--
> qapi-schema.json | 17 +++++++++++++++++
> qmp-commands.hx | 2 +-
> 3 files changed, 20 insertions(+), 3 deletions(-)
>
> +++ b/qapi-schema.json
> @@ -21,6 +21,23 @@
> { 'include': 'qapi/introspect.json' }
>
> ##
> +# @qmp_capabilities:
> +#
> +# Enable QMP capabilities.
> +#
> +# Arguments: None.
> +#
> +# Example:
> +#
> +# -> { "execute": "qmp_capabilities" }
> +# <- { "return": {} }
> +#
> +# Notes: This command must be issued before issuing any other command.
I'd also mention that it is only accepted once; maybe this is better?
Notes: This command is valid exactly when first connecting: it must be
issued before any other command will be accepted, and will fail once the
monitor is accepting other commands.
Otherwise, I'm a fan of this patch.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 05/36] qapi: move examples to json schema
2015-09-25 14:03 ` [Qemu-devel] [PATCH 05/36] qapi: move examples to json schema marcandre.lureau
@ 2015-09-25 15:16 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:16 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1775 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Clean-up qmp-commands.hx from examples.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 1128 +++++++++++++++-
> qapi/block-core.json | 365 +++++
> qapi/block.json | 32 +
> qapi/common.json | 32 +
> qapi/rocker.json | 43 +
> qapi/trace.json | 12 +
> qmp-commands.hx | 3617 +-------------------------------------------------
> 7 files changed, 1625 insertions(+), 3604 deletions(-)
Mammoth patch.
I don't know if it would make sense to break it into smaller pieces (say
10 or so related commands per patch) - more emails, but each email is
more reviewable, and the review can be divided among the various
maintainers that implement those various commands.
Or even if there were an easy way to automate the diff to prove that
every example was exactly moved, regardless of whether the example is
correct.
I'm not necessarily opposed to keeping it as one big patch, just that it
is a big commitment to review. And I do like where we end up, it's just
that I'm worried about making sure we don't regress along the way
(particularly if other QMP command examples are introduced along the way
before this gets merged - we already had a recent example of a
regression in -help output for PCI devices due to text being added to
one file in parallel with another patch that moved the text between files).
Also, I'd love to see docs/qapi-code-gen.txt updated to list Example: as
a proper part of a sample qapi listing.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files
2015-09-25 14:03 ` [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files marcandre.lureau
@ 2015-09-25 15:23 ` Eric Blake
2015-09-25 15:29 ` Marc-André Lureau
0 siblings, 1 reply; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:23 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 3769 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Moving the remaining bits of documentation to the schema files.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> qapi-schema.json | 48 ++++++++++++++++++++++++++++++++++++++++++-
> qmp-commands.hx | 62 --------------------------------------------------------
> 2 files changed, 47 insertions(+), 63 deletions(-)
>
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 1383011..c8ee75d 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -1,6 +1,52 @@
> # -*- Mode: Python -*-
> +##
> +# = Introduction
> +#
> +# This document describes all commands currently supported by QMP.
> +#
> +# Most of the time their usage is exactly the same as in the user Monitor, this
> +# means that any other document which also describe commands (the manpage,
> +# QEMU's manual, etc) can and should be consulted.
> +#
> +# QMP has two types of commands: regular and query commands. Regular commands
> +# usually change the Virtual Machine's state someway, while query commands just
> +# return information. The sections below are divided accordingly.
Do we really still have that clean division?
> +#
> +# It's important to observe that all communication examples are formatted in
> +# a reader-friendly way, so that they're easier to understand. However, in real
> +# protocol usage, they're emitted as a single line.
The server replies in a single line, but the client is free to send in
multiple lines.
> +#
> +# Also, the following notation is used to denote data flow:
> +#
> +# Example:
> +#
> +# | -> data issued by the Client
> +# | <- Server data response
> +#
> +# Please, refer to the QMP specification (QMP/qmp-spec.txt) for detailed
> +# information on the Server command and response formats.
Stale comment, pointing to the wrong file name (commit 7537fe04 moved it
from QMP/ to docs/qmp/) (and Markus has a patch pending that moves it
from docs/qmp/qmp-spec.txt to docs/qmp-spec.txt).
> +#
> +# = Stability Considerations
> +#
> +# The current QMP command set (described in this file) may be useful for a
> +# number of use cases, however it's limited and several commands have bad
> +# defined semantics, specially with regard to command completion.
> +#
> +# These problems are going to be solved incrementally in the next QEMU releases
> +# and we're going to establish a deprecation policy for badly defined commands.
Wow - some of this stuff has bit-rotted over time. I don't know how much
command completion we support for QMP (I guess it depends whether you
are using qmp-shell or a straight monitor connection), and while we do
still have badly defined commands, they are now the exception and we
have made a lot of progress in fixing things.
> +#
> +# If you're planning to adopt QMP, please observe the following:
> +#
> +# 1. The deprecation policy will take effect and be documented soon, please
> +# check the documentation of each used command as soon as a new release of
> +# QEMU is available
Umm, we still don't have a documented deprecation policy.
> +#
> +# 2. DO NOT rely on anything which is not explicit documented
s/explicit/explicitly/
> +#
> +# 3. Errors, in special, are not documented. Applications should NOT check
> +# for specific errors classes or data (it's strongly recommended to only
> +# check for the "error" key)
> #
> -# QAPI Schema
>
> # QAPI common definitions
> { 'include': 'qapi/common.json' }
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 07/36] qapi: add some headings in docs
2015-09-25 14:03 ` [Qemu-devel] [PATCH 07/36] qapi: add some headings in docs marcandre.lureau
@ 2015-09-25 15:26 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:26 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: qemu-trivial, armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1049 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Add some missing double-#, the doc parser can't easily distinguish doc
> comments from comments to be ignored otherwise.
>
> Also add some more section headings.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
Adding qemu-trivial; this can (mostly) be taken without waiting for
pending qapi patches, as it is a consistency cleanup.
> +++ b/qapi-schema.json
> @@ -67,6 +67,9 @@
> { 'include': 'qapi/introspect.json' }
>
> ##
> +# = QMP commands
> +
> +##
> # @qmp_capabilities:
well, except that you'd want to rebase the cleanups in this patch to
occur before your other patches which are NOT trivial (while I'm in
favor of documenting qmp_capabilities in qapi-schema.json, that one is
not a trivial patch)
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files
2015-09-25 15:23 ` Eric Blake
@ 2015-09-25 15:29 ` Marc-André Lureau
2015-09-25 15:35 ` Eric Blake
0 siblings, 1 reply; 64+ messages in thread
From: Marc-André Lureau @ 2015-09-25 15:29 UTC (permalink / raw)
To: Eric Blake; +Cc: mdroth, marcandre lureau, qemu-devel, armbru
----- Original Message -----
> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Moving the remaining bits of documentation to the schema files.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > ---
> > qapi-schema.json | 48 ++++++++++++++++++++++++++++++++++++++++++-
> > qmp-commands.hx | 62
> > --------------------------------------------------------
> > 2 files changed, 47 insertions(+), 63 deletions(-)
> >
> > diff --git a/qapi-schema.json b/qapi-schema.json
> > index 1383011..c8ee75d 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -1,6 +1,52 @@
> > # -*- Mode: Python -*-
> > +##
> > +# = Introduction
> > +#
> > +# This document describes all commands currently supported by QMP.
> > +#
> > +# Most of the time their usage is exactly the same as in the user Monitor,
> > this
> > +# means that any other document which also describe commands (the manpage,
> > +# QEMU's manual, etc) can and should be consulted.
> > +#
> > +# QMP has two types of commands: regular and query commands. Regular
> > commands
> > +# usually change the Virtual Machine's state someway, while query commands
> > just
> > +# return information. The sections below are divided accordingly.
>
> Do we really still have that clean division?
snip
Could we leave the content change for a later patch? The point was not to rewrite the documentation, but simply to move it.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 08/36] qapi: add qapi2texi script
2015-09-25 14:03 ` [Qemu-devel] [PATCH 08/36] qapi: add qapi2texi script marcandre.lureau
@ 2015-09-25 15:34 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:34 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 2419 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> As the name suggests, the qapi2texi script converts JSON QAPI
> description into a standalone texi file suitable for different target
> formats.
>
> It parses the following kind of blocks with some little variations:
>
> ##
> # = Section
> # == Subsection
> #
> # Some text foo with *emphasis*
> # 1. with a list
> # 2. like that
> #
> # And some code:
> # | <- do this
> # | -> get that
Backwards; you mean:
# | -> send this
# | <- get that
> # Example:
> #
> # -> { "execute": "quit" }
> # <- { "return": {} }
> #
but this one is right.
I'd love to have this formalized semantics of what you plan to parse
documented in docs/qapi-code-gen.txt, as a reference we can point to for
new commands that don't comply.
> Thanks to the json declaration, it's able to give extra information
> about the type of arguments and return value expected.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi.py | 88 +++++++++++++++-
> scripts/qapi2texi.py | 293 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 379 insertions(+), 2 deletions(-)
> create mode 100755 scripts/qapi2texi.py
I will forbear the actual review detailed for now, in part because it
may need another rebase, but the idea seems nice. But I'll do a quick
read-through review:
>
> diff --git a/scripts/qapi.py b/scripts/qapi.py
> index 27894c1..2a9b6e5 100644
> --- a/scripts/qapi.py
> +++ b/scripts/qapi.py
> @@ -112,6 +112,67 @@ class QAPIExprError(Exception):
> "%s:%d: %s" % (self.info['file'], self.info['line'], self.msg)
>
>
> +class QAPIDoc:
Use the new-style class inheritance (as in "class QAPIDoc(object):")
> +++ b/scripts/qapi2texi.py
> @@ -0,0 +1,293 @@
> +#!/usr/bin/env python
> +# QAPI texi generator
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2.
Can we please use GPLv2+ for this file? GPLv2-only is a pain (yes,
qapi.py is stuck there unless someone does legwork to see if former
contributors don't mind relaxing it, but that doesn't mean we have to
repeat the mistake)
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files
2015-09-25 15:29 ` Marc-André Lureau
@ 2015-09-25 15:35 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:35 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: mdroth, marcandre lureau, qemu-devel, armbru
[-- Attachment #1: Type: text/plain, Size: 1067 bytes --]
On 09/25/2015 09:29 AM, Marc-André Lureau wrote:
>
>
> ----- Original Message -----
>> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
>>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>
>>> Moving the remaining bits of documentation to the schema files.
>>>
>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>> ---
>>> qapi-schema.json | 48 ++++++++++++++++++++++++++++++++++++++++++-
>>> qmp-commands.hx | 62
>>> --------------------------------------------------------
>>> 2 files changed, 47 insertions(+), 63 deletions(-)
>>>
>> Do we really still have that clean division?
>
> snip
>
> Could we leave the content change for a later patch? The point was not to rewrite the documentation, but simply to move it.
Probably fine that way, but I also don't want to forget about the
content change (so even if it is not done in this patch, it should still
be part of the series).
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 09/36] qapi: remove qmp-events.txt
2015-09-25 14:03 ` [Qemu-devel] [PATCH 09/36] qapi: remove qmp-events.txt marcandre.lureau
@ 2015-09-25 15:40 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:40 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Move the examples in the json file with the rest of the documentation to
> avoid duplication.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> docs/qmp/qmp-events.txt | 664 ------------------------------------------------
> qapi/block-core.json | 59 ++++-
> qapi/block.json | 9 +
> qapi/event.json | 206 +++++++++++++++
> 4 files changed, 272 insertions(+), 666 deletions(-)
> delete mode 100644 docs/qmp/qmp-events.txt
Another big patch; not sure if it is worth splitting to ease review by
sharing the review load across multiple emails. But not quite as
daunting as the qmp-commands.hx content move. It will be a while before
I have a good stretch of time to commit to the actual review to make
sure nothing gets dropped, but I'm in favor of the idea.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 10/36] texi2pod: learn quotation, deftp and deftypefn
2015-09-25 14:03 ` [Qemu-devel] [PATCH 10/36] texi2pod: learn quotation, deftp and deftypefn marcandre.lureau
@ 2015-09-25 15:44 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:44 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 954 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Learn a few more markups used for API documentation.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/texi2pod.pl | 44 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 43 insertions(+), 1 deletion(-)
This file was originally from gcc (we forked it from a point before gcc
upstream made theirs GPLv3). Are your additions written from scratch,
or are they copied from somewhere else like gcc? Might be nice to be
explicit in your commit message.
I'm not the best perl reviewer, but the obvious test is whether the
resulting output file looks clean; offhand that seems to be the case,
but I'm not confident enough to leave R-b on this pass of reviews.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 11/36] build-sys: generate QAPI doc based on json
2015-09-25 14:03 ` [Qemu-devel] [PATCH 11/36] build-sys: generate QAPI doc based on json marcandre.lureau
@ 2015-09-25 15:49 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:49 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1900 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Learn to generate info/html/pdf/man documentation for QEMU and agent QMP
> APIs.
>
> This allows to provide missing agent documentation, and should help
"allows to" is not idiomatic English (it is missing a subject of who is
being allowed). Better would be either:
This allows us to provide missing agent documentation,
This provides missing agent documentation,
although I'd lean to the shorter form.
> getting rid of the duplicate documentation in qmp-commands.hx.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> Makefile | 36 ++++++++++++++++++++++++++++++------
> 1 file changed, 30 insertions(+), 6 deletions(-)
> @@ -363,7 +364,7 @@ distclean: clean
> rm -f qemu-doc.vr
> rm -f config.log
> rm -f linux-headers/asm
> - rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech.ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr
> + rm -f qemu-tech.info qemu-tech.aux qemu-tech.cp qemu-tech.dvi qemu-tech.fn qemu-tech.info qemu-tech..ky qemu-tech.log qemu-tech.pdf qemu-tech.pg qemu-tech.toc qemu-tech.tp qemu-tech.vr qemu-qapi.info qemu-qapi.aux qemu-qapi.cp qemu-qapi.dvi qemu-qapi.fn qemu-qapi.info qemu-qapi..ky qemu-qapi.log qemu-qapi.pdf qemu-qapi.pg qemu-qapi.toc qemu-qapi.tp qemu-qapi.vr qemu-ga-qapi.info qemu-ga-qapi.aux qemu-ga-qapi.cp qemu-ga-qapi.dvi qemu-ga-qapi.fn qemu-ga-qapi.info qemu-ga-qapi..ky qemu-ga-qapi.log qemu-ga-qapi.pdf qemu-ga-qapi.pg qemu-ga-qapi.toc qemu-ga-qapi.tp qemu-ga-qapi.vr
This line is now way long; can we use \ continuation to split it into
something easier to manage?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 15/36] monitor: register gen:false commands manually
2015-09-25 14:03 ` [Qemu-devel] [PATCH 15/36] monitor: register gen:false commands manually marcandre.lureau
@ 2015-09-25 15:56 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:56 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1304 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Since some commands are using 'gen': false, they are not registered
> automatically by the generator. Register manually instead.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> monitor.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/monitor.c b/monitor.c
> index 410c3a5..a979924 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -945,6 +945,16 @@ static void qmp_query_qmp_schema(QDict *qdict, QObject **ret_data,
> *ret_data = qobject_from_json(qmp_schema_json);
> }
>
> +static void qmp_init_marshal(void)
> +{
> + qmp_register_command("query-qmp-schema", qmp_query_qmp_schema,
> + QCO_NO_OPTIONS);
> + qmp_register_command("device_add", qmp_device_add,
> + QCO_NO_OPTIONS);
> +}
device_add wasn't even mentioned in a *.json file before your series.
/me goes and looks
Oh, you sneakily added it in "qapi: move examples to json schema".
Please separate that into its own patch, as it is more than just moving
examples.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (35 preceding siblings ...)
2015-09-25 14:04 ` [Qemu-devel] [PATCH 36/36] console: add screendump-async marcandre.lureau
@ 2015-09-25 15:58 ` Eric Blake
2015-09-25 16:01 ` Marc-André Lureau
2015-09-25 16:21 ` Markus Armbruster
37 siblings, 1 reply; 64+ messages in thread
From: Eric Blake @ 2015-09-25 15:58 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1007 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Hi,
>
> I have grown a qapi branch during the past 2 months that was
> post-poned for review until the introspection and other fixes got
> merged or ready.
For other reviewer's convenience, it looks like this is at
git fetch https://github.com/elmarco/qemu.git qapi
>
> It could be splitted roughly in 3 parts, but since they depend on each
s/splitted/split/
> other, it make sense to send as one:
> 1. generate QAPI documentation from schema (1->12)
> 2. remove use generated qmp dispatch in monitor (13->20)
> 3. add some support for async commands (22->36)
>
> 1 and 2 are hopefully not controversial, however 3 was discussed
> previously in 'async commands with QMP' thread:
For today, I'm just doing a quick look over parts 1 and 2.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements
2015-09-25 15:58 ` [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements Eric Blake
@ 2015-09-25 16:01 ` Marc-André Lureau
0 siblings, 0 replies; 64+ messages in thread
From: Marc-André Lureau @ 2015-09-25 16:01 UTC (permalink / raw)
To: Eric Blake; +Cc: mdroth, marcandre lureau, qemu-devel, armbru
Hi
----- Original Message -----
> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Hi,
> >
> > I have grown a qapi branch during the past 2 months that was
> > post-poned for review until the introspection and other fixes got
> > merged or ready.
>
> For other reviewer's convenience, it looks like this is at
> git fetch https://github.com/elmarco/qemu.git qapi
>
right, I just updated the branch with this latest series.
cheers
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 16/36] qmp: register qapi commands (no middle mode)
2015-09-25 14:03 ` [Qemu-devel] [PATCH 16/36] qmp: register qapi commands (no middle mode) marcandre.lureau
@ 2015-09-25 16:01 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 16:01 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 1891 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> The marshal functions are no longer exported, they are registered in the
> dispatch table instead. The following patches will make use of
> qmp_dispatch(). This patch temporarily breaks qmp/hmp commands.
Should this be squashed with the patch that fixes things?
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> Makefile | 2 +-
> qmp-commands-old.h | 129 -----------------------------------------------------
> vl.c | 1 +
> 3 files changed, 2 insertions(+), 130 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index 5e09e88..9750b71 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -289,7 +289,7 @@ $(qapi-modules) $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
> qmp-commands.h qmp-marshal.c :\
> $(qapi-modules) $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
> $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
> - $(gen-out-type) -o "." -m $<, \
> + $(gen-out-type) -o "." $<, \
> " GEN $@")
> qmp-introspect.h qmp-introspect.c :\
> $(qapi-modules) $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
> diff --git a/qmp-commands-old.h b/qmp-commands-old.h
> index 3a7af18..956157d 100644
> --- a/qmp-commands-old.h
> +++ b/qmp-commands-old.h
> @@ -1,279 +1,225 @@
> {
> .name = "quit",
> .args_type = "",
> - .mhandler.cmd_new = qmp_marshal_quit,
> },
> {
> .name = "eject",
> .args_type = "force:-f,device:B",
> - .mhandler.cmd_new = qmp_marshal_eject,
Do we still need .args_type? Can it be generated instead of maintained
by hand?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 18/36] qapi: remove "middle" mode
2015-09-25 14:03 ` [Qemu-devel] [PATCH 18/36] qapi: remove "middle" mode marcandre.lureau
@ 2015-09-25 16:03 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 16:03 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 627 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Now that the register function is always generated, we can
> remove the so-called "middle" mode to the generator script.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> scripts/qapi-commands.py | 29 +++++------------------------
> 1 file changed, 5 insertions(+), 24 deletions(-)
Yay. Although I haven't closely reviewed this one, I like the concept.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 19/36] qmp: implement qmp_query_commands without qmp_cmds
2015-09-25 14:03 ` [Qemu-devel] [PATCH 19/36] qmp: implement qmp_query_commands without qmp_cmds marcandre.lureau
@ 2015-09-25 16:06 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 16:06 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 508 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> So we can get rid of the static qmp_cmds table.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> monitor.c | 25 ++++++++++++++-----------
> 1 file changed, 14 insertions(+), 11 deletions(-)
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 20/36] qmp: remove old qmp-commands table
2015-09-25 14:03 ` [Qemu-devel] [PATCH 20/36] qmp: remove old qmp-commands table marcandre.lureau
@ 2015-09-25 16:08 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 16:08 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 593 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> The table is no longer used.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> monitor.c | 7 -
> qmp-commands-old.h | 554 -----------------------------------------------------
> 2 files changed, 561 deletions(-)
> delete mode 100644 qmp-commands-old.h
Nice!
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 21/36] misc: spelling
2015-09-25 14:03 ` [Qemu-devel] [PATCH 21/36] misc: spelling marcandre.lureau
@ 2015-09-25 16:08 ` Eric Blake
2015-10-03 16:55 ` Michael Tokarev
0 siblings, 1 reply; 64+ messages in thread
From: Eric Blake @ 2015-09-25 16:08 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: qemu-trivial, armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 889 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> ---
> monitor.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Trivial, can be applied now without waiting for pending qapi patches.
Reviewed-by: Eric Blake <eblake@redhat.com>
>
> diff --git a/monitor.c b/monitor.c
> index 4deef29..25f9608 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -306,7 +306,7 @@ static void monitor_flush_locked(Monitor *mon)
> return;
> }
> if (rc > 0) {
> - /* partinal write */
> + /* partial write */
> QString *tmp = qstring_from_str(buf + rc);
> QDECREF(mon->outbuf);
> mon->outbuf = tmp;
>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 30/36] tests: change /0.15/* tests to /qmp/*
2015-09-25 14:03 ` [Qemu-devel] [PATCH 30/36] tests: change /0.15/* tests to /qmp/* marcandre.lureau
@ 2015-09-25 16:10 ` Eric Blake
0 siblings, 0 replies; 64+ messages in thread
From: Eric Blake @ 2015-09-25 16:10 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
[-- Attachment #1: Type: text/plain, Size: 645 bytes --]
On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Presumably 0.15 was the version it was first introduced, but
> qmp keeps evolving. There is no point in having that version
> has test prefix, qmp makes more sense.
s/has/be the/
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
> tests/test-qmp-commands.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
Reviewed-by: Eric Blake <eblake@redhat.com>
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
` (36 preceding siblings ...)
2015-09-25 15:58 ` [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements Eric Blake
@ 2015-09-25 16:21 ` Markus Armbruster
37 siblings, 0 replies; 64+ messages in thread
From: Markus Armbruster @ 2015-09-25 16:21 UTC (permalink / raw)
To: marcandre.lureau; +Cc: qemu-devel, mdroth
marcandre.lureau@redhat.com writes:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Hi,
>
> I have grown a qapi branch during the past 2 months that was
> post-poned for review until the introspection and other fixes got
> merged or ready.
>
> It could be splitted roughly in 3 parts, but since they depend on each
> other, it make sense to send as one:
> 1. generate QAPI documentation from schema (1->12)
> 2. remove use generated qmp dispatch in monitor (13->20)
> 3. add some support for async commands (22->36)
>
> 1 and 2 are hopefully not controversial, however 3 was discussed
> previously in 'async commands with QMP' thread:
Parts 1 and 2 sound enticing!
> QMP was initially designed with async support, but the implementation
> was buggy, since the async context didn't hold the request 'id', and
> thus it wasn't really used, so it was removed in 65207c59d a few
> months ago.
>
> However, there a valid reasons to want better async support. Many qmp
> operations take time, and it's not a good idea to block the monitor
> during this time. Also, some operations, such as screendump with QXL,
> have to reenter the loop in order to complete. Furthermore, the
> current protocol is not purely synchronous, since the client have to
> handle unexpected in the middle replies, such as events.
>
> The current status-quo for async commands is to return immediately,
> and send loosely related events later. This is quite poor from an API
> point of view, and the events are not related to a previous command
> (they don't hold the request 'id'). They are also broadcasted, which
> may not make sense to other clients for various commands (all the dump
> & query for example) and this prevent from adding meaningful client
> 'id' field (since it may conflict with other clients 'id').
>
> I propose to re-introduce a better 'async' support, where command may
> return with the request 'id' only to the caller, when they are
> finished, and not block the monitor. This will be opt-out, so existing
> code do not have to change. Furthermore, since reply order is not
> guaranteed, clients will have to have the new 'async' capability to
> use those async commands. This scheme is not incompatible with having
> additional commands to query the command status, or broadcast related
> events to all clients.
This needs thought, and probably some debate.
With Eric's series and yours on top I'm again thoroughly swamped. My
current idea to avoid despair and ensure progress is to doggedly review
some patches every day, and not think about the length of the queue.
Unfortunately, that means it'll take me a while to reach part 3.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 21/36] misc: spelling
2015-09-25 16:08 ` Eric Blake
@ 2015-10-03 16:55 ` Michael Tokarev
2015-10-05 5:09 ` Markus Armbruster
0 siblings, 1 reply; 64+ messages in thread
From: Michael Tokarev @ 2015-10-03 16:55 UTC (permalink / raw)
To: Eric Blake, marcandre.lureau, qemu-devel; +Cc: qemu-trivial, armbru, mdroth
25.09.2015 19:08, Eric Blake wrote:
> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>>
>> ---
>> monitor.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> Trivial, can be applied now without waiting for pending qapi patches.
>
> Reviewed-by: Eric Blake <eblake@redhat.com>
Note there's no S-o-b line in the original patch (whole series,
looks like). Hopefully it is okay for such a really trivial
patch :)
Applied, thanks!
/mjt
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 02/36] qapi: add missing @
2015-09-25 14:03 ` [Qemu-devel] [PATCH 02/36] qapi: add missing @ marcandre.lureau
2015-09-25 15:03 ` Eric Blake
@ 2015-10-03 16:57 ` Michael Tokarev
1 sibling, 0 replies; 64+ messages in thread
From: Michael Tokarev @ 2015-10-03 16:57 UTC (permalink / raw)
To: marcandre.lureau, qemu-devel; +Cc: armbru, mdroth
Applied to -trivial, thanks!
/mjt
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 21/36] misc: spelling
2015-10-03 16:55 ` Michael Tokarev
@ 2015-10-05 5:09 ` Markus Armbruster
2015-10-05 7:32 ` Michael Tokarev
0 siblings, 1 reply; 64+ messages in thread
From: Markus Armbruster @ 2015-10-05 5:09 UTC (permalink / raw)
To: Michael Tokarev; +Cc: qemu-trivial, marcandre.lureau, qemu-devel, mdroth
Michael Tokarev <mjt@tls.msk.ru> writes:
> 25.09.2015 19:08, Eric Blake wrote:
>> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
>>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>
>>> ---
>>> monitor.c | 2 +-
>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> Trivial, can be applied now without waiting for pending qapi patches.
>>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>
> Note there's no S-o-b line in the original patch (whole series,
> looks like). Hopefully it is okay for such a really trivial
> patch :)
>
> Applied, thanks!
It may be legally safe, but do we really want to engage in judging
whether patches are copyrightable or not? Besides, it sets a bad
example.
Marc-André, please repost your patches ready for -trivial with your
S-o-B, cc: qemu-trivial.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 21/36] misc: spelling
2015-10-05 5:09 ` Markus Armbruster
@ 2015-10-05 7:32 ` Michael Tokarev
2015-10-05 17:05 ` Markus Armbruster
0 siblings, 1 reply; 64+ messages in thread
From: Michael Tokarev @ 2015-10-05 7:32 UTC (permalink / raw)
To: Markus Armbruster; +Cc: qemu-trivial, marcandre.lureau, qemu-devel, mdroth
05.10.2015 08:09, Markus Armbruster пишет:
> Michael Tokarev <mjt@tls.msk.ru> writes:
>
>> 25.09.2015 19:08, Eric Blake wrote:
>>> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
>>>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
[]
>>> Reviewed-by: Eric Blake <eblake@redhat.com>
>>
>> Note there's no S-o-b line in the original patch (whole series,
>> looks like). Hopefully it is okay for such a really trivial
>> patch :)
>>
>> Applied, thanks!
>
> It may be legally safe, but do we really want to engage in judging
> whether patches are copyrightable or not? Besides, it sets a bad
> example.
Sometimes I question our own sanity. Even for a trivial spelling fix
we require significantly more beaurocracy(sp) than the fix is worth,
and want formal rules instead of using common sense. This is a common
trend in the world, to formalize everything instead of thinking, the
world is becoming "candy". This reminded me an old movie, "Demolition
Man", -- the cops in the future reads instructions about what to do
in each situation they happened to come. But oh well, no one want to
take responsibility, that's okay ;)
Sorry for somewhat non-technical answer, I'll revert this patch,
waiting for more beaurocracy.
> Marc-André, please repost your patches ready for -trivial with your
> S-o-B, cc: qemu-trivial.
Mind you, it was a large series, with wasn't intended for -trivial
at all. That's more rules and more beaurocracy. And many other
patches in that series didn't have s-o-b line too.
Thanks,
/mjt
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [Qemu-devel] [PATCH 21/36] misc: spelling
2015-10-05 7:32 ` Michael Tokarev
@ 2015-10-05 17:05 ` Markus Armbruster
0 siblings, 0 replies; 64+ messages in thread
From: Markus Armbruster @ 2015-10-05 17:05 UTC (permalink / raw)
To: Michael Tokarev; +Cc: qemu-trivial, marcandre.lureau, qemu-devel, mdroth
Michael Tokarev <mjt@tls.msk.ru> writes:
> 05.10.2015 08:09, Markus Armbruster пишет:
>> Michael Tokarev <mjt@tls.msk.ru> writes:
>>
>>> 25.09.2015 19:08, Eric Blake wrote:
>>>> On 09/25/2015 08:03 AM, marcandre.lureau@redhat.com wrote:
>>>>> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> []
>>>> Reviewed-by: Eric Blake <eblake@redhat.com>
>>>
>>> Note there's no S-o-b line in the original patch (whole series,
>>> looks like). Hopefully it is okay for such a really trivial
>>> patch :)
>>>
>>> Applied, thanks!
>>
>> It may be legally safe, but do we really want to engage in judging
>> whether patches are copyrightable or not? Besides, it sets a bad
>> example.
>
> Sometimes I question our own sanity. Even for a trivial spelling fix
> we require significantly more beaurocracy(sp) than the fix is worth,
> and want formal rules instead of using common sense. This is a common
> trend in the world, to formalize everything instead of thinking, the
> world is becoming "candy". This reminded me an old movie, "Demolition
> Man", -- the cops in the future reads instructions about what to do
> in each situation they happened to come. But oh well, no one want to
> take responsibility, that's okay ;)
>
> Sorry for somewhat non-technical answer, I'll revert this patch,
> waiting for more beaurocracy.
Well, it could be worse, it could be CLA and copyright assignment.
S-o-B is probably the most lightweight thing we can do to stay on
relatively solid legal ground.
In my opinion, applying the "must have S-o-B" rule unthinkingly is less
effort than trying to identify cases where we can do without.
>> Marc-André, please repost your patches ready for -trivial with your
>> S-o-B, cc: qemu-trivial.
>
> Mind you, it was a large series, with wasn't intended for -trivial
> at all. That's more rules and more beaurocracy. And many other
> patches in that series didn't have s-o-b line too.
Chances are these patches really need it, so Marc-André has to repost
his series anyway.
^ permalink raw reply [flat|nested] 64+ messages in thread
end of thread, other threads:[~2015-10-05 17:14 UTC | newest]
Thread overview: 64+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-25 14:03 [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 01/36] qapi: add comment block before ChardevDummy marcandre.lureau
2015-09-25 15:03 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 02/36] qapi: add missing @ marcandre.lureau
2015-09-25 15:03 ` Eric Blake
2015-10-03 16:57 ` Michael Tokarev
2015-09-25 14:03 ` [Qemu-devel] [PATCH 03/36] qapi: add some line spacing to help doc parser marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 04/36] monitor: use qapi for qmp_capabilities command marcandre.lureau
2015-09-25 15:09 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 05/36] qapi: move examples to json schema marcandre.lureau
2015-09-25 15:16 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 06/36] qapi: move documentation bits in schema files marcandre.lureau
2015-09-25 15:23 ` Eric Blake
2015-09-25 15:29 ` Marc-André Lureau
2015-09-25 15:35 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 07/36] qapi: add some headings in docs marcandre.lureau
2015-09-25 15:26 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 08/36] qapi: add qapi2texi script marcandre.lureau
2015-09-25 15:34 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 09/36] qapi: remove qmp-events.txt marcandre.lureau
2015-09-25 15:40 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 10/36] texi2pod: learn quotation, deftp and deftypefn marcandre.lureau
2015-09-25 15:44 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 11/36] build-sys: generate QAPI doc based on json marcandre.lureau
2015-09-25 15:49 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 12/36] build-sys: generate qmp-commands.txt marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 13/36] build-sys: do not generate qmp-commands-old.h marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 14/36] monitor: remove usage of generated marshal functions marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 15/36] monitor: register gen:false commands manually marcandre.lureau
2015-09-25 15:56 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 16/36] qmp: register qapi commands (no middle mode) marcandre.lureau
2015-09-25 16:01 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 17/36] qmp: use qmp_dispatch() marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 18/36] qapi: remove "middle" mode marcandre.lureau
2015-09-25 16:03 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 19/36] qmp: implement qmp_query_commands without qmp_cmds marcandre.lureau
2015-09-25 16:06 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 20/36] qmp: remove old qmp-commands table marcandre.lureau
2015-09-25 16:08 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 21/36] misc: spelling marcandre.lureau
2015-09-25 16:08 ` Eric Blake
2015-10-03 16:55 ` Michael Tokarev
2015-10-05 5:09 ` Markus Armbruster
2015-10-05 7:32 ` Michael Tokarev
2015-10-05 17:05 ` Markus Armbruster
2015-09-25 14:03 ` [Qemu-devel] [PATCH 22/36] qmp: teach qmp_dispatch() to take a pre-filled QDict marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 23/36] qmp: use a return callback for the command reply marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 24/36] qmp: add QmpClient marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 25/36] qmp: introduce async command type marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 26/36] qmp: check that async command have an 'id' marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 27/36] scripts: learn 'async' qapi commands marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 28/36] scripts: ensure -async commands are declared async marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 29/36] qapi: take 'id' from request marcandre.lureau
2015-09-25 14:03 ` [Qemu-devel] [PATCH 30/36] tests: change /0.15/* tests to /qmp/* marcandre.lureau
2015-09-25 16:10 ` Eric Blake
2015-09-25 14:03 ` [Qemu-devel] [PATCH 31/36] tests: add /qmp/dispatch_cmd_async test marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 32/36] qmp: update qmp-spec about async capability marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 33/36] monitor: add 'async' capability marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 34/36] console: graphic_hw_update return true if async marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 35/36] console: add graphic_hw_update_done() marcandre.lureau
2015-09-25 14:04 ` [Qemu-devel] [PATCH 36/36] console: add screendump-async marcandre.lureau
2015-09-25 15:58 ` [Qemu-devel] [PATCH 00/36] post-Eric's fixes, QAPI improvements Eric Blake
2015-09-25 16:01 ` Marc-André Lureau
2015-09-25 16:21 ` Markus Armbruster
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).