From 275307aaab86a57ec1ce9c9eb066dd48e7ab0971 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:36 +0200 Subject: hmp: Move hmp.h to include/monitor/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: "Dr. David Alan Gilbert" Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-4-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Dr. David Alan Gilbert --- monitor/hmp-cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'monitor/hmp-cmds.c') diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index c283dde0e9..5082fcd016 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -14,7 +14,7 @@ */ #include "qemu/osdep.h" -#include "hmp.h" +#include "monitor/hmp.h" #include "net/net.h" #include "net/eth.h" #include "chardev/char.h" -- cgit 1.4.1 From c577ff624f7961e41eb194cec18055a2c3bb34c1 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:37 +0200 Subject: qapi: Split qom.json and qdev.json off misc.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move commands object-add, object-del, qom-get, qom-list, qom-list-properties, qom-list-types, and qom-set with their types from misc.json to new qom.json. Move commands device-list-properties, device_add, device-del, and event DEVICE_DELETED from misc.json to new qdev.json. Add both new files to MAINTAINERS section QOM. Cc: Paolo Bonzini Cc: "Daniel P. Berrange" Cc: Eduardo Habkost Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-5-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé [Straightforwardly updated for "MAINTAINERS: Make section "QOM" cover qdev as well"] --- MAINTAINERS | 2 + hw/block/xen-block.c | 2 +- hw/core/qdev.c | 2 +- monitor/hmp-cmds.c | 1 + monitor/qmp-cmds.c | 1 + qapi/Makefile.objs | 5 +- qapi/misc.json | 351 -------------------------------------------------- qapi/qapi-schema.json | 2 + qapi/qdev.json | 125 ++++++++++++++++++ qapi/qom.json | 244 +++++++++++++++++++++++++++++++++++ qdev-monitor.c | 2 +- 11 files changed, 381 insertions(+), 356 deletions(-) create mode 100644 qapi/qdev.json create mode 100644 qapi/qom.json (limited to 'monitor/hmp-cmds.c') diff --git a/MAINTAINERS b/MAINTAINERS index 3d139b61ff..ecab4310a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2039,6 +2039,8 @@ F: include/hw/qdev* F: include/monitor/qdev.h F: include/qom/ X: include/qom/cpu.h +F: qapi/qom.json +F: qapi/qdev.json F: qdev-monitor.c F: qom/ X: qom/cpu.c diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index 8f224ef81d..69d73196e2 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -11,7 +11,7 @@ #include "qemu/option.h" #include "qapi/error.h" #include "qapi/qapi-commands-block-core.h" -#include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-commands-qom.h" #include "qapi/qapi-visit-block-core.h" #include "qapi/qobject-input-visitor.h" #include "qapi/visitor.h" diff --git a/hw/core/qdev.c b/hw/core/qdev.c index f9b6efe509..94ebc0a4a1 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -29,7 +29,7 @@ #include "hw/qdev.h" #include "sysemu/sysemu.h" #include "qapi/error.h" -#include "qapi/qapi-events-misc.h" +#include "qapi/qapi-events-qdev.h" #include "qapi/qmp/qerror.h" #include "qapi/visitor.h" #include "qemu/error-report.h" diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 5082fcd016..d94ab7563e 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -34,6 +34,7 @@ #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" +#include "qapi/qapi-commands-qdev.h" #include "qapi/qapi-commands-rocker.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-commands-tpm.h" diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 01ce77e129..33f32ad72a 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -34,6 +34,7 @@ #include "qapi/error.h" #include "qapi/qapi-commands-block-core.h" #include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-commands-qdev.h" #include "qapi/qapi-commands-ui.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index 729e5185c5..40b1dcffc4 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -6,8 +6,9 @@ util-obj-y += qmp-event.o util-obj-y += qapi-util.o QAPI_COMMON_MODULES = audio authz block-core block char common crypto -QAPI_COMMON_MODULES += introspect job migration misc net rdma rocker -QAPI_COMMON_MODULES += run-state sockets tpm trace transaction ui +QAPI_COMMON_MODULES += introspect job migration misc net +QAPI_COMMON_MODULES += qdev qom rdma rocker run-state sockets tpm +QAPI_COMMON_MODULES += trace transaction ui QAPI_TARGET_MODULES = target QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES) diff --git a/qapi/misc.json b/qapi/misc.json index dc4cf9da20..5fbda70ad8 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1342,140 +1342,6 @@ 'data': {'command-line': 'str', '*cpu-index': 'int'}, 'returns': 'str' } -## -# @ObjectPropertyInfo: -# -# @name: the name of the property -# -# @type: the type of the property. This will typically come in one of four -# forms: -# -# 1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'. -# These types are mapped to the appropriate JSON type. -# -# 2) A child type in the form 'child' where subtype is a qdev -# device type name. Child properties create the composition tree. -# -# 3) A link type in the form 'link' where subtype is a qdev -# device type name. Link properties form the device model graph. -# -# @description: if specified, the description of the property. -# -# Since: 1.2 -## -{ 'struct': 'ObjectPropertyInfo', - 'data': { 'name': 'str', 'type': 'str', '*description': 'str' } } - -## -# @qom-list: -# -# This command will list any properties of a object given a path in the object -# model. -# -# @path: the path within the object model. See @qom-get for a description of -# this parameter. -# -# Returns: a list of @ObjectPropertyInfo that describe the properties of the -# object. -# -# Since: 1.2 -# -# Example: -# -# -> { "execute": "qom-list", -# "arguments": { "path": "/chardevs" } } -# <- { "return": [ { "name": "type", "type": "string" }, -# { "name": "parallel0", "type": "child" }, -# { "name": "serial0", "type": "child" }, -# { "name": "mon0", "type": "child" } ] } -# -## -{ 'command': 'qom-list', - 'data': { 'path': 'str' }, - 'returns': [ 'ObjectPropertyInfo' ], - 'allow-preconfig': true } - -## -# @qom-get: -# -# This command will get a property from a object model path and return the -# value. -# -# @path: The path within the object model. There are two forms of supported -# paths--absolute and partial paths. -# -# Absolute paths are derived from the root object and can follow child<> -# or link<> properties. Since they can follow link<> properties, they -# can be arbitrarily long. Absolute paths look like absolute filenames -# and are prefixed with a leading slash. -# -# Partial paths look like relative filenames. They do not begin -# with a prefix. The matching rules for partial paths are subtle but -# designed to make specifying objects easy. At each level of the -# composition tree, the partial path is matched as an absolute path. -# The first match is not returned. At least two matches are searched -# for. A successful result is only returned if only one match is -# found. If more than one match is found, a flag is return to -# indicate that the match was ambiguous. -# -# @property: The property name to read -# -# Returns: The property value. The type depends on the property -# type. child<> and link<> properties are returned as #str -# pathnames. All integer property types (u8, u16, etc) are -# returned as #int. -# -# Since: 1.2 -# -# Example: -# -# 1. Use absolute path -# -# -> { "execute": "qom-get", -# "arguments": { "path": "/machine/unattached/device[0]", -# "property": "hotplugged" } } -# <- { "return": false } -# -# 2. Use partial path -# -# -> { "execute": "qom-get", -# "arguments": { "path": "unattached/sysbus", -# "property": "type" } } -# <- { "return": "System" } -# -## -{ 'command': 'qom-get', - 'data': { 'path': 'str', 'property': 'str' }, - 'returns': 'any', - 'allow-preconfig': true } - -## -# @qom-set: -# -# This command will set a property from a object model path. -# -# @path: see @qom-get for a description of this parameter -# -# @property: the property name to set -# -# @value: a value who's type is appropriate for the property type. See @qom-get -# for a description of type mapping. -# -# Since: 1.2 -# -# Example: -# -# -> { "execute": "qom-set", -# "arguments": { "path": "/machine", -# "property": "graphics", -# "value": false } } -# <- { "return": {} } -# -## -{ 'command': 'qom-set', - 'data': { 'path': 'str', 'property': 'str', 'value': 'any' }, - 'allow-preconfig': true } - ## # @change: # @@ -1524,80 +1390,6 @@ { 'command': 'change', 'data': {'device': 'str', 'target': 'str', '*arg': 'str'} } -## -# @ObjectTypeInfo: -# -# This structure describes a search result from @qom-list-types -# -# @name: the type name found in the search -# -# @abstract: the type is abstract and can't be directly instantiated. -# Omitted if false. (since 2.10) -# -# @parent: Name of parent type, if any (since 2.10) -# -# Since: 1.1 -## -{ 'struct': 'ObjectTypeInfo', - 'data': { 'name': 'str', '*abstract': 'bool', '*parent': 'str' } } - -## -# @qom-list-types: -# -# This command will return a list of types given search parameters -# -# @implements: if specified, only return types that implement this type name -# -# @abstract: if true, include abstract types in the results -# -# Returns: a list of @ObjectTypeInfo or an empty list if no results are found -# -# Since: 1.1 -## -{ 'command': 'qom-list-types', - 'data': { '*implements': 'str', '*abstract': 'bool' }, - 'returns': [ 'ObjectTypeInfo' ], - 'allow-preconfig': true } - -## -# @device-list-properties: -# -# List properties associated with a device. -# -# @typename: the type name of a device -# -# Returns: a list of ObjectPropertyInfo describing a devices properties -# -# Note: objects can create properties at runtime, for example to describe -# links between different devices and/or objects. These properties -# are not included in the output of this command. -# -# Since: 1.2 -## -{ 'command': 'device-list-properties', - 'data': { 'typename': 'str'}, - 'returns': [ 'ObjectPropertyInfo' ] } - -## -# @qom-list-properties: -# -# List properties associated with a QOM object. -# -# @typename: the type name of an object -# -# Note: objects can create properties at runtime, for example to describe -# links between different devices and/or objects. These properties -# are not included in the output of this command. -# -# Returns: a list of ObjectPropertyInfo describing object properties -# -# Since: 2.12 -## -{ 'command': 'qom-list-properties', - 'data': { 'typename': 'str'}, - 'returns': [ 'ObjectPropertyInfo' ], - 'allow-preconfig': true } - ## # @xen-set-global-dirty-log: # @@ -1618,102 +1410,6 @@ ## { 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } } -## -# @device_add: -# -# @driver: the name of the new device's driver -# -# @bus: the device's parent bus (device tree path) -# -# @id: the device's ID, must be unique -# -# Additional arguments depend on the type. -# -# 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,help" command-line argument, where DEVICE is the -# device's name -# -# Example: -# -# -> { "execute": "device_add", -# "arguments": { "driver": "e1000", "id": "net1", -# "bus": "pci.0", -# "mac": "52:54:00:12:34:56" } } -# <- { "return": {} } -# -# TODO: This command effectively bypasses QAPI completely due to its -# "additional arguments" business. It shouldn't have been added to -# the schema in this form. It should be qapified properly, or -# replaced by a properly qapified command. -# -# Since: 0.13 -## -{ 'command': 'device_add', - 'data': {'driver': 'str', '*bus': 'str', '*id': 'str'}, - 'gen': false } # so we can get the additional arguments - -## -# @device_del: -# -# Remove a device from a guest -# -# @id: the device's ID or QOM path -# -# Returns: Nothing on success -# If @id is not a valid device, DeviceNotFound -# -# Notes: When this command completes, the device may not be removed from the -# guest. Hot removal is an operation that requires guest cooperation. -# This command merely requests that the guest begin the hot removal -# process. Completion of the device removal process is signaled with a -# DEVICE_DELETED event. Guest reset will automatically complete removal -# 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'} } - -## -# @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. -# -# @device: device name -# -# @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' } } - ## # @DumpGuestMemoryFormat: # @@ -1906,53 +1602,6 @@ { 'command': 'query-dump-guest-memory-capability', 'returns': 'DumpGuestMemoryCapability' } -## -# @object-add: -# -# Create a QOM object. -# -# @qom-type: the class name for the object to be created -# -# @id: the name of the new object -# -# @props: a dictionary of properties to be passed to the backend -# -# Returns: Nothing on success -# 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'} } - -## -# @object-del: -# -# Remove a QOM object. -# -# @id: the name of the QOM object to remove -# -# Returns: Nothing on success -# 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'} } - ## # @getfd: # diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index 4bd1223637..d6cf90a85a 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -97,6 +97,8 @@ { 'include': 'transaction.json' } { 'include': 'trace.json' } { 'include': 'introspect.json' } +{ 'include': 'qom.json' } +{ 'include': 'qdev.json' } { 'include': 'misc.json' } { 'include': 'target.json' } { 'include': 'audio.json' } diff --git a/qapi/qdev.json b/qapi/qdev.json new file mode 100644 index 0000000000..c6d05032f4 --- /dev/null +++ b/qapi/qdev.json @@ -0,0 +1,125 @@ +# -*- Mode: Python -*- +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# = Device infrastructure (qdev) +## + +{ 'include': 'qom.json' } + +## +# @device-list-properties: +# +# List properties associated with a device. +# +# @typename: the type name of a device +# +# Returns: a list of ObjectPropertyInfo describing a devices properties +# +# Note: objects can create properties at runtime, for example to describe +# links between different devices and/or objects. These properties +# are not included in the output of this command. +# +# Since: 1.2 +## +{ 'command': 'device-list-properties', + 'data': { 'typename': 'str'}, + 'returns': [ 'ObjectPropertyInfo' ] } + +## +# @device_add: +# +# @driver: the name of the new device's driver +# +# @bus: the device's parent bus (device tree path) +# +# @id: the device's ID, must be unique +# +# Additional arguments depend on the type. +# +# 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,help" command-line argument, where DEVICE is the +# device's name +# +# Example: +# +# -> { "execute": "device_add", +# "arguments": { "driver": "e1000", "id": "net1", +# "bus": "pci.0", +# "mac": "52:54:00:12:34:56" } } +# <- { "return": {} } +# +# TODO: This command effectively bypasses QAPI completely due to its +# "additional arguments" business. It shouldn't have been added to +# the schema in this form. It should be qapified properly, or +# replaced by a properly qapified command. +# +# Since: 0.13 +## +{ 'command': 'device_add', + 'data': {'driver': 'str', '*bus': 'str', '*id': 'str'}, + 'gen': false } # so we can get the additional arguments + +## +# @device_del: +# +# Remove a device from a guest +# +# @id: the device's ID or QOM path +# +# Returns: Nothing on success +# If @id is not a valid device, DeviceNotFound +# +# Notes: When this command completes, the device may not be removed from the +# guest. Hot removal is an operation that requires guest cooperation. +# This command merely requests that the guest begin the hot removal +# process. Completion of the device removal process is signaled with a +# DEVICE_DELETED event. Guest reset will automatically complete removal +# 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'} } + +## +# @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. +# +# @device: device name +# +# @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' } } diff --git a/qapi/qom.json b/qapi/qom.json new file mode 100644 index 0000000000..32db96ffc4 --- /dev/null +++ b/qapi/qom.json @@ -0,0 +1,244 @@ +# -*- Mode: Python -*- +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# = QEMU Object Model (QOM) +## + +## +# @ObjectPropertyInfo: +# +# @name: the name of the property +# +# @type: the type of the property. This will typically come in one of four +# forms: +# +# 1) A primitive type such as 'u8', 'u16', 'bool', 'str', or 'double'. +# These types are mapped to the appropriate JSON type. +# +# 2) A child type in the form 'child' where subtype is a qdev +# device type name. Child properties create the composition tree. +# +# 3) A link type in the form 'link' where subtype is a qdev +# device type name. Link properties form the device model graph. +# +# @description: if specified, the description of the property. +# +# Since: 1.2 +## +{ 'struct': 'ObjectPropertyInfo', + 'data': { 'name': 'str', 'type': 'str', '*description': 'str' } } + +## +# @qom-list: +# +# This command will list any properties of a object given a path in the object +# model. +# +# @path: the path within the object model. See @qom-get for a description of +# this parameter. +# +# Returns: a list of @ObjectPropertyInfo that describe the properties of the +# object. +# +# Since: 1.2 +# +# Example: +# +# -> { "execute": "qom-list", +# "arguments": { "path": "/chardevs" } } +# <- { "return": [ { "name": "type", "type": "string" }, +# { "name": "parallel0", "type": "child" }, +# { "name": "serial0", "type": "child" }, +# { "name": "mon0", "type": "child" } ] } +# +## +{ 'command': 'qom-list', + 'data': { 'path': 'str' }, + 'returns': [ 'ObjectPropertyInfo' ], + 'allow-preconfig': true } + +## +# @qom-get: +# +# This command will get a property from a object model path and return the +# value. +# +# @path: The path within the object model. There are two forms of supported +# paths--absolute and partial paths. +# +# Absolute paths are derived from the root object and can follow child<> +# or link<> properties. Since they can follow link<> properties, they +# can be arbitrarily long. Absolute paths look like absolute filenames +# and are prefixed with a leading slash. +# +# Partial paths look like relative filenames. They do not begin +# with a prefix. The matching rules for partial paths are subtle but +# designed to make specifying objects easy. At each level of the +# composition tree, the partial path is matched as an absolute path. +# The first match is not returned. At least two matches are searched +# for. A successful result is only returned if only one match is +# found. If more than one match is found, a flag is return to +# indicate that the match was ambiguous. +# +# @property: The property name to read +# +# Returns: The property value. The type depends on the property +# type. child<> and link<> properties are returned as #str +# pathnames. All integer property types (u8, u16, etc) are +# returned as #int. +# +# Since: 1.2 +# +# Example: +# +# 1. Use absolute path +# +# -> { "execute": "qom-get", +# "arguments": { "path": "/machine/unattached/device[0]", +# "property": "hotplugged" } } +# <- { "return": false } +# +# 2. Use partial path +# +# -> { "execute": "qom-get", +# "arguments": { "path": "unattached/sysbus", +# "property": "type" } } +# <- { "return": "System" } +# +## +{ 'command': 'qom-get', + 'data': { 'path': 'str', 'property': 'str' }, + 'returns': 'any', + 'allow-preconfig': true } + +## +# @qom-set: +# +# This command will set a property from a object model path. +# +# @path: see @qom-get for a description of this parameter +# +# @property: the property name to set +# +# @value: a value who's type is appropriate for the property type. See @qom-get +# for a description of type mapping. +# +# Since: 1.2 +# +# Example: +# +# -> { "execute": "qom-set", +# "arguments": { "path": "/machine", +# "property": "graphics", +# "value": false } } +# <- { "return": {} } +# +## +{ 'command': 'qom-set', + 'data': { 'path': 'str', 'property': 'str', 'value': 'any' }, + 'allow-preconfig': true } + +## +# @ObjectTypeInfo: +# +# This structure describes a search result from @qom-list-types +# +# @name: the type name found in the search +# +# @abstract: the type is abstract and can't be directly instantiated. +# Omitted if false. (since 2.10) +# +# @parent: Name of parent type, if any (since 2.10) +# +# Since: 1.1 +## +{ 'struct': 'ObjectTypeInfo', + 'data': { 'name': 'str', '*abstract': 'bool', '*parent': 'str' } } + +## +# @qom-list-types: +# +# This command will return a list of types given search parameters +# +# @implements: if specified, only return types that implement this type name +# +# @abstract: if true, include abstract types in the results +# +# Returns: a list of @ObjectTypeInfo or an empty list if no results are found +# +# Since: 1.1 +## +{ 'command': 'qom-list-types', + 'data': { '*implements': 'str', '*abstract': 'bool' }, + 'returns': [ 'ObjectTypeInfo' ], + 'allow-preconfig': true } + +## +# @qom-list-properties: +# +# List properties associated with a QOM object. +# +# @typename: the type name of an object +# +# Note: objects can create properties at runtime, for example to describe +# links between different devices and/or objects. These properties +# are not included in the output of this command. +# +# Returns: a list of ObjectPropertyInfo describing object properties +# +# Since: 2.12 +## +{ 'command': 'qom-list-properties', + 'data': { 'typename': 'str'}, + 'returns': [ 'ObjectPropertyInfo' ], + 'allow-preconfig': true } + +## +# @object-add: +# +# Create a QOM object. +# +# @qom-type: the class name for the object to be created +# +# @id: the name of the new object +# +# @props: a dictionary of properties to be passed to the backend +# +# Returns: Nothing on success +# 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'} } + +## +# @object-del: +# +# Remove a QOM object. +# +# @id: the name of the QOM object to remove +# +# Returns: Nothing on success +# 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'} } diff --git a/qdev-monitor.c b/qdev-monitor.c index 373b9ad445..63a87e9632 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -24,7 +24,7 @@ #include "monitor/qdev.h" #include "sysemu/arch_init.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-commands-qdev.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" #include "qemu/config-file.h" -- cgit 1.4.1 From 3950a37716dd64a1d9f729c49cbb7c6e7aaa4200 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:39 +0200 Subject: qom: Move HMP command handlers to qom/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the HMP command handlers related to QOM handlers from monitor/hmp-cmds.c and qdev-monitor.c to new qom/qom-hmp-cmds.c, where they are covered by MAINTAINERS section QOM. Cc: Paolo Bonzini Cc: "Daniel P. Berrange" Cc: Eduardo Habkost Cc: "Dr. David Alan Gilbert" Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-7-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Dr. David Alan Gilbert [Also move hmp_info_qom_tree(), tweak commit message accordingly] --- include/monitor/hmp.h | 3 ++ include/monitor/qdev.h | 1 - monitor/hmp-cmds.c | 50 +-------------------- qdev-monitor.c | 57 ----------------------- qom/Makefile.objs | 2 +- qom/qom-hmp-cmds.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 125 insertions(+), 108 deletions(-) create mode 100644 qom/qom-hmp-cmds.c (limited to 'monitor/hmp-cmds.c') diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index 1d095d5837..b36ebccd29 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -16,6 +16,8 @@ #include "qemu/readline.h" +void hmp_handle_error(Monitor *mon, Error **errp); + void hmp_info_name(Monitor *mon, const QDict *qdict); void hmp_info_version(Monitor *mon, const QDict *qdict); void hmp_info_kvm(Monitor *mon, const QDict *qdict); @@ -118,6 +120,7 @@ void hmp_info_memdev(Monitor *mon, const QDict *qdict); void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void hmp_qom_list(Monitor *mon, const QDict *qdict); void hmp_qom_set(Monitor *mon, const QDict *qdict); +void hmp_info_qom_tree(Monitor *mon, const QDict *dict); void object_add_completion(ReadLineState *rs, int nb_args, const char *str); void object_del_completion(ReadLineState *rs, int nb_args, const char *str); void device_add_completion(ReadLineState *rs, int nb_args, const char *str); diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h index 0ff3331284..084799e4d9 100644 --- a/include/monitor/qdev.h +++ b/include/monitor/qdev.h @@ -7,7 +7,6 @@ void hmp_info_qtree(Monitor *mon, const QDict *qdict); void hmp_info_qdm(Monitor *mon, const QDict *qdict); -void hmp_info_qom_tree(Monitor *mon, const QDict *dict); void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp); int qdev_device_help(QemuOpts *opts); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index d94ab7563e..5641036dc3 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -60,7 +60,7 @@ #include #endif -static void hmp_handle_error(Monitor *mon, Error **errp) +void hmp_handle_error(Monitor *mon, Error **errp) { assert(errp); if (*errp) { @@ -2714,54 +2714,6 @@ void hmp_info_iothreads(Monitor *mon, const QDict *qdict) qapi_free_IOThreadInfoList(info_list); } -void hmp_qom_list(Monitor *mon, const QDict *qdict) -{ - const char *path = qdict_get_try_str(qdict, "path"); - ObjectPropertyInfoList *list; - Error *err = NULL; - - if (path == NULL) { - monitor_printf(mon, "/\n"); - return; - } - - list = qmp_qom_list(path, &err); - if (err == NULL) { - ObjectPropertyInfoList *start = list; - while (list != NULL) { - ObjectPropertyInfo *value = list->value; - - monitor_printf(mon, "%s (%s)\n", - value->name, value->type); - list = list->next; - } - qapi_free_ObjectPropertyInfoList(start); - } - hmp_handle_error(mon, &err); -} - -void hmp_qom_set(Monitor *mon, const QDict *qdict) -{ - const char *path = qdict_get_str(qdict, "path"); - const char *property = qdict_get_str(qdict, "property"); - const char *value = qdict_get_str(qdict, "value"); - Error *err = NULL; - bool ambiguous = false; - Object *obj; - - obj = object_resolve_path(path, &ambiguous); - if (obj == NULL) { - error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND, - "Device '%s' not found", path); - } else { - if (ambiguous) { - monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path); - } - object_property_parse(obj, value, property, &err); - } - hmp_handle_error(mon, &err); -} - void hmp_rocker(Monitor *mon, const QDict *qdict) { const char *name = qdict_get_str(qdict, "name"); diff --git a/qdev-monitor.c b/qdev-monitor.c index 63a87e9632..58222c2211 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -739,63 +739,6 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict) qdev_print_devinfos(true); } -typedef struct QOMCompositionState { - Monitor *mon; - int indent; -} QOMCompositionState; - -static void print_qom_composition(Monitor *mon, Object *obj, int indent); - -static int print_qom_composition_child(Object *obj, void *opaque) -{ - QOMCompositionState *s = opaque; - - print_qom_composition(s->mon, obj, s->indent); - - return 0; -} - -static void print_qom_composition(Monitor *mon, Object *obj, int indent) -{ - QOMCompositionState s = { - .mon = mon, - .indent = indent + 2, - }; - char *name; - - if (obj == object_get_root()) { - name = g_strdup(""); - } else { - name = object_get_canonical_path_component(obj); - } - monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name, - object_get_typename(obj)); - g_free(name); - object_child_foreach(obj, print_qom_composition_child, &s); -} - -void hmp_info_qom_tree(Monitor *mon, const QDict *dict) -{ - const char *path = qdict_get_try_str(dict, "path"); - Object *obj; - bool ambiguous = false; - - if (path) { - obj = object_resolve_path(path, &ambiguous); - if (!obj) { - monitor_printf(mon, "Path '%s' could not be resolved.\n", path); - return; - } - if (ambiguous) { - monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path); - return; - } - } else { - obj = qdev_get_machine(); - } - print_qom_composition(mon, obj, 0); -} - void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) { Error *local_err = NULL; diff --git a/qom/Makefile.objs b/qom/Makefile.objs index 5fb43b842c..aae478fc21 100644 --- a/qom/Makefile.objs +++ b/qom/Makefile.objs @@ -2,4 +2,4 @@ qom-obj-y = object.o container.o qom-qobject.o qom-obj-y += object_interfaces.o common-obj-y = cpu.o -common-obj-$(CONFIG_SOFTMMU) += qom-qmp-cmds.o +common-obj-$(CONFIG_SOFTMMU) += qom-hmp-cmds.o qom-qmp-cmds.o diff --git a/qom/qom-hmp-cmds.c b/qom/qom-hmp-cmds.c new file mode 100644 index 0000000000..a268e01eb4 --- /dev/null +++ b/qom/qom-hmp-cmds.c @@ -0,0 +1,120 @@ +/* + * HMP commands related to QOM + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/qdev-core.h" +#include "monitor/hmp.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-qom.h" +#include "qapi/qmp/qdict.h" +#include "qom/object.h" + +void hmp_qom_list(Monitor *mon, const QDict *qdict) +{ + const char *path = qdict_get_try_str(qdict, "path"); + ObjectPropertyInfoList *list; + Error *err = NULL; + + if (path == NULL) { + monitor_printf(mon, "/\n"); + return; + } + + list = qmp_qom_list(path, &err); + if (err == NULL) { + ObjectPropertyInfoList *start = list; + while (list != NULL) { + ObjectPropertyInfo *value = list->value; + + monitor_printf(mon, "%s (%s)\n", + value->name, value->type); + list = list->next; + } + qapi_free_ObjectPropertyInfoList(start); + } + hmp_handle_error(mon, &err); +} + +void hmp_qom_set(Monitor *mon, const QDict *qdict) +{ + const char *path = qdict_get_str(qdict, "path"); + const char *property = qdict_get_str(qdict, "property"); + const char *value = qdict_get_str(qdict, "value"); + Error *err = NULL; + bool ambiguous = false; + Object *obj; + + obj = object_resolve_path(path, &ambiguous); + if (obj == NULL) { + error_set(&err, ERROR_CLASS_DEVICE_NOT_FOUND, + "Device '%s' not found", path); + } else { + if (ambiguous) { + monitor_printf(mon, "Warning: Path '%s' is ambiguous\n", path); + } + object_property_parse(obj, value, property, &err); + } + hmp_handle_error(mon, &err); +} + +typedef struct QOMCompositionState { + Monitor *mon; + int indent; +} QOMCompositionState; + +static void print_qom_composition(Monitor *mon, Object *obj, int indent); + +static int print_qom_composition_child(Object *obj, void *opaque) +{ + QOMCompositionState *s = opaque; + + print_qom_composition(s->mon, obj, s->indent); + + return 0; +} + +static void print_qom_composition(Monitor *mon, Object *obj, int indent) +{ + QOMCompositionState s = { + .mon = mon, + .indent = indent + 2, + }; + char *name; + + if (obj == object_get_root()) { + name = g_strdup(""); + } else { + name = object_get_canonical_path_component(obj); + } + monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name, + object_get_typename(obj)); + g_free(name); + object_child_foreach(obj, print_qom_composition_child, &s); +} + +void hmp_info_qom_tree(Monitor *mon, const QDict *dict) +{ + const char *path = qdict_get_try_str(dict, "path"); + Object *obj; + bool ambiguous = false; + + if (path) { + obj = object_resolve_path(path, &ambiguous); + if (!obj) { + monitor_printf(mon, "Path '%s' could not be resolved.\n", path); + return; + } + if (ambiguous) { + monitor_printf(mon, "Warning: Path '%s' is ambiguous.\n", path); + return; + } + } else { + obj = qdev_get_machine(); + } + print_qom_composition(mon, obj, 0); +} -- cgit 1.4.1 From 8ac25c84429031695a8b57727e2b518f5c3d8137 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:41 +0200 Subject: qapi: Split machine.json off misc.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move commands cpu-add, query-cpus, query-cpus-fast, query-current-machine, query-hotpluggable-cpus, query-machines, query-memdev, and set-numa-node with their types from misc.json to new machine.json. Also move types X86CPURegister32 and X86CPUFeatureWordInfo. Add machine.json to MAINTAINERS section "Machine core". Cc: Eduardo Habkost Cc: Marcel Apfelbaum Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-9-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé --- MAINTAINERS | 1 + cpus.c | 1 + include/hw/boards.h | 1 + include/sysemu/hostmem.h | 2 +- monitor/hmp-cmds.c | 1 + monitor/qmp-cmds.c | 1 + numa.c | 4 +- qapi/Makefile.objs | 2 +- qapi/machine.json | 697 +++++++++++++++++++++++++++++++++++++++++++++++ qapi/misc.json | 687 ---------------------------------------------- qapi/qapi-schema.json | 1 + target/i386/cpu.c | 2 +- target/s390x/cpu.c | 2 +- target/s390x/sigp.c | 2 +- vl.c | 2 +- 15 files changed, 711 insertions(+), 695 deletions(-) create mode 100644 qapi/machine.json (limited to 'monitor/hmp-cmds.c') diff --git a/MAINTAINERS b/MAINTAINERS index bcd9675f4a..f4d8c75d27 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1268,6 +1268,7 @@ F: hw/core/machine.c F: hw/core/null-machine.c F: hw/cpu/cluster.c F: numa.c +F: qapi/machine.json F: qom/cpu.c F: include/hw/boards.h F: include/hw/cpu/cluster.h diff --git a/cpus.c b/cpus.c index 1af51b73dd..100ce47fef 100644 --- a/cpus.c +++ b/cpus.c @@ -28,6 +28,7 @@ #include "cpu.h" #include "monitor/monitor.h" #include "qapi/error.h" +#include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-events-run-state.h" #include "qapi/qmp/qerror.h" diff --git a/include/hw/boards.h b/include/hw/boards.h index eaa050a7ab..c6ad196b14 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -6,6 +6,7 @@ #include "sysemu/blockdev.h" #include "sysemu/accel.h" #include "hw/qdev.h" +#include "qapi/qapi-types-machine.h" #include "qemu/module.h" #include "qom/object.h" #include "qom/cpu.h" diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h index a023b372a4..92fa0e458c 100644 --- a/include/sysemu/hostmem.h +++ b/include/sysemu/hostmem.h @@ -14,7 +14,7 @@ #define SYSEMU_HOSTMEM_H #include "sysemu/sysemu.h" /* for MAX_NODES */ -#include "qapi/qapi-types-misc.h" +#include "qapi/qapi-types-machine.h" #include "qom/object.h" #include "exec/memory.h" #include "qemu/bitmap.h" diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 5641036dc3..789f763938 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -31,6 +31,7 @@ #include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-commands-block.h" #include "qapi/qapi-commands-char.h" +#include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 6c06733c31..5788db5c59 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -31,6 +31,7 @@ #include "sysemu/block-backend.h" #include "qapi/error.h" #include "qapi/qapi-commands-block-core.h" +#include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-ui.h" #include "qapi/qmp/qerror.h" diff --git a/numa.c b/numa.c index 955ec0c830..6f85407c46 100644 --- a/numa.c +++ b/numa.c @@ -31,8 +31,8 @@ #include "qemu/error-report.h" #include "qapi/error.h" #include "qapi/opts-visitor.h" -#include "qapi/qapi-commands-misc.h" -#include "qapi/qapi-visit-misc.h" +#include "qapi/qapi-commands-machine.h" +#include "qapi/qapi-visit-machine.h" #include "hw/boards.h" #include "sysemu/hostmem.h" #include "hw/mem/pc-dimm.h" diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index 40b1dcffc4..01dced01aa 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -6,7 +6,7 @@ util-obj-y += qmp-event.o util-obj-y += qapi-util.o QAPI_COMMON_MODULES = audio authz block-core block char common crypto -QAPI_COMMON_MODULES += introspect job migration misc net +QAPI_COMMON_MODULES += introspect job machine migration misc net QAPI_COMMON_MODULES += qdev qom rdma rocker run-state sockets tpm QAPI_COMMON_MODULES += trace transaction ui QAPI_TARGET_MODULES = target diff --git a/qapi/machine.json b/qapi/machine.json new file mode 100644 index 0000000000..81849acb3a --- /dev/null +++ b/qapi/machine.json @@ -0,0 +1,697 @@ +# -*- Mode: Python -*- +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# = Machines +## + +{ 'include': 'common.json' } + +## +# @CpuInfoArch: +# +# An enumeration of cpu types that enable additional information during +# @query-cpus and @query-cpus-fast. +# +# @s390: since 2.12 +# +# @riscv: since 2.12 +# +# Since: 2.6 +## +{ 'enum': 'CpuInfoArch', + 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 's390', 'riscv', 'other' ] } + +## +# @CpuInfo: +# +# Information about a virtual CPU +# +# @CPU: the index of the virtual CPU +# +# @current: this only exists for backwards compatibility and should be ignored +# +# @halted: true if the virtual CPU is in the halt state. Halt usually refers +# to a processor specific low power mode. +# +# @qom_path: path to the CPU object in the QOM tree (since 2.4) +# +# @thread_id: ID of the underlying host thread +# +# @props: properties describing to which node/socket/core/thread +# virtual CPU belongs to, provided if supported by board (since 2.10) +# +# @arch: architecture of the cpu, which determines which additional fields +# will be listed (since 2.6) +# +# Since: 0.14.0 +# +# Notes: @halted is a transient state that changes frequently. By the time the +# data is sent to the client, the guest may no longer be halted. +## +{ 'union': 'CpuInfo', + 'base': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', + 'qom_path': 'str', 'thread_id': 'int', + '*props': 'CpuInstanceProperties', 'arch': 'CpuInfoArch' }, + 'discriminator': 'arch', + 'data': { 'x86': 'CpuInfoX86', + 'sparc': 'CpuInfoSPARC', + 'ppc': 'CpuInfoPPC', + 'mips': 'CpuInfoMIPS', + 'tricore': 'CpuInfoTricore', + 's390': 'CpuInfoS390', + 'riscv': 'CpuInfoRISCV' } } + +## +# @CpuInfoX86: +# +# Additional information about a virtual i386 or x86_64 CPU +# +# @pc: the 64-bit instruction pointer +# +# Since: 2.6 +## +{ 'struct': 'CpuInfoX86', 'data': { 'pc': 'int' } } + +## +# @CpuInfoSPARC: +# +# Additional information about a virtual SPARC CPU +# +# @pc: the PC component of the instruction pointer +# +# @npc: the NPC component of the instruction pointer +# +# Since: 2.6 +## +{ 'struct': 'CpuInfoSPARC', 'data': { 'pc': 'int', 'npc': 'int' } } + +## +# @CpuInfoPPC: +# +# Additional information about a virtual PPC CPU +# +# @nip: the instruction pointer +# +# Since: 2.6 +## +{ 'struct': 'CpuInfoPPC', 'data': { 'nip': 'int' } } + +## +# @CpuInfoMIPS: +# +# Additional information about a virtual MIPS CPU +# +# @PC: the instruction pointer +# +# Since: 2.6 +## +{ 'struct': 'CpuInfoMIPS', 'data': { 'PC': 'int' } } + +## +# @CpuInfoTricore: +# +# Additional information about a virtual Tricore CPU +# +# @PC: the instruction pointer +# +# Since: 2.6 +## +{ 'struct': 'CpuInfoTricore', 'data': { 'PC': 'int' } } + +## +# @CpuInfoRISCV: +# +# Additional information about a virtual RISCV CPU +# +# @pc: the instruction pointer +# +# Since 2.12 +## +{ 'struct': 'CpuInfoRISCV', 'data': { 'pc': 'int' } } + +## +# @CpuS390State: +# +# An enumeration of cpu states that can be assumed by a virtual +# S390 CPU +# +# Since: 2.12 +## +{ 'enum': 'CpuS390State', + 'prefix': 'S390_CPU_STATE', + 'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] } + +## +# @CpuInfoS390: +# +# Additional information about a virtual S390 CPU +# +# @cpu-state: the virtual CPU's state +# +# Since: 2.12 +## +{ 'struct': 'CpuInfoS390', 'data': { 'cpu-state': 'CpuS390State' } } + +## +# @query-cpus: +# +# Returns a list of information about each virtual CPU. +# +# This command causes vCPU threads to exit to userspace, which causes +# a small interruption to guest CPU execution. This will have a negative +# impact on realtime guests and other latency sensitive guest workloads. +# It is recommended to use @query-cpus-fast instead of this command to +# avoid the vCPU interruption. +# +# 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]", +# "arch":"x86", +# "pc":3227107138, +# "thread_id":3134 +# }, +# { +# "CPU":1, +# "current":false, +# "halted":true, +# "qom_path":"/machine/unattached/device[2]", +# "arch":"x86", +# "pc":7108165, +# "thread_id":3135 +# } +# ] +# } +# +# Notes: This interface is deprecated (since 2.12.0), and it is strongly +# recommended that you avoid using it. Use @query-cpus-fast to +# obtain information about virtual CPUs. +# +## +{ 'command': 'query-cpus', 'returns': ['CpuInfo'] } + +## +# @CpuInfoFast: +# +# Information about a virtual CPU +# +# @cpu-index: index of the virtual CPU +# +# @qom-path: path to the CPU object in the QOM tree +# +# @thread-id: ID of the underlying host thread +# +# @props: properties describing to which node/socket/core/thread +# virtual CPU belongs to, provided if supported by board +# +# @arch: base architecture of the cpu; deprecated since 3.0.0 in favor +# of @target +# +# @target: the QEMU system emulation target, which determines which +# additional fields will be listed (since 3.0) +# +# Since: 2.12 +# +## +{ 'union' : 'CpuInfoFast', + 'base' : { 'cpu-index' : 'int', + 'qom-path' : 'str', + 'thread-id' : 'int', + '*props' : 'CpuInstanceProperties', + 'arch' : 'CpuInfoArch', + 'target' : 'SysEmuTarget' }, + 'discriminator' : 'target', + 'data' : { 's390x' : 'CpuInfoS390' } } + +## +# @query-cpus-fast: +# +# Returns information about all virtual CPUs. This command does not +# incur a performance penalty and should be used in production +# instead of query-cpus. +# +# Returns: list of @CpuInfoFast +# +# Since: 2.12 +# +# Example: +# +# -> { "execute": "query-cpus-fast" } +# <- { "return": [ +# { +# "thread-id": 25627, +# "props": { +# "core-id": 0, +# "thread-id": 0, +# "socket-id": 0 +# }, +# "qom-path": "/machine/unattached/device[0]", +# "arch":"x86", +# "target":"x86_64", +# "cpu-index": 0 +# }, +# { +# "thread-id": 25628, +# "props": { +# "core-id": 0, +# "thread-id": 0, +# "socket-id": 1 +# }, +# "qom-path": "/machine/unattached/device[2]", +# "arch":"x86", +# "target":"x86_64", +# "cpu-index": 1 +# } +# ] +# } +## +{ 'command': 'query-cpus-fast', 'returns': [ 'CpuInfoFast' ] } + +## +# @cpu-add: +# +# Adds CPU with specified ID. +# +# @id: ID of CPU to be created, valid values [0..max_cpus) +# +# Returns: Nothing on success +# +# Since: 1.5 +# +# Note: This command is deprecated. The `device_add` command should be +# used instead. See the `query-hotpluggable-cpus` command for +# details. +# +# Example: +# +# -> { "execute": "cpu-add", "arguments": { "id": 2 } } +# <- { "return": {} } +# +## +{ 'command': 'cpu-add', 'data': {'id': 'int'} } + +## +# @MachineInfo: +# +# Information describing a machine. +# +# @name: the name of the machine +# +# @alias: an alias for the machine name +# +# @is-default: whether the machine is default +# +# @cpu-max: maximum number of CPUs supported by the machine type +# (since 1.5.0) +# +# @hotpluggable-cpus: cpu hotplug via -device is supported (since 2.7.0) +# +# Since: 1.2.0 +## +{ 'struct': 'MachineInfo', + 'data': { 'name': 'str', '*alias': 'str', + '*is-default': 'bool', 'cpu-max': 'int', + 'hotpluggable-cpus': 'bool'} } + +## +# @query-machines: +# +# Return a list of supported machines +# +# Returns: a list of MachineInfo +# +# Since: 1.2.0 +## +{ 'command': 'query-machines', 'returns': ['MachineInfo'] } + +## +# @CurrentMachineParams: +# +# Information describing the running machine parameters. +# +# @wakeup-suspend-support: true if the machine supports wake up from +# suspend +# +# Since: 4.0 +## +{ 'struct': 'CurrentMachineParams', + 'data': { 'wakeup-suspend-support': 'bool'} } + +## +# @query-current-machine: +# +# Return information on the current virtual machine. +# +# Returns: CurrentMachineParams +# +# Since: 4.0 +## +{ 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' } + +## +# @NumaOptionsType: +# +# @node: NUMA nodes configuration +# +# @dist: NUMA distance configuration (since 2.10) +# +# @cpu: property based CPU(s) to node mapping (Since: 2.10) +# +# Since: 2.1 +## +{ 'enum': 'NumaOptionsType', + 'data': [ 'node', 'dist', 'cpu' ] } + +## +# @NumaOptions: +# +# A discriminated record of NUMA options. (for OptsVisitor) +# +# Since: 2.1 +## +{ 'union': 'NumaOptions', + 'base': { 'type': 'NumaOptionsType' }, + 'discriminator': 'type', + 'data': { + 'node': 'NumaNodeOptions', + 'dist': 'NumaDistOptions', + 'cpu': 'NumaCpuOptions' }} + +## +# @NumaNodeOptions: +# +# Create a guest NUMA node. (for OptsVisitor) +# +# @nodeid: NUMA node ID (increase by 1 from 0 if omitted) +# +# @cpus: VCPUs belonging to this node (assign VCPUS round-robin +# if omitted) +# +# @mem: memory size of this node; mutually exclusive with @memdev. +# Equally divide total memory among nodes if both @mem and @memdev are +# omitted. +# +# @memdev: memory backend object. If specified for one node, +# it must be specified for all nodes. +# +# Since: 2.1 +## +{ 'struct': 'NumaNodeOptions', + 'data': { + '*nodeid': 'uint16', + '*cpus': ['uint16'], + '*mem': 'size', + '*memdev': 'str' }} + +## +# @NumaDistOptions: +# +# Set the distance between 2 NUMA nodes. +# +# @src: source NUMA node. +# +# @dst: destination NUMA node. +# +# @val: NUMA distance from source node to destination node. +# When a node is unreachable from another node, set the distance +# between them to 255. +# +# Since: 2.10 +## +{ 'struct': 'NumaDistOptions', + 'data': { + 'src': 'uint16', + 'dst': 'uint16', + 'val': 'uint8' }} + +## +# @X86CPURegister32: +# +# A X86 32-bit register +# +# Since: 1.5 +## +{ 'enum': 'X86CPURegister32', + 'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] } + +## +# @X86CPUFeatureWordInfo: +# +# Information about a X86 CPU feature word +# +# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature word +# +# @cpuid-input-ecx: Input ECX value for CPUID instruction for that +# feature word +# +# @cpuid-register: Output register containing the feature bits +# +# @features: value of output register, containing the feature bits +# +# Since: 1.5 +## +{ 'struct': 'X86CPUFeatureWordInfo', + 'data': { 'cpuid-input-eax': 'int', + '*cpuid-input-ecx': 'int', + 'cpuid-register': 'X86CPURegister32', + 'features': 'int' } } + +## +# @DummyForceArrays: +# +# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally +# +# Since: 2.5 +## +{ 'struct': 'DummyForceArrays', + 'data': { 'unused': ['X86CPUFeatureWordInfo'] } } + +## +# @NumaCpuOptions: +# +# Option "-numa cpu" overrides default cpu to node mapping. +# It accepts the same set of cpu properties as returned by +# query-hotpluggable-cpus[].props, where node-id could be used to +# override default node mapping. +# +# Since: 2.10 +## +{ 'struct': 'NumaCpuOptions', + 'base': 'CpuInstanceProperties', + 'data' : {} } + +## +# @HostMemPolicy: +# +# Host memory policy types +# +# @default: restore default policy, remove any nondefault policy +# +# @preferred: set the preferred host nodes for allocation +# +# @bind: a strict policy that restricts memory allocation to the +# host nodes specified +# +# @interleave: memory allocations are interleaved across the set +# of host nodes specified +# +# Since: 2.1 +## +{ 'enum': 'HostMemPolicy', + 'data': [ 'default', 'preferred', 'bind', 'interleave' ] } + +## +# @Memdev: +# +# Information about memory backend +# +# @id: backend's ID if backend has 'id' property (since 2.9) +# +# @size: memory backend size +# +# @merge: enables or disables memory merge support +# +# @dump: includes memory backend's memory in a core dump or not +# +# @prealloc: enables or disables memory preallocation +# +# @host-nodes: host nodes for its memory policy +# +# @policy: memory policy of memory backend +# +# Since: 2.1 +## +{ 'struct': 'Memdev', + 'data': { + '*id': 'str', + 'size': 'size', + 'merge': 'bool', + 'dump': 'bool', + 'prealloc': 'bool', + 'host-nodes': ['uint16'], + 'policy': 'HostMemPolicy' }} + +## +# @query-memdev: +# +# Returns information for all memory backends. +# +# Returns: a list of @Memdev. +# +# Since: 2.1 +# +# Example: +# +# -> { "execute": "query-memdev" } +# <- { "return": [ +# { +# "id": "mem1", +# "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'], 'allow-preconfig': true } + +## +# @CpuInstanceProperties: +# +# List of properties to be used for hotplugging a CPU instance, +# it should be passed by management with device_add command when +# a CPU is being hotplugged. +# +# @node-id: NUMA node ID the CPU belongs to +# @socket-id: socket number within node/board the CPU belongs to +# @core-id: core number within socket the CPU belongs to +# @thread-id: thread number within core the CPU belongs to +# +# Note: currently there are 4 properties that could be present +# but management should be prepared to pass through other +# properties with device_add command to allow for future +# interface extension. This also requires the filed names to be kept in +# sync with the properties passed to -device/device_add. +# +# Since: 2.7 +## +{ 'struct': 'CpuInstanceProperties', + 'data': { '*node-id': 'int', + '*socket-id': 'int', + '*core-id': 'int', + '*thread-id': 'int' + } +} + +## +# @HotpluggableCPU: +# +# @type: CPU object type for usage with device_add command +# @props: list of properties to be used for hotplugging CPU +# @vcpus-count: number of logical VCPU threads @HotpluggableCPU provides +# @qom-path: link to existing CPU object if CPU is present or +# omitted if CPU is not present. +# +# Since: 2.7 +## +{ 'struct': 'HotpluggableCPU', + 'data': { 'type': 'str', + 'vcpus-count': 'int', + 'props': 'CpuInstanceProperties', + '*qom-path': 'str' + } +} + +## +# @query-hotpluggable-cpus: +# +# TODO: Better documentation; currently there is none. +# +# Returns: a list of HotpluggableCPU objects. +# +# Since: 2.7 +# +# Example: +# +# For pseries machine type started with -smp 2,cores=2,maxcpus=4 -cpu POWER8: +# +# -> { "execute": "query-hotpluggable-cpus" } +# <- {"return": [ +# { "props": { "core": 8 }, "type": "POWER8-spapr-cpu-core", +# "vcpus-count": 1 }, +# { "props": { "core": 0 }, "type": "POWER8-spapr-cpu-core", +# "vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"} +# ]}' +# +# For pc machine type started with -smp 1,maxcpus=2: +# +# -> { "execute": "query-hotpluggable-cpus" } +# <- {"return": [ +# { +# "type": "qemu64-x86_64-cpu", "vcpus-count": 1, +# "props": {"core-id": 0, "socket-id": 1, "thread-id": 0} +# }, +# { +# "qom-path": "/machine/unattached/device[0]", +# "type": "qemu64-x86_64-cpu", "vcpus-count": 1, +# "props": {"core-id": 0, "socket-id": 0, "thread-id": 0} +# } +# ]} +# +# For s390x-virtio-ccw machine type started with -smp 1,maxcpus=2 -cpu qemu +# (Since: 2.11): +# +# -> { "execute": "query-hotpluggable-cpus" } +# <- {"return": [ +# { +# "type": "qemu-s390x-cpu", "vcpus-count": 1, +# "props": { "core-id": 1 } +# }, +# { +# "qom-path": "/machine/unattached/device[0]", +# "type": "qemu-s390x-cpu", "vcpus-count": 1, +# "props": { "core-id": 0 } +# } +# ]} +# +## +{ 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'], + 'allow-preconfig': true } + +## +# @set-numa-node: +# +# Runtime equivalent of '-numa' CLI option, available at +# preconfigure stage to configure numa mapping before initializing +# machine. +# +# Since 3.0 +## +{ 'command': 'set-numa-node', 'boxed': true, + 'data': 'NumaOptions', + 'allow-preconfig': true +} diff --git a/qapi/misc.json b/qapi/misc.json index 5fbda70ad8..b4f8c658b7 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -342,276 +342,6 @@ ## { 'command': 'query-events', 'returns': ['EventInfo'] } -## -# @CpuInfoArch: -# -# An enumeration of cpu types that enable additional information during -# @query-cpus and @query-cpus-fast. -# -# @s390: since 2.12 -# -# @riscv: since 2.12 -# -# Since: 2.6 -## -{ 'enum': 'CpuInfoArch', - 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 's390', 'riscv', 'other' ] } - -## -# @CpuInfo: -# -# Information about a virtual CPU -# -# @CPU: the index of the virtual CPU -# -# @current: this only exists for backwards compatibility and should be ignored -# -# @halted: true if the virtual CPU is in the halt state. Halt usually refers -# to a processor specific low power mode. -# -# @qom_path: path to the CPU object in the QOM tree (since 2.4) -# -# @thread_id: ID of the underlying host thread -# -# @props: properties describing to which node/socket/core/thread -# virtual CPU belongs to, provided if supported by board (since 2.10) -# -# @arch: architecture of the cpu, which determines which additional fields -# will be listed (since 2.6) -# -# Since: 0.14.0 -# -# Notes: @halted is a transient state that changes frequently. By the time the -# data is sent to the client, the guest may no longer be halted. -## -{ 'union': 'CpuInfo', - 'base': {'CPU': 'int', 'current': 'bool', 'halted': 'bool', - 'qom_path': 'str', 'thread_id': 'int', - '*props': 'CpuInstanceProperties', 'arch': 'CpuInfoArch' }, - 'discriminator': 'arch', - 'data': { 'x86': 'CpuInfoX86', - 'sparc': 'CpuInfoSPARC', - 'ppc': 'CpuInfoPPC', - 'mips': 'CpuInfoMIPS', - 'tricore': 'CpuInfoTricore', - 's390': 'CpuInfoS390', - 'riscv': 'CpuInfoRISCV' } } - -## -# @CpuInfoX86: -# -# Additional information about a virtual i386 or x86_64 CPU -# -# @pc: the 64-bit instruction pointer -# -# Since: 2.6 -## -{ 'struct': 'CpuInfoX86', 'data': { 'pc': 'int' } } - -## -# @CpuInfoSPARC: -# -# Additional information about a virtual SPARC CPU -# -# @pc: the PC component of the instruction pointer -# -# @npc: the NPC component of the instruction pointer -# -# Since: 2.6 -## -{ 'struct': 'CpuInfoSPARC', 'data': { 'pc': 'int', 'npc': 'int' } } - -## -# @CpuInfoPPC: -# -# Additional information about a virtual PPC CPU -# -# @nip: the instruction pointer -# -# Since: 2.6 -## -{ 'struct': 'CpuInfoPPC', 'data': { 'nip': 'int' } } - -## -# @CpuInfoMIPS: -# -# Additional information about a virtual MIPS CPU -# -# @PC: the instruction pointer -# -# Since: 2.6 -## -{ 'struct': 'CpuInfoMIPS', 'data': { 'PC': 'int' } } - -## -# @CpuInfoTricore: -# -# Additional information about a virtual Tricore CPU -# -# @PC: the instruction pointer -# -# Since: 2.6 -## -{ 'struct': 'CpuInfoTricore', 'data': { 'PC': 'int' } } - -## -# @CpuInfoRISCV: -# -# Additional information about a virtual RISCV CPU -# -# @pc: the instruction pointer -# -# Since 2.12 -## -{ 'struct': 'CpuInfoRISCV', 'data': { 'pc': 'int' } } - -## -# @CpuS390State: -# -# An enumeration of cpu states that can be assumed by a virtual -# S390 CPU -# -# Since: 2.12 -## -{ 'enum': 'CpuS390State', - 'prefix': 'S390_CPU_STATE', - 'data': [ 'uninitialized', 'stopped', 'check-stop', 'operating', 'load' ] } - -## -# @CpuInfoS390: -# -# Additional information about a virtual S390 CPU -# -# @cpu-state: the virtual CPU's state -# -# Since: 2.12 -## -{ 'struct': 'CpuInfoS390', 'data': { 'cpu-state': 'CpuS390State' } } - -## -# @query-cpus: -# -# Returns a list of information about each virtual CPU. -# -# This command causes vCPU threads to exit to userspace, which causes -# a small interruption to guest CPU execution. This will have a negative -# impact on realtime guests and other latency sensitive guest workloads. -# It is recommended to use @query-cpus-fast instead of this command to -# avoid the vCPU interruption. -# -# 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]", -# "arch":"x86", -# "pc":3227107138, -# "thread_id":3134 -# }, -# { -# "CPU":1, -# "current":false, -# "halted":true, -# "qom_path":"/machine/unattached/device[2]", -# "arch":"x86", -# "pc":7108165, -# "thread_id":3135 -# } -# ] -# } -# -# Notes: This interface is deprecated (since 2.12.0), and it is strongly -# recommended that you avoid using it. Use @query-cpus-fast to -# obtain information about virtual CPUs. -# -## -{ 'command': 'query-cpus', 'returns': ['CpuInfo'] } - -## -# @CpuInfoFast: -# -# Information about a virtual CPU -# -# @cpu-index: index of the virtual CPU -# -# @qom-path: path to the CPU object in the QOM tree -# -# @thread-id: ID of the underlying host thread -# -# @props: properties describing to which node/socket/core/thread -# virtual CPU belongs to, provided if supported by board -# -# @arch: base architecture of the cpu; deprecated since 3.0.0 in favor -# of @target -# -# @target: the QEMU system emulation target, which determines which -# additional fields will be listed (since 3.0) -# -# Since: 2.12 -# -## -{ 'union' : 'CpuInfoFast', - 'base' : { 'cpu-index' : 'int', - 'qom-path' : 'str', - 'thread-id' : 'int', - '*props' : 'CpuInstanceProperties', - 'arch' : 'CpuInfoArch', - 'target' : 'SysEmuTarget' }, - 'discriminator' : 'target', - 'data' : { 's390x' : 'CpuInfoS390' } } - -## -# @query-cpus-fast: -# -# Returns information about all virtual CPUs. This command does not -# incur a performance penalty and should be used in production -# instead of query-cpus. -# -# Returns: list of @CpuInfoFast -# -# Since: 2.12 -# -# Example: -# -# -> { "execute": "query-cpus-fast" } -# <- { "return": [ -# { -# "thread-id": 25627, -# "props": { -# "core-id": 0, -# "thread-id": 0, -# "socket-id": 0 -# }, -# "qom-path": "/machine/unattached/device[0]", -# "arch":"x86", -# "target":"x86_64", -# "cpu-index": 0 -# }, -# { -# "thread-id": 25628, -# "props": { -# "core-id": 0, -# "thread-id": 0, -# "socket-id": 1 -# }, -# "qom-path": "/machine/unattached/device[2]", -# "arch":"x86", -# "target":"x86_64", -# "cpu-index": 1 -# } -# ] -# } -## -{ 'command': 'query-cpus-fast', 'returns': [ 'CpuInfoFast' ] } - ## # @IOThreadInfo: # @@ -1105,29 +835,6 @@ ## { 'command': 'system_powerdown' } -## -# @cpu-add: -# -# Adds CPU with specified ID. -# -# @id: ID of CPU to be created, valid values [0..max_cpus) -# -# Returns: Nothing on success -# -# Since: 1.5 -# -# Note: This command is deprecated. The `device_add` command should be -# used instead. See the `query-hotpluggable-cpus` command for -# details. -# -# Example: -# -# -> { "execute": "cpu-add", "arguments": { "id": 2 } } -# <- { "return": {} } -# -## -{ 'command': 'cpu-add', 'data': {'id': 'int'} } - ## # @memsave: # @@ -1647,64 +1354,6 @@ ## { 'command': 'closefd', 'data': {'fdname': 'str'} } -## -# @MachineInfo: -# -# Information describing a machine. -# -# @name: the name of the machine -# -# @alias: an alias for the machine name -# -# @is-default: whether the machine is default -# -# @cpu-max: maximum number of CPUs supported by the machine type -# (since 1.5.0) -# -# @hotpluggable-cpus: cpu hotplug via -device is supported (since 2.7.0) -# -# Since: 1.2.0 -## -{ 'struct': 'MachineInfo', - 'data': { 'name': 'str', '*alias': 'str', - '*is-default': 'bool', 'cpu-max': 'int', - 'hotpluggable-cpus': 'bool'} } - -## -# @query-machines: -# -# Return a list of supported machines -# -# Returns: a list of MachineInfo -# -# Since: 1.2.0 -## -{ 'command': 'query-machines', 'returns': ['MachineInfo'] } - -## -# @CurrentMachineParams: -# -# Information describing the running machine parameters. -# -# @wakeup-suspend-support: true if the machine supports wake up from -# suspend -# -# Since: 4.0 -## -{ 'struct': 'CurrentMachineParams', - 'data': { 'wakeup-suspend-support': 'bool'} } - -## -# @query-current-machine: -# -# Return information on the current virtual machine. -# -# Returns: CurrentMachineParams -# -# Since: 4.0 -## -{ 'command': 'query-current-machine', 'returns': 'CurrentMachineParams' } - ## # @MemoryInfo: # @@ -2132,226 +1781,6 @@ 'returns': ['CommandLineOptionInfo'], 'allow-preconfig': true } -## -# @X86CPURegister32: -# -# A X86 32-bit register -# -# Since: 1.5 -## -{ 'enum': 'X86CPURegister32', - 'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] } - -## -# @X86CPUFeatureWordInfo: -# -# Information about a X86 CPU feature word -# -# @cpuid-input-eax: Input EAX value for CPUID instruction for that feature word -# -# @cpuid-input-ecx: Input ECX value for CPUID instruction for that -# feature word -# -# @cpuid-register: Output register containing the feature bits -# -# @features: value of output register, containing the feature bits -# -# Since: 1.5 -## -{ 'struct': 'X86CPUFeatureWordInfo', - 'data': { 'cpuid-input-eax': 'int', - '*cpuid-input-ecx': 'int', - 'cpuid-register': 'X86CPURegister32', - 'features': 'int' } } - -## -# @DummyForceArrays: -# -# Not used by QMP; hack to let us use X86CPUFeatureWordInfoList internally -# -# Since: 2.5 -## -{ 'struct': 'DummyForceArrays', - 'data': { 'unused': ['X86CPUFeatureWordInfo'] } } - - -## -# @NumaOptionsType: -# -# @node: NUMA nodes configuration -# -# @dist: NUMA distance configuration (since 2.10) -# -# @cpu: property based CPU(s) to node mapping (Since: 2.10) -# -# Since: 2.1 -## -{ 'enum': 'NumaOptionsType', - 'data': [ 'node', 'dist', 'cpu' ] } - -## -# @NumaOptions: -# -# A discriminated record of NUMA options. (for OptsVisitor) -# -# Since: 2.1 -## -{ 'union': 'NumaOptions', - 'base': { 'type': 'NumaOptionsType' }, - 'discriminator': 'type', - 'data': { - 'node': 'NumaNodeOptions', - 'dist': 'NumaDistOptions', - 'cpu': 'NumaCpuOptions' }} - -## -# @NumaNodeOptions: -# -# Create a guest NUMA node. (for OptsVisitor) -# -# @nodeid: NUMA node ID (increase by 1 from 0 if omitted) -# -# @cpus: VCPUs belonging to this node (assign VCPUS round-robin -# if omitted) -# -# @mem: memory size of this node; mutually exclusive with @memdev. -# Equally divide total memory among nodes if both @mem and @memdev are -# omitted. -# -# @memdev: memory backend object. If specified for one node, -# it must be specified for all nodes. -# -# Since: 2.1 -## -{ 'struct': 'NumaNodeOptions', - 'data': { - '*nodeid': 'uint16', - '*cpus': ['uint16'], - '*mem': 'size', - '*memdev': 'str' }} - -## -# @NumaDistOptions: -# -# Set the distance between 2 NUMA nodes. -# -# @src: source NUMA node. -# -# @dst: destination NUMA node. -# -# @val: NUMA distance from source node to destination node. -# When a node is unreachable from another node, set the distance -# between them to 255. -# -# Since: 2.10 -## -{ 'struct': 'NumaDistOptions', - 'data': { - 'src': 'uint16', - 'dst': 'uint16', - 'val': 'uint8' }} - -## -# @NumaCpuOptions: -# -# Option "-numa cpu" overrides default cpu to node mapping. -# It accepts the same set of cpu properties as returned by -# query-hotpluggable-cpus[].props, where node-id could be used to -# override default node mapping. -# -# Since: 2.10 -## -{ 'struct': 'NumaCpuOptions', - 'base': 'CpuInstanceProperties', - 'data' : {} } - -## -# @HostMemPolicy: -# -# Host memory policy types -# -# @default: restore default policy, remove any nondefault policy -# -# @preferred: set the preferred host nodes for allocation -# -# @bind: a strict policy that restricts memory allocation to the -# host nodes specified -# -# @interleave: memory allocations are interleaved across the set -# of host nodes specified -# -# Since: 2.1 -## -{ 'enum': 'HostMemPolicy', - 'data': [ 'default', 'preferred', 'bind', 'interleave' ] } - -## -# @Memdev: -# -# Information about memory backend -# -# @id: backend's ID if backend has 'id' property (since 2.9) -# -# @size: memory backend size -# -# @merge: enables or disables memory merge support -# -# @dump: includes memory backend's memory in a core dump or not -# -# @prealloc: enables or disables memory preallocation -# -# @host-nodes: host nodes for its memory policy -# -# @policy: memory policy of memory backend -# -# Since: 2.1 -## -{ 'struct': 'Memdev', - 'data': { - '*id': 'str', - 'size': 'size', - 'merge': 'bool', - 'dump': 'bool', - 'prealloc': 'bool', - 'host-nodes': ['uint16'], - 'policy': 'HostMemPolicy' }} - -## -# @query-memdev: -# -# Returns information for all memory backends. -# -# Returns: a list of @Memdev. -# -# Since: 2.1 -# -# Example: -# -# -> { "execute": "query-memdev" } -# <- { "return": [ -# { -# "id": "mem1", -# "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'], 'allow-preconfig': true } - ## # @PCDIMMDeviceInfo: # @@ -2560,109 +1989,6 @@ ## { 'command': 'xen-load-devices-state', 'data': {'filename': 'str'} } -## -# @CpuInstanceProperties: -# -# List of properties to be used for hotplugging a CPU instance, -# it should be passed by management with device_add command when -# a CPU is being hotplugged. -# -# @node-id: NUMA node ID the CPU belongs to -# @socket-id: socket number within node/board the CPU belongs to -# @core-id: core number within socket the CPU belongs to -# @thread-id: thread number within core the CPU belongs to -# -# Note: currently there are 4 properties that could be present -# but management should be prepared to pass through other -# properties with device_add command to allow for future -# interface extension. This also requires the filed names to be kept in -# sync with the properties passed to -device/device_add. -# -# Since: 2.7 -## -{ 'struct': 'CpuInstanceProperties', - 'data': { '*node-id': 'int', - '*socket-id': 'int', - '*core-id': 'int', - '*thread-id': 'int' - } -} - -## -# @HotpluggableCPU: -# -# @type: CPU object type for usage with device_add command -# @props: list of properties to be used for hotplugging CPU -# @vcpus-count: number of logical VCPU threads @HotpluggableCPU provides -# @qom-path: link to existing CPU object if CPU is present or -# omitted if CPU is not present. -# -# Since: 2.7 -## -{ 'struct': 'HotpluggableCPU', - 'data': { 'type': 'str', - 'vcpus-count': 'int', - 'props': 'CpuInstanceProperties', - '*qom-path': 'str' - } -} - -## -# @query-hotpluggable-cpus: -# -# TODO: Better documentation; currently there is none. -# -# Returns: a list of HotpluggableCPU objects. -# -# Since: 2.7 -# -# Example: -# -# For pseries machine type started with -smp 2,cores=2,maxcpus=4 -cpu POWER8: -# -# -> { "execute": "query-hotpluggable-cpus" } -# <- {"return": [ -# { "props": { "core": 8 }, "type": "POWER8-spapr-cpu-core", -# "vcpus-count": 1 }, -# { "props": { "core": 0 }, "type": "POWER8-spapr-cpu-core", -# "vcpus-count": 1, "qom-path": "/machine/unattached/device[0]"} -# ]}' -# -# For pc machine type started with -smp 1,maxcpus=2: -# -# -> { "execute": "query-hotpluggable-cpus" } -# <- {"return": [ -# { -# "type": "qemu64-x86_64-cpu", "vcpus-count": 1, -# "props": {"core-id": 0, "socket-id": 1, "thread-id": 0} -# }, -# { -# "qom-path": "/machine/unattached/device[0]", -# "type": "qemu64-x86_64-cpu", "vcpus-count": 1, -# "props": {"core-id": 0, "socket-id": 0, "thread-id": 0} -# } -# ]} -# -# For s390x-virtio-ccw machine type started with -smp 1,maxcpus=2 -cpu qemu -# (Since: 2.11): -# -# -> { "execute": "query-hotpluggable-cpus" } -# <- {"return": [ -# { -# "type": "qemu-s390x-cpu", "vcpus-count": 1, -# "props": { "core-id": 1 } -# }, -# { -# "qom-path": "/machine/unattached/device[0]", -# "type": "qemu-s390x-cpu", "vcpus-count": 1, -# "props": { "core-id": 0 } -# } -# ]} -# -## -{ 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'], - 'allow-preconfig': true } - ## # @GuidInfo: # @@ -2683,16 +2009,3 @@ ## { 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' } -## -# @set-numa-node: -# -# Runtime equivalent of '-numa' CLI option, available at -# preconfigure stage to configure numa mapping before initializing -# machine. -# -# Since 3.0 -## -{ 'command': 'set-numa-node', 'boxed': true, - 'data': 'NumaOptions', - 'allow-preconfig': true -} diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index d6cf90a85a..31611191db 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -99,6 +99,7 @@ { 'include': 'introspect.json' } { 'include': 'qom.json' } { 'include': 'qdev.json' } +{ 'include': 'machine.json' } { 'include': 'misc.json' } { 'include': 'target.json' } { 'include': 'audio.json' } diff --git a/target/i386/cpu.c b/target/i386/cpu.c index da6eb67cfb..147ff981ed 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -36,7 +36,7 @@ #include "qemu/option.h" #include "qemu/config-file.h" #include "qapi/error.h" -#include "qapi/qapi-visit-misc.h" +#include "qapi/qapi-visit-machine.h" #include "qapi/qapi-visit-run-state.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qerror.h" diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c index f2d93644d5..8540e7a2cb 100644 --- a/target/s390x/cpu.c +++ b/target/s390x/cpu.c @@ -31,7 +31,7 @@ #include "qemu/module.h" #include "trace.h" #include "qapi/visitor.h" -#include "qapi/qapi-visit-misc.h" +#include "qapi/qapi-types-machine.h" #include "qapi/qapi-visit-run-state.h" #include "sysemu/hw_accel.h" #include "hw/qdev-properties.h" diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c index ce49a792fc..8348b7035e 100644 --- a/target/s390x/sigp.c +++ b/target/s390x/sigp.c @@ -17,7 +17,7 @@ #include "sysemu/sysemu.h" #include "sysemu/tcg.h" #include "trace.h" -#include "qapi/qapi-types-misc.h" +#include "qapi/qapi-types-machine.h" QemuMutex qemu_sigp_mutex; diff --git a/vl.c b/vl.c index 99a56b5556..0eb9b2c8bd 100644 --- a/vl.c +++ b/vl.c @@ -125,7 +125,7 @@ int main(int argc, char **argv) #include "qapi/qapi-visit-block-core.h" #include "qapi/qapi-visit-ui.h" #include "qapi/qapi-commands-block-core.h" -#include "qapi/qapi-commands-misc.h" +#include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-run-state.h" #include "qapi/qapi-commands-ui.h" #include "qapi/qmp/qerror.h" -- cgit 1.4.1 From 55225c853ab8ba948ef70634cee6fbca0d8c67dc Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:44 +0200 Subject: hw/core: Collect HMP command handlers in hw/core/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the HMP handlers related to qapi/machine.json to hw/core/machine-hmp-cmds.c, where they are covered by MAINTAINERS section "Machine core", just like qapi/machine.json. Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: "Dr. David Alan Gilbert" Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-12-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Dr. David Alan Gilbert --- hw/core/Makefile.objs | 1 + hw/core/machine-hmp-cmds.c | 164 +++++++++++++++++++++++++++++++++++++++++++++ include/monitor/hmp.h | 1 + monitor/hmp-cmds.c | 111 ------------------------------ monitor/misc.c | 32 +-------- 5 files changed, 168 insertions(+), 141 deletions(-) create mode 100644 hw/core/machine-hmp-cmds.c (limited to 'monitor/hmp-cmds.c') diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs index 99e7abe982..585b734358 100644 --- a/hw/core/Makefile.objs +++ b/hw/core/Makefile.objs @@ -25,3 +25,4 @@ common-obj-$(CONFIG_SOFTMMU) += null-machine.o obj-$(CONFIG_SOFTMMU) += machine-qmp-cmds.o obj-$(CONFIG_SOFTMMU) += numa.o +common-obj-$(CONFIG_SOFTMMU) += machine-hmp-cmds.o diff --git a/hw/core/machine-hmp-cmds.c b/hw/core/machine-hmp-cmds.c new file mode 100644 index 0000000000..7fa6075f1e --- /dev/null +++ b/hw/core/machine-hmp-cmds.c @@ -0,0 +1,164 @@ +/* + * HMP commands related to machines and CPUs + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Anthony Liguori + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Contributions after 2012-01-13 are licensed under the terms of the + * GNU GPL, version 2 or (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "monitor/hmp.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qapi/qapi-builtin-visit.h" +#include "qapi/qapi-commands-machine.h" +#include "qapi/qmp/qdict.h" +#include "qapi/string-output-visitor.h" +#include "qemu/error-report.h" +#include "sysemu/numa.h" + +void hmp_info_cpus(Monitor *mon, const QDict *qdict) +{ + CpuInfoFastList *cpu_list, *cpu; + + cpu_list = qmp_query_cpus_fast(NULL); + + for (cpu = cpu_list; cpu; cpu = cpu->next) { + int active = ' '; + + if (cpu->value->cpu_index == monitor_get_cpu_index()) { + active = '*'; + } + + monitor_printf(mon, "%c CPU #%" PRId64 ":", active, + cpu->value->cpu_index); + monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id); + } + + qapi_free_CpuInfoFastList(cpu_list); +} + +void hmp_cpu_add(Monitor *mon, const QDict *qdict) +{ + int cpuid; + Error *err = NULL; + + error_report("cpu_add is deprecated, please use device_add instead"); + + cpuid = qdict_get_int(qdict, "id"); + qmp_cpu_add(cpuid, &err); + hmp_handle_error(mon, &err); +} + +void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err); + HotpluggableCPUList *saved = l; + CpuInstanceProperties *c; + + if (err != NULL) { + hmp_handle_error(mon, &err); + return; + } + + monitor_printf(mon, "Hotpluggable CPUs:\n"); + while (l) { + monitor_printf(mon, " type: \"%s\"\n", l->value->type); + monitor_printf(mon, " vcpus_count: \"%" PRIu64 "\"\n", + l->value->vcpus_count); + if (l->value->has_qom_path) { + monitor_printf(mon, " qom_path: \"%s\"\n", l->value->qom_path); + } + + c = l->value->props; + monitor_printf(mon, " CPUInstance Properties:\n"); + if (c->has_node_id) { + monitor_printf(mon, " node-id: \"%" PRIu64 "\"\n", c->node_id); + } + if (c->has_socket_id) { + monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->socket_id); + } + if (c->has_core_id) { + monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); + } + if (c->has_thread_id) { + monitor_printf(mon, " thread-id: \"%" PRIu64 "\"\n", c->thread_id); + } + + l = l->next; + } + + qapi_free_HotpluggableCPUList(saved); +} + +void hmp_info_memdev(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + MemdevList *memdev_list = qmp_query_memdev(&err); + MemdevList *m = memdev_list; + Visitor *v; + char *str; + + while (m) { + v = string_output_visitor_new(false, &str); + visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL); + monitor_printf(mon, "memory backend: %s\n", m->value->id); + monitor_printf(mon, " size: %" PRId64 "\n", m->value->size); + monitor_printf(mon, " merge: %s\n", + m->value->merge ? "true" : "false"); + monitor_printf(mon, " dump: %s\n", + m->value->dump ? "true" : "false"); + monitor_printf(mon, " prealloc: %s\n", + m->value->prealloc ? "true" : "false"); + monitor_printf(mon, " policy: %s\n", + HostMemPolicy_str(m->value->policy)); + visit_complete(v, &str); + monitor_printf(mon, " host nodes: %s\n", str); + + g_free(str); + visit_free(v); + m = m->next; + } + + monitor_printf(mon, "\n"); + + qapi_free_MemdevList(memdev_list); + hmp_handle_error(mon, &err); +} + +void hmp_info_numa(Monitor *mon, const QDict *qdict) +{ + int i; + NumaNodeMem *node_mem; + CpuInfoList *cpu_list, *cpu; + + cpu_list = qmp_query_cpus(&error_abort); + node_mem = g_new0(NumaNodeMem, nb_numa_nodes); + + query_numa_node_mem(node_mem); + monitor_printf(mon, "%d nodes\n", nb_numa_nodes); + for (i = 0; i < nb_numa_nodes; i++) { + monitor_printf(mon, "node %d cpus:", i); + for (cpu = cpu_list; cpu; cpu = cpu->next) { + if (cpu->value->has_props && cpu->value->props->has_node_id && + cpu->value->props->node_id == i) { + monitor_printf(mon, " %" PRIi64, cpu->value->CPU); + } + } + monitor_printf(mon, "\n"); + monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i, + node_mem[i].node_mem >> 20); + monitor_printf(mon, "node %d plugged: %" PRId64 " MB\n", i, + node_mem[i].node_plugged_mem >> 20); + } + qapi_free_CpuInfoList(cpu_list); + g_free(node_mem); +} diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h index b36ebccd29..a0e9511440 100644 --- a/include/monitor/hmp.h +++ b/include/monitor/hmp.h @@ -117,6 +117,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_info_memdev(Monitor *mon, const QDict *qdict); +void hmp_info_numa(Monitor *mon, const QDict *qdict); void hmp_info_memory_devices(Monitor *mon, const QDict *qdict); void hmp_qom_list(Monitor *mon, const QDict *qdict); void hmp_qom_set(Monitor *mon, const QDict *qdict); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 789f763938..ea8ae2966e 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -31,7 +31,6 @@ #include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-commands-block.h" #include "qapi/qapi-commands-char.h" -#include "qapi/qapi-commands-machine.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" @@ -457,27 +456,6 @@ void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict) qmp_query_migrate_cache_size(NULL) >> 10); } -void hmp_info_cpus(Monitor *mon, const QDict *qdict) -{ - CpuInfoFastList *cpu_list, *cpu; - - cpu_list = qmp_query_cpus_fast(NULL); - - for (cpu = cpu_list; cpu; cpu = cpu->next) { - int active = ' '; - - if (cpu->value->cpu_index == monitor_get_cpu_index()) { - active = '*'; - } - - monitor_printf(mon, "%c CPU #%" PRId64 ":", active, - cpu->value->cpu_index); - monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id); - } - - qapi_free_CpuInfoFastList(cpu_list); -} - static void print_block_info(Monitor *mon, BlockInfo *info, BlockDeviceInfo *inserted, bool verbose) { @@ -2472,18 +2450,6 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); } -void hmp_cpu_add(Monitor *mon, const QDict *qdict) -{ - int cpuid; - Error *err = NULL; - - error_report("cpu_add is deprecated, please use device_add instead"); - - cpuid = qdict_get_int(qdict, "id"); - qmp_cpu_add(cpuid, &err); - hmp_handle_error(mon, &err); -} - void hmp_chardev_add(Monitor *mon, const QDict *qdict) { const char *args = qdict_get_str(qdict, "args"); @@ -2615,41 +2581,6 @@ void hmp_object_del(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); } -void hmp_info_memdev(Monitor *mon, const QDict *qdict) -{ - Error *err = NULL; - MemdevList *memdev_list = qmp_query_memdev(&err); - MemdevList *m = memdev_list; - Visitor *v; - char *str; - - while (m) { - v = string_output_visitor_new(false, &str); - visit_type_uint16List(v, NULL, &m->value->host_nodes, NULL); - monitor_printf(mon, "memory backend: %s\n", m->value->id); - monitor_printf(mon, " size: %" PRId64 "\n", m->value->size); - monitor_printf(mon, " merge: %s\n", - m->value->merge ? "true" : "false"); - monitor_printf(mon, " dump: %s\n", - m->value->dump ? "true" : "false"); - monitor_printf(mon, " prealloc: %s\n", - m->value->prealloc ? "true" : "false"); - monitor_printf(mon, " policy: %s\n", - HostMemPolicy_str(m->value->policy)); - visit_complete(v, &str); - monitor_printf(mon, " host nodes: %s\n", str); - - g_free(str); - visit_free(v); - m = m->next; - } - - monitor_printf(mon, "\n"); - - qapi_free_MemdevList(memdev_list); - hmp_handle_error(mon, &err); -} - void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) { Error *err = NULL; @@ -3039,48 +2970,6 @@ void hmp_info_ramblock(Monitor *mon, const QDict *qdict) ram_block_dump(mon); } -void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict) -{ - Error *err = NULL; - HotpluggableCPUList *l = qmp_query_hotpluggable_cpus(&err); - HotpluggableCPUList *saved = l; - CpuInstanceProperties *c; - - if (err != NULL) { - hmp_handle_error(mon, &err); - return; - } - - monitor_printf(mon, "Hotpluggable CPUs:\n"); - while (l) { - monitor_printf(mon, " type: \"%s\"\n", l->value->type); - monitor_printf(mon, " vcpus_count: \"%" PRIu64 "\"\n", - l->value->vcpus_count); - if (l->value->has_qom_path) { - monitor_printf(mon, " qom_path: \"%s\"\n", l->value->qom_path); - } - - c = l->value->props; - monitor_printf(mon, " CPUInstance Properties:\n"); - if (c->has_node_id) { - monitor_printf(mon, " node-id: \"%" PRIu64 "\"\n", c->node_id); - } - if (c->has_socket_id) { - monitor_printf(mon, " socket-id: \"%" PRIu64 "\"\n", c->socket_id); - } - if (c->has_core_id) { - monitor_printf(mon, " core-id: \"%" PRIu64 "\"\n", c->core_id); - } - if (c->has_thread_id) { - monitor_printf(mon, " thread-id: \"%" PRIu64 "\"\n", c->thread_id); - } - - l = l->next; - } - - qapi_free_HotpluggableCPUList(saved); -} - void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict) { Error *err = NULL; diff --git a/monitor/misc.c b/monitor/misc.c index 45f3f55a4d..00338c002a 100644 --- a/monitor/misc.c +++ b/monitor/misc.c @@ -36,7 +36,6 @@ #include "net/slirp.h" #include "chardev/char-mux.h" #include "ui/qemu-spice.h" -#include "sysemu/numa.h" #include "qemu/config-file.h" #include "qemu/ctype.h" #include "ui/console.h" @@ -48,6 +47,8 @@ #include "sysemu/hw_accel.h" #include "authz/list.h" #include "qapi/util.h" +#include "sysemu/blockdev.h" +#include "sysemu/sysemu.h" #include "sysemu/tcg.h" #include "sysemu/tpm.h" #include "qapi/qmp/qdict.h" @@ -1081,35 +1082,6 @@ static void hmp_info_mtree(Monitor *mon, const QDict *qdict) mtree_info(flatview, dispatch_tree, owner); } -static void hmp_info_numa(Monitor *mon, const QDict *qdict) -{ - int i; - NumaNodeMem *node_mem; - CpuInfoList *cpu_list, *cpu; - - cpu_list = qmp_query_cpus(&error_abort); - node_mem = g_new0(NumaNodeMem, nb_numa_nodes); - - query_numa_node_mem(node_mem); - monitor_printf(mon, "%d nodes\n", nb_numa_nodes); - for (i = 0; i < nb_numa_nodes; i++) { - monitor_printf(mon, "node %d cpus:", i); - for (cpu = cpu_list; cpu; cpu = cpu->next) { - if (cpu->value->has_props && cpu->value->props->has_node_id && - cpu->value->props->node_id == i) { - monitor_printf(mon, " %" PRIi64, cpu->value->CPU); - } - } - monitor_printf(mon, "\n"); - monitor_printf(mon, "node %d size: %" PRId64 " MB\n", i, - node_mem[i].node_mem >> 20); - monitor_printf(mon, "node %d plugged: %" PRId64 " MB\n", i, - node_mem[i].node_plugged_mem >> 20); - } - qapi_free_CpuInfoList(cpu_list); - g_free(node_mem); -} - #ifdef CONFIG_PROFILER int64_t dev_time; -- cgit 1.4.1 From d06b747bd55059f6e5bde64f105477929f8275fb Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:47 +0200 Subject: qapi: Split dump.json off misc.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move commands dump-guest-memory, query-dump, query-dump-guest-memory-capability with their types from misc.json to new dump.json. Add dump.json to MAINTAINERS section "Dump". Cc: Marc-André Lureau Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-15-armbru@redhat.com> Reviewed-by: Marc-André Lureau Reviewed-by: Daniel P. Berrangé --- MAINTAINERS | 1 + dump.c | 4 +- include/sysemu/dump.h | 2 +- monitor/hmp-cmds.c | 1 + qapi/Makefile.objs | 2 +- qapi/dump.json | 200 ++++++++++++++++++++++++++++++++++++++++++++++++++ qapi/misc.json | 192 ------------------------------------------------ qapi/qapi-schema.json | 1 + 8 files changed, 207 insertions(+), 196 deletions(-) create mode 100644 qapi/dump.json (limited to 'monitor/hmp-cmds.c') diff --git a/MAINTAINERS b/MAINTAINERS index 2eb851cbdd..4dbc9c212c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1855,6 +1855,7 @@ F: hw/misc/vmcoreinfo.c F: include/hw/misc/vmcoreinfo.h F: include/sysemu/dump-arch.h F: include/sysemu/dump.h +F: qapi/dump.json F: scripts/dump-guest-memory.py F: stubs/dump.c diff --git a/dump.c b/dump.c index e99554628c..c7b2301652 100644 --- a/dump.c +++ b/dump.c @@ -24,8 +24,8 @@ #include "sysemu/memory_mapping.h" #include "sysemu/cpus.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc.h" -#include "qapi/qapi-events-misc.h" +#include "qapi/qapi-commands-dump.h" +#include "qapi/qapi-events-dump.h" #include "qapi/qmp/qerror.h" #include "qemu/error-report.h" #include "hw/misc/vmcoreinfo.h" diff --git a/include/sysemu/dump.h b/include/sysemu/dump.h index d824bc0941..250143cb5a 100644 --- a/include/sysemu/dump.h +++ b/include/sysemu/dump.h @@ -14,7 +14,7 @@ #ifndef DUMP_H #define DUMP_H -#include "qapi/qapi-types-misc.h" +#include "qapi/qapi-types-dump.h" #define MAKEDUMPFILE_SIGNATURE "makedumpfile" #define MAX_SIZE_MDF_HEADER (4096) /* max size of makedumpfile_header */ diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index ea8ae2966e..18ffeb7017 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -31,6 +31,7 @@ #include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-commands-block.h" #include "qapi/qapi-commands-char.h" +#include "qapi/qapi-commands-dump.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs index c0be6fcd3e..c5a29e86e2 100644 --- a/qapi/Makefile.objs +++ b/qapi/Makefile.objs @@ -6,7 +6,7 @@ util-obj-y += qmp-event.o util-obj-y += qapi-util.o QAPI_COMMON_MODULES = audio authz block-core block char common crypto -QAPI_COMMON_MODULES += introspect job machine migration misc net +QAPI_COMMON_MODULES += dump introspect job machine migration misc net QAPI_COMMON_MODULES += qdev qom rdma rocker run-state sockets tpm QAPI_COMMON_MODULES += trace transaction ui QAPI_TARGET_MODULES = machine-target misc-target diff --git a/qapi/dump.json b/qapi/dump.json new file mode 100644 index 0000000000..2b35409a7b --- /dev/null +++ b/qapi/dump.json @@ -0,0 +1,200 @@ +# -*- Mode: Python -*- +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# = Dump guest memory +## + +## +# @DumpGuestMemoryFormat: +# +# An enumeration of guest-memory-dump's format. +# +# @elf: elf format +# +# @kdump-zlib: kdump-compressed format with zlib-compressed +# +# @kdump-lzo: kdump-compressed format with lzo-compressed +# +# @kdump-snappy: kdump-compressed format with snappy-compressed +# +# @win-dmp: Windows full crashdump format, +# can be used instead of ELF converting (since 2.13) +# +# Since: 2.0 +## +{ 'enum': 'DumpGuestMemoryFormat', + 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy', 'win-dmp' ] } + +## +# @dump-guest-memory: +# +# Dump guest's memory to vmcore. It is a synchronous operation that can take +# very long depending on the amount of guest memory. +# +# @paging: if true, do paging to get guest's memory mapping. This allows +# using gdb to process the core file. +# +# IMPORTANT: this option can make QEMU allocate several gigabytes +# of RAM. This can happen for a large guest, or a +# malicious guest pretending to be large. +# +# Also, paging=true has the following limitations: +# +# 1. The guest may be in a catastrophic state or can have corrupted +# memory, which cannot be trusted +# 2. The guest can be in real-mode even if paging is enabled. For +# example, the guest uses ACPI to sleep, and ACPI sleep state +# goes in real-mode +# 3. Currently only supported on i386 and x86_64. +# +# @protocol: the filename or file descriptor of the vmcore. The supported +# protocols are: +# +# 1. file: the protocol starts with "file:", and the following +# string is the file's path. +# 2. fd: the protocol starts with "fd:", and the following string +# is the fd's name. +# +# @detach: if true, QMP will return immediately rather than +# waiting for the dump to finish. The user can track progress +# using "query-dump". (since 2.6). +# +# @begin: if specified, the starting physical address. +# +# @length: if specified, the memory size, in bytes. If you don't +# want to dump all guest's memory, please specify the start @begin +# and @length +# +# @format: if specified, the format of guest memory dump. But non-elf +# format is conflict with paging and filter, ie. @paging, @begin and +# @length is not allowed to be specified with non-elf @format at the +# same time (since 2.0) +# +# Note: All boolean arguments default to false +# +# 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', '*detach': 'bool', + '*begin': 'int', '*length': 'int', + '*format': 'DumpGuestMemoryFormat'} } + +## +# @DumpStatus: +# +# Describe the status of a long-running background guest memory dump. +# +# @none: no dump-guest-memory has started yet. +# +# @active: there is one dump running in background. +# +# @completed: the last dump has finished successfully. +# +# @failed: the last dump has failed. +# +# Since: 2.6 +## +{ 'enum': 'DumpStatus', + 'data': [ 'none', 'active', 'completed', 'failed' ] } + +## +# @DumpQueryResult: +# +# The result format for 'query-dump'. +# +# @status: enum of @DumpStatus, which shows current dump status +# +# @completed: bytes written in latest dump (uncompressed) +# +# @total: total bytes to be written in latest dump (uncompressed) +# +# Since: 2.6 +## +{ 'struct': 'DumpQueryResult', + 'data': { 'status': 'DumpStatus', + 'completed': 'int', + 'total': 'int' } } + +## +# @query-dump: +# +# Query latest dump status. +# +# Returns: A @DumpStatus object showing the dump status. +# +# Since: 2.6 +# +# Example: +# +# -> { "execute": "query-dump" } +# <- { "return": { "status": "active", "completed": 1024000, +# "total": 2048000 } } +# +## +{ 'command': 'query-dump', 'returns': 'DumpQueryResult' } + +## +# @DUMP_COMPLETED: +# +# Emitted when background dump has completed +# +# @result: final dump status +# +# @error: human-readable error string that provides +# hint on why dump failed. Only presents on failure. The +# user should not try to interpret the error string. +# +# Since: 2.6 +# +# Example: +# +# { "event": "DUMP_COMPLETED", +# "data": {"result": {"total": 1090650112, "status": "completed", +# "completed": 1090650112} } } +# +## +{ 'event': 'DUMP_COMPLETED' , + 'data': { 'result': 'DumpQueryResult', '*error': 'str' } } + +## +# @DumpGuestMemoryCapability: +# +# A list of the available formats for dump-guest-memory +# +# Since: 2.0 +## +{ 'struct': 'DumpGuestMemoryCapability', + 'data': { + 'formats': ['DumpGuestMemoryFormat'] } } + +## +# @query-dump-guest-memory-capability: +# +# Returns the available formats for dump-guest-memory +# +# Returns: A @DumpGuestMemoryCapability object listing available formats for +# 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' } diff --git a/qapi/misc.json b/qapi/misc.json index d7db863c81..31427d45a6 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -1117,198 +1117,6 @@ ## { 'command': 'xen-set-global-dirty-log', 'data': { 'enable': 'bool' } } -## -# @DumpGuestMemoryFormat: -# -# An enumeration of guest-memory-dump's format. -# -# @elf: elf format -# -# @kdump-zlib: kdump-compressed format with zlib-compressed -# -# @kdump-lzo: kdump-compressed format with lzo-compressed -# -# @kdump-snappy: kdump-compressed format with snappy-compressed -# -# @win-dmp: Windows full crashdump format, -# can be used instead of ELF converting (since 2.13) -# -# Since: 2.0 -## -{ 'enum': 'DumpGuestMemoryFormat', - 'data': [ 'elf', 'kdump-zlib', 'kdump-lzo', 'kdump-snappy', 'win-dmp' ] } - -## -# @dump-guest-memory: -# -# Dump guest's memory to vmcore. It is a synchronous operation that can take -# very long depending on the amount of guest memory. -# -# @paging: if true, do paging to get guest's memory mapping. This allows -# using gdb to process the core file. -# -# IMPORTANT: this option can make QEMU allocate several gigabytes -# of RAM. This can happen for a large guest, or a -# malicious guest pretending to be large. -# -# Also, paging=true has the following limitations: -# -# 1. The guest may be in a catastrophic state or can have corrupted -# memory, which cannot be trusted -# 2. The guest can be in real-mode even if paging is enabled. For -# example, the guest uses ACPI to sleep, and ACPI sleep state -# goes in real-mode -# 3. Currently only supported on i386 and x86_64. -# -# @protocol: the filename or file descriptor of the vmcore. The supported -# protocols are: -# -# 1. file: the protocol starts with "file:", and the following -# string is the file's path. -# 2. fd: the protocol starts with "fd:", and the following string -# is the fd's name. -# -# @detach: if true, QMP will return immediately rather than -# waiting for the dump to finish. The user can track progress -# using "query-dump". (since 2.6). -# -# @begin: if specified, the starting physical address. -# -# @length: if specified, the memory size, in bytes. If you don't -# want to dump all guest's memory, please specify the start @begin -# and @length -# -# @format: if specified, the format of guest memory dump. But non-elf -# format is conflict with paging and filter, ie. @paging, @begin and -# @length is not allowed to be specified with non-elf @format at the -# same time (since 2.0) -# -# Note: All boolean arguments default to false -# -# 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', '*detach': 'bool', - '*begin': 'int', '*length': 'int', - '*format': 'DumpGuestMemoryFormat'} } - -## -# @DumpStatus: -# -# Describe the status of a long-running background guest memory dump. -# -# @none: no dump-guest-memory has started yet. -# -# @active: there is one dump running in background. -# -# @completed: the last dump has finished successfully. -# -# @failed: the last dump has failed. -# -# Since: 2.6 -## -{ 'enum': 'DumpStatus', - 'data': [ 'none', 'active', 'completed', 'failed' ] } - -## -# @DumpQueryResult: -# -# The result format for 'query-dump'. -# -# @status: enum of @DumpStatus, which shows current dump status -# -# @completed: bytes written in latest dump (uncompressed) -# -# @total: total bytes to be written in latest dump (uncompressed) -# -# Since: 2.6 -## -{ 'struct': 'DumpQueryResult', - 'data': { 'status': 'DumpStatus', - 'completed': 'int', - 'total': 'int' } } - -## -# @query-dump: -# -# Query latest dump status. -# -# Returns: A @DumpStatus object showing the dump status. -# -# Since: 2.6 -# -# Example: -# -# -> { "execute": "query-dump" } -# <- { "return": { "status": "active", "completed": 1024000, -# "total": 2048000 } } -# -## -{ 'command': 'query-dump', 'returns': 'DumpQueryResult' } - -## -# @DUMP_COMPLETED: -# -# Emitted when background dump has completed -# -# @result: final dump status -# -# @error: human-readable error string that provides -# hint on why dump failed. Only presents on failure. The -# user should not try to interpret the error string. -# -# Since: 2.6 -# -# Example: -# -# { "event": "DUMP_COMPLETED", -# "data": {"result": {"total": 1090650112, "status": "completed", -# "completed": 1090650112} } } -# -## -{ 'event': 'DUMP_COMPLETED' , - 'data': { 'result': 'DumpQueryResult', '*error': 'str' } } - -## -# @DumpGuestMemoryCapability: -# -# A list of the available formats for dump-guest-memory -# -# Since: 2.0 -## -{ 'struct': 'DumpGuestMemoryCapability', - 'data': { - 'formats': ['DumpGuestMemoryFormat'] } } - -## -# @query-dump-guest-memory-capability: -# -# Returns the available formats for dump-guest-memory -# -# Returns: A @DumpGuestMemoryCapability object listing available formats for -# 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' } - ## # @getfd: # diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json index bcfac85074..38af54d6b3 100644 --- a/qapi/qapi-schema.json +++ b/qapi/qapi-schema.json @@ -86,6 +86,7 @@ { 'include': 'crypto.json' } { 'include': 'block.json' } { 'include': 'char.json' } +{ 'include': 'dump.json' } { 'include': 'job.json' } { 'include': 'net.json' } { 'include': 'rdma.json' } -- cgit 1.4.1 From 2608b3df8f9cd91baee9d04e246a0255dbb612db Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 19 Jun 2019 22:10:50 +0200 Subject: dump: Move HMP command handlers to dump/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the HMP handlers related to qapi/dump.json to dump/dump-hmp-cmds.c, where they are covered by MAINTAINERS section "Dump", just like qapi/dump.json. Cc: Marc-André Lureau Cc: "Dr. David Alan Gilbert" Signed-off-by: Markus Armbruster Message-Id: <20190619201050.19040-18-armbru@redhat.com> Reviewed-by: Daniel P. Berrangé Reviewed-by: Dr. David Alan Gilbert [Commit message typo fixed] --- Makefile.objs | 1 + dump/Makefile.objs | 1 + dump/dump-hmp-cmds.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ monitor/hmp-cmds.c | 76 --------------------------------------------- 4 files changed, 90 insertions(+), 76 deletions(-) create mode 100644 dump/dump-hmp-cmds.c (limited to 'monitor/hmp-cmds.c') diff --git a/Makefile.objs b/Makefile.objs index fe4f339b7c..6a143dcd57 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -45,6 +45,7 @@ io-obj-y = io/ ifeq ($(CONFIG_SOFTMMU),y) common-obj-y = blockdev.o blockdev-nbd.o block/ common-obj-y += bootdevice.o iothread.o +common-obj-y += dump/ common-obj-y += job-qmp.o common-obj-y += monitor/ common-obj-y += net/ diff --git a/dump/Makefile.objs b/dump/Makefile.objs index ea6b074967..d2a5db3b81 100644 --- a/dump/Makefile.objs +++ b/dump/Makefile.objs @@ -1,2 +1,3 @@ obj-y += dump.o +common-obj-y += dump-hmp-cmds.o obj-$(TARGET_X86_64) += win_dump.o diff --git a/dump/dump-hmp-cmds.c b/dump/dump-hmp-cmds.c new file mode 100644 index 0000000000..3dbf44372c --- /dev/null +++ b/dump/dump-hmp-cmds.c @@ -0,0 +1,88 @@ +/* + * Human Monitor Interface commands + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "monitor/hmp.h" +#include "monitor/monitor.h" +#include "qapi/error.h" +#include "qapi/qapi-commands-dump.h" +#include "qapi/qmp/qdict.h" + +void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) +{ + Error *err = NULL; + bool win_dmp = qdict_get_try_bool(qdict, "windmp", false); + bool paging = qdict_get_try_bool(qdict, "paging", false); + bool zlib = qdict_get_try_bool(qdict, "zlib", false); + bool lzo = qdict_get_try_bool(qdict, "lzo", false); + bool snappy = qdict_get_try_bool(qdict, "snappy", false); + const char *file = qdict_get_str(qdict, "filename"); + bool has_begin = qdict_haskey(qdict, "begin"); + bool has_length = qdict_haskey(qdict, "length"); + bool has_detach = qdict_haskey(qdict, "detach"); + int64_t begin = 0; + int64_t length = 0; + bool detach = false; + enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF; + char *prot; + + if (zlib + lzo + snappy + win_dmp > 1) { + error_setg(&err, "only one of '-z|-l|-s|-w' can be set"); + hmp_handle_error(mon, &err); + return; + } + + if (win_dmp) { + dump_format = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; + } + + if (zlib) { + dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB; + } + + if (lzo) { + dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO; + } + + if (snappy) { + dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; + } + + if (has_begin) { + begin = qdict_get_int(qdict, "begin"); + } + if (has_length) { + length = qdict_get_int(qdict, "length"); + } + if (has_detach) { + detach = qdict_get_bool(qdict, "detach"); + } + + prot = g_strconcat("file:", file, NULL); + + qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin, + has_length, length, true, dump_format, &err); + hmp_handle_error(mon, &err); + g_free(prot); +} + +void hmp_info_dump(Monitor *mon, const QDict *qdict) +{ + DumpQueryResult *result = qmp_query_dump(NULL); + + assert(result && result->status < DUMP_STATUS__MAX); + monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status)); + + if (result->status == DUMP_STATUS_ACTIVE) { + float percent = 0; + assert(result->total != 0); + percent = 100.0 * result->completed / result->total; + monitor_printf(mon, "Finished: %.2f %%\n", percent); + } + + qapi_free_DumpQueryResult(result); +} diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 18ffeb7017..dc12ae6129 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -31,7 +31,6 @@ #include "qapi/qapi-builtin-visit.h" #include "qapi/qapi-commands-block.h" #include "qapi/qapi-commands-char.h" -#include "qapi/qapi-commands-dump.h" #include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-misc.h" #include "qapi/qapi-commands-net.h" @@ -2160,64 +2159,6 @@ void hmp_device_del(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); } -void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict) -{ - Error *err = NULL; - bool win_dmp = qdict_get_try_bool(qdict, "windmp", false); - bool paging = qdict_get_try_bool(qdict, "paging", false); - bool zlib = qdict_get_try_bool(qdict, "zlib", false); - bool lzo = qdict_get_try_bool(qdict, "lzo", false); - bool snappy = qdict_get_try_bool(qdict, "snappy", false); - const char *file = qdict_get_str(qdict, "filename"); - bool has_begin = qdict_haskey(qdict, "begin"); - bool has_length = qdict_haskey(qdict, "length"); - bool has_detach = qdict_haskey(qdict, "detach"); - int64_t begin = 0; - int64_t length = 0; - bool detach = false; - enum DumpGuestMemoryFormat dump_format = DUMP_GUEST_MEMORY_FORMAT_ELF; - char *prot; - - if (zlib + lzo + snappy + win_dmp > 1) { - error_setg(&err, "only one of '-z|-l|-s|-w' can be set"); - hmp_handle_error(mon, &err); - return; - } - - if (win_dmp) { - dump_format = DUMP_GUEST_MEMORY_FORMAT_WIN_DMP; - } - - if (zlib) { - dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_ZLIB; - } - - if (lzo) { - dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO; - } - - if (snappy) { - dump_format = DUMP_GUEST_MEMORY_FORMAT_KDUMP_SNAPPY; - } - - if (has_begin) { - begin = qdict_get_int(qdict, "begin"); - } - if (has_length) { - length = qdict_get_int(qdict, "length"); - } - if (has_detach) { - detach = qdict_get_bool(qdict, "detach"); - } - - prot = g_strconcat("file:", file, NULL); - - qmp_dump_guest_memory(paging, prot, true, detach, has_begin, begin, - has_length, length, true, dump_format, &err); - hmp_handle_error(mon, &err); - g_free(prot); -} - void hmp_netdev_add(Monitor *mon, const QDict *qdict) { Error *err = NULL; @@ -2949,23 +2890,6 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict) qapi_free_RockerOfDpaGroupList(list); } -void hmp_info_dump(Monitor *mon, const QDict *qdict) -{ - DumpQueryResult *result = qmp_query_dump(NULL); - - assert(result && result->status < DUMP_STATUS__MAX); - monitor_printf(mon, "Status: %s\n", DumpStatus_str(result->status)); - - if (result->status == DUMP_STATUS_ACTIVE) { - float percent = 0; - assert(result->total != 0); - percent = 100.0 * result->completed / result->total; - monitor_printf(mon, "Finished: %.2f %%\n", percent); - } - - qapi_free_DumpQueryResult(result); -} - void hmp_info_ramblock(Monitor *mon, const QDict *qdict) { ram_block_dump(mon); -- cgit 1.4.1