Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2020-03-17' into staging

QAPI patches for 2020-03-17

# gpg: Signature made Tue 17 Mar 2020 20:50:54 GMT
# gpg:                using RSA key 354BC8B3D7EB2A6B68674E5F3870B400EB918653
# gpg:                issuer "armbru@redhat.com"
# gpg: Good signature from "Markus Armbruster <armbru@redhat.com>" [full]
# gpg:                 aka "Markus Armbruster <armbru@pond.sub.org>" [full]
# Primary key fingerprint: 354B C8B3 D7EB 2A6B 6867  4E5F 3870 B400 EB91 8653

* remotes/armbru/tags/pull-qapi-2020-03-17: (30 commits)
  net: Track netdevs in NetClientState rather than QemuOpt
  net: Complete qapi-fication of netdev_add
  qmp: constify QmpCommand and list
  qapi: Mark deprecated QMP parts with feature 'deprecated'
  qapi: New special feature flag "deprecated"
  qapi: Replace qmp_dispatch()'s TODO comment by an explanation
  qapi: Simplify how qmp_dispatch() gets the request ID
  qapi: Simplify how qmp_dispatch() deals with QCO_NO_SUCCESS_RESP
  qapi: Inline do_qmp_dispatch() into qmp_dispatch()
  qapi: Add feature flags to struct members
  qapi/schema: Call QAPIDoc.connect_member() in just one place
  qapi/schema: Rename QAPISchemaObjectType{Variant,Variants}
  qapi/schema: Reorder classes so related ones are together
  qapi/schema: Change _make_features() to a take feature list
  qapi/introspect: Factor out _make_tree()
  qapi/introspect: Rename *qlit* to reduce confusion
  qapi: Consistently put @features parameter right after @ifcond
  qapi: Add feature flags to remaining definitions
  qapi/schema: Clean up around QAPISchemaEntity.connect_doc()
  tests/test-qmp-event: Check event is actually emitted
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2020-03-19 10:18:07 +00:00
42 changed files with 941 additions and 786 deletions
+62 -19
View File
@@ -172,7 +172,8 @@ Syntax:
ENUM = { 'enum': STRING,
'data': [ ENUM-VALUE, ... ],
'*prefix': STRING,
'*if': COND }
'*if': COND,
'*features': FEATURES }
ENUM-VALUE = STRING
| { 'name': STRING, '*if': COND }
@@ -207,6 +208,9 @@ the job satisfactorily.
The optional 'if' member specifies a conditional. See "Configuring
the schema" below for more on this.
The optional 'features' member specifies features. See "Features"
below for more on this.
=== Type references and array types ===
@@ -230,7 +234,9 @@ Syntax:
'*features': FEATURES }
MEMBERS = { MEMBER, ... }
MEMBER = STRING : TYPE-REF
| STRING : { 'type': TYPE-REF, '*if': COND }
| STRING : { 'type': TYPE-REF,
'*if': COND,
'*features': FEATURES }
Member 'struct' names the struct type.
@@ -279,12 +285,14 @@ below for more on this.
Syntax:
UNION = { 'union': STRING,
'data': BRANCHES,
'*if': COND }
'*if': COND,
'*features': FEATURES }
| { 'union': STRING,
'data': BRANCHES,
'base': ( MEMBERS | STRING ),
'discriminator': STRING,
'*if': COND }
'*if': COND,
'*features': FEATURES }
BRANCHES = { BRANCH, ... }
BRANCH = STRING : TYPE-REF
| STRING : { 'type': TYPE-REF, '*if': COND }
@@ -391,15 +399,19 @@ is identical on the wire to:
The optional 'if' member specifies a conditional. See "Configuring
the schema" below for more on this.
The optional 'features' member specifies features. See "Features"
below for more on this.
=== Alternate types ===
Syntax:
ALTERNATE = { 'alternate': STRING,
'data': ALTERNATIVES,
'*if': COND }
'*if': COND,
'*features': FEATURES }
ALTERNATIVES = { ALTERNATIVE, ... }
ALTERNATIVE = STRING : TYPE-REF
ALTERNATIVE = STRING : STRING
| STRING : { 'type': STRING, '*if': COND }
Member 'alternate' names the alternate type.
@@ -441,6 +453,9 @@ following example objects:
The optional 'if' member specifies a conditional. See "Configuring
the schema" below for more on this.
The optional 'features' member specifies features. See "Features"
below for more on this.
=== Commands ===
@@ -584,6 +599,9 @@ started with --preconfig.
The optional 'if' member specifies a conditional. See "Configuring
the schema" below for more on this.
The optional 'features' member specifies features. See "Features"
below for more on this.
=== Events ===
@@ -595,7 +613,8 @@ Syntax:
'data': STRING,
'boxed': true,
)
'*if': COND }
'*if': COND,
'*features': FEATURES }
Member 'event' names the event. This is the event name used in the
Client JSON Protocol.
@@ -628,6 +647,9 @@ complex type. See section "Code generated for events" for examples.
The optional 'if' member specifies a conditional. See "Configuring
the schema" below for more on this.
The optional 'features' member specifies features. See "Features"
below for more on this.
=== Features ===
@@ -642,13 +664,8 @@ that previously resulted in an error). QMP clients may still need to
know whether the extension is available.
For this purpose, a list of features can be specified for a command or
struct type. This is exposed to the client as a list of strings,
where each string signals that this build of QEMU shows a certain
behaviour.
Each member of the 'features' array defines a feature. It can either
be { 'name': STRING, '*if': COND }, or STRING, which is shorthand for
{ 'name': STRING }.
struct type. Each list member can either be { 'name': STRING, '*if':
COND }, or STRING, which is shorthand for { 'name': STRING }.
The optional 'if' member specifies a conditional. See "Configuring
the schema" below for more on this.
@@ -659,6 +676,18 @@ Example:
'data': { 'number': 'int' },
'features': [ 'allow-negative-numbers' ] }
The feature strings are exposed to clients in introspection, as
explained in section "Client JSON Protocol introspection".
Intended use is to have each feature string signal that this build of
QEMU shows a certain behaviour.
==== Special features ====
Feature "deprecated" marks a command, event, or struct member as
deprecated. It is not supported elsewhere so far.
=== Naming rules and reserved names ===
@@ -965,8 +994,9 @@ schema, along with the SchemaInfo type. This text attempts to give an
overview how things work. For details you need to consult the QAPI
schema.
SchemaInfo objects have common members "name" and "meta-type", and
additional variant members depending on the value of meta-type.
SchemaInfo objects have common members "name", "meta-type",
"features", and additional variant members depending on the value of
meta-type.
Each SchemaInfo object describes a wire ABI entity of a certain
meta-type: a command, event or one of several kinds of type.
@@ -979,6 +1009,9 @@ not. Therefore, the SchemaInfo for types have auto-generated
meaningless names. For readability, the examples in this section use
meaningful type names instead.
Optional member "features" exposes the entity's feature strings as a
JSON array of strings.
To examine a type, start with a command or event using it, then follow
references by name.
@@ -988,9 +1021,9 @@ The SchemaInfo for a command has meta-type "command", and variant
members "arg-type", "ret-type" and "allow-oob". On the wire, the
"arguments" member of a client's "execute" command must conform to the
object type named by "arg-type". The "return" member that the server
passes in a success response conforms to the type named by
"ret-type". When "allow-oob" is set, it means the command supports
out-of-band execution.
passes in a success response conforms to the type named by "ret-type".
When "allow-oob" is true, it means the command supports out-of-band
execution. It defaults to false.
If the command takes no arguments, "arg-type" names an object type
without members. Likewise, if the command returns nothing, "ret-type"
@@ -1047,6 +1080,16 @@ Example: the SchemaInfo for MyType from section Struct types
{ "name": "member2", "type": "int" },
{ "name": "member3", "type": "str", "default": null } ] }
"features" exposes the command's feature strings as a JSON array of
strings.
Example: the SchemaInfo for TestType from section Features:
{ "name": "TestType", "meta-type": "object",
"members": [
{ "name": "number", "type": "int" } ],
"features": ["allow-negative-numbers"] }
"tag" is the name of the common member serving as type tag.
"variants" is a JSON array describing the object's variant members.
Each element is a JSON object with members "case" (the value of type
+44 -4
View File
@@ -180,27 +180,67 @@ QEMU Machine Protocol (QMP) commands
Use ``blockdev-change-medium`` or ``change-vnc-password`` instead.
``blockdev-open-tray``, ``blockdev-close-tray`` argument ``device`` (since 2.8.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use argument ``id`` instead.
``eject`` argument ``device`` (since 2.8.0)
'''''''''''''''''''''''''''''''''''''''''''
Use argument ``id`` instead.
``blockdev-change-medium`` argument ``device`` (since 2.8.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use argument ``id`` instead.
``block_set_io_throttle`` argument ``device`` (since 2.8.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use argument ``id`` instead.
``migrate_set_downtime`` and ``migrate_set_speed`` (since 2.8.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use ``migrate-set-parameters`` instead.
``query-named-block-nodes`` result ``encryption_key_missing`` (since 2.10.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Always false.
``query-block`` result ``inserted.encryption_key_missing`` (since 2.10.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Always false.
``blockdev-add`` empty string argument ``backing`` (since 2.10.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use argument value ``null`` instead.
``migrate-set-cache-size`` and ``query-migrate-cache-size`` (since 2.11.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use ``migrate-set-parameters`` and ``query-migrate-parameters`` instead.
``block-commit`` arguments ``base`` and ``top`` (since 3.1.0)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Use arguments ``base-node`` and ``top-node`` instead.
``object-add`` option ``props`` (since 5.0)
'''''''''''''''''''''''''''''''''''''''''''
Specify the properties for the object as top-level arguments instead.
``query-block`` result field ``dirty-bitmaps[i].status`` (since 4.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
``query-named-block-nodes`` and ``query-block`` result dirty-bitmaps[i].status (since 4.0)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The ``status`` field of the ``BlockDirtyInfo`` structure, returned by
the query-block command is deprecated. Two new boolean fields,
``recording`` and ``busy`` effectively replace it.
these commands is deprecated. Two new boolean fields, ``recording`` and
``busy`` effectively replace it.
``query-block`` result field ``dirty-bitmaps`` (Since 4.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+1 -1
View File
@@ -98,6 +98,7 @@ struct NetClientState {
unsigned rxfilter_notify_enabled:1;
int vring_enable;
int vnet_hdr_len;
bool is_netdev;
QTAILQ_HEAD(, NetFilterState) filters;
};
@@ -203,7 +204,6 @@ void net_cleanup(void);
void hmp_host_net_add(Monitor *mon, const QDict *qdict);
void hmp_host_net_remove(Monitor *mon, const QDict *qdict);
void netdev_add(QemuOpts *opts, Error **errp);
void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp);
int net_hub_id_for_client(NetClientState *nc, int *id);
NetClientState *net_hub_port_find(int hub_id);
+5 -4
View File
@@ -39,7 +39,8 @@ typedef QTAILQ_HEAD(QmpCommandList, QmpCommand) QmpCommandList;
void qmp_register_command(QmpCommandList *cmds, const char *name,
QmpCommandFunc *fn, QmpCommandOptions options);
QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name);
const QmpCommand *qmp_find_command(const QmpCommandList *cmds,
const char *name);
void qmp_disable_command(QmpCommandList *cmds, const char *name);
void qmp_enable_command(QmpCommandList *cmds, const char *name);
@@ -47,13 +48,13 @@ bool qmp_command_is_enabled(const QmpCommand *cmd);
const char *qmp_command_name(const QmpCommand *cmd);
bool qmp_has_success_response(const QmpCommand *cmd);
QDict *qmp_error_response(Error *err);
QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request,
QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
bool allow_oob);
bool qmp_is_oob(const QDict *dict);
typedef void (*qmp_cmd_callback_fn)(QmpCommand *cmd, void *opaque);
typedef void (*qmp_cmd_callback_fn)(const QmpCommand *cmd, void *opaque);
void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn,
void qmp_for_each_command(const QmpCommandList *cmds, qmp_cmd_callback_fn fn,
void *opaque);
#endif
+1 -5
View File
@@ -247,8 +247,6 @@ static void monitor_init_qmp_commands(void)
qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
qmp_register_command(&qmp_commands, "device_add", qmp_device_add,
QCO_NO_OPTIONS);
qmp_register_command(&qmp_commands, "netdev_add", qmp_netdev_add,
QCO_NO_OPTIONS);
qmp_register_command(&qmp_commands, "object-add", qmp_object_add,
QCO_NO_OPTIONS);
@@ -2037,13 +2035,11 @@ void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC,
MAX_QUEUE_NUM);
for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
QemuOpts *opts;
const char *name = ncs[i]->name;
if (strncmp(str, name, len)) {
continue;
}
opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
if (opts) {
if (ncs[i]->is_netdev) {
readline_add_completion(rs, name);
}
}
+1 -1
View File
@@ -133,7 +133,7 @@ typedef struct {
* qmp_capabilities succeeds, we go into command mode, and
* @command becomes &qmp_commands.
*/
QmpCommandList *commands;
const QmpCommandList *commands;
bool capab_offered[QMP_CAPABILITY__MAX]; /* capabilities offered */
bool capab[QMP_CAPABILITY__MAX]; /* offered and accepted */
/*
+1 -1
View File
@@ -101,7 +101,7 @@ VersionInfo *qmp_query_version(Error **errp)
return info;
}
static void query_commands_cb(QmpCommand *cmd, void *opaque)
static void query_commands_cb(const QmpCommand *cmd, void *opaque)
{
CommandInfoList *info, **list = opaque;
+12 -27
View File
@@ -1060,6 +1060,15 @@ static int net_client_init1(const void *object, bool is_netdev, Error **errp)
}
return -1;
}
if (is_netdev) {
NetClientState *nc;
nc = qemu_find_netdev(netdev->id);
assert(nc);
nc->is_netdev = true;
}
return 0;
}
@@ -1170,36 +1179,14 @@ void netdev_add(QemuOpts *opts, Error **errp)
net_client_init(opts, true, errp);
}
void qmp_netdev_add(QDict *qdict, QObject **ret, Error **errp)
void qmp_netdev_add(Netdev *netdev, Error **errp)
{
Error *local_err = NULL;
QemuOptsList *opts_list;
QemuOpts *opts;
opts_list = qemu_find_opts_err("netdev", &local_err);
if (local_err) {
goto out;
}
opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
if (local_err) {
goto out;
}
netdev_add(opts, &local_err);
if (local_err) {
qemu_opts_del(opts);
goto out;
}
out:
error_propagate(errp, local_err);
net_client_init1(netdev, true, errp);
}
void qmp_netdev_del(const char *id, Error **errp)
{
NetClientState *nc;
QemuOpts *opts;
nc = qemu_find_netdev(id);
if (!nc) {
@@ -1208,14 +1195,12 @@ void qmp_netdev_del(const char *id, Error **errp)
return;
}
opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), id);
if (!opts) {
if (!nc->is_netdev) {
error_setg(errp, "Device '%s' is not a netdev", id);
return;
}
qemu_del_net_client(nc);
qemu_opts_del(opts);
}
static void netfilter_print_info(Monitor *mon, NetFilterState *nf)
+37 -11
View File
@@ -297,7 +297,7 @@
#
# @encrypted: true if the backing device is encrypted
#
# @encryption_key_missing: Deprecated; always false
# @encryption_key_missing: always false
#
# @detect_zeroes: detect and optimize zero writes (Since 2.1)
#
@@ -363,13 +363,19 @@
# @dirty-bitmaps: dirty bitmaps information (only present if node
# has one or more dirty bitmaps) (Since 4.2)
#
# Features:
# @deprecated: Member @encryption_key_missing is deprecated. It is
# always false.
#
# Since: 0.14.0
#
##
{ 'struct': 'BlockDeviceInfo',
'data': { 'file': 'str', '*node-name': 'str', 'ro': 'bool', 'drv': 'str',
'*backing_file': 'str', 'backing_file_depth': 'int',
'encrypted': 'bool', 'encryption_key_missing': 'bool',
'encrypted': 'bool',
'encryption_key_missing': { 'type': 'bool',
'features': [ 'deprecated' ] },
'detect_zeroes': 'BlockdevDetectZeroesOptions',
'bps': 'int', 'bps_rd': 'int', 'bps_wr': 'int',
'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
@@ -475,7 +481,7 @@
#
# @granularity: granularity of the dirty bitmap in bytes (since 1.4)
#
# @status: Deprecated in favor of @recording and @locked. (since 2.4)
# @status: current status of the dirty bitmap (since 2.4)
#
# @recording: true if the bitmap is recording new writes from the guest.
# Replaces `active` and `disabled` statuses. (since 4.0)
@@ -492,11 +498,17 @@
# @busy to be false. This bitmap cannot be used. To remove
# it, use @block-dirty-bitmap-remove. (Since 4.0)
#
# Features:
# @deprecated: Member @status is deprecated. Use @recording and
# @locked instead.
#
# Since: 1.3
##
{ 'struct': 'BlockDirtyInfo',
'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32',
'recording': 'bool', 'busy': 'bool', 'status': 'DirtyBitmapStatus',
'recording': 'bool', 'busy': 'bool',
'status': { 'type': 'DirtyBitmapStatus',
'features': [ 'deprecated' ] },
'persistent': 'bool', '*inconsistent': 'bool' } }
##
@@ -587,7 +599,6 @@
#
# @dirty-bitmaps: dirty bitmaps information (only present if the
# driver has one or more dirty bitmaps) (Since 2.0)
# Deprecated in 4.2; see BlockDeviceInfo instead.
#
# @io-status: @BlockDeviceIoStatus. Only present if the device
# supports it and the VM is configured to stop on errors
@@ -597,13 +608,18 @@
# @inserted: @BlockDeviceInfo describing the device if media is
# present
#
# Features:
# @deprecated: Member @dirty-bitmaps is deprecated. Use @inserted
# member @dirty-bitmaps instead.
#
# Since: 0.14.0
##
{ 'struct': 'BlockInfo',
'data': {'device': 'str', '*qdev': 'str', 'type': 'str', 'removable': 'bool',
'locked': 'bool', '*inserted': 'BlockDeviceInfo',
'*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',
'*dirty-bitmaps': ['BlockDirtyInfo'] } }
'*dirty-bitmaps': { 'type': ['BlockDirtyInfo'],
'features': [ 'deprecated' ] } } }
##
# @BlockMeasureInfo:
@@ -1551,7 +1567,7 @@
# @base: Same as @base-node, except that it is a file name rather than a node
# name. This must be the exact filename string that was used to open the
# node; other strings, even if addressing the same file, are not
# accepted (deprecated, use @base-node instead)
# accepted
#
# @top-node: The node name of the backing image within the image chain
# which contains the topmost data to be committed down. If
@@ -1560,7 +1576,7 @@
# @top: Same as @top-node, except that it is a file name rather than a node
# name. This must be the exact filename string that was used to open the
# node; other strings, even if addressing the same file, are not
# accepted (deprecated, use @base-node instead)
# accepted
#
# @backing-file: The backing file string to write into the overlay
# image of 'top'. If 'top' is the active layer,
@@ -1614,6 +1630,10 @@
# list without user intervention.
# Defaults to true. (Since 3.1)
#
# Features:
# @deprecated: Members @base and @top are deprecated. Use @base-node
# and @top-node instead.
#
# Returns: - Nothing on success
# - If @device does not exist, DeviceNotFound
# - Any other error returns a GenericError.
@@ -1630,7 +1650,9 @@
##
{ 'command': 'block-commit',
'data': { '*job-id': 'str', 'device': 'str', '*base-node': 'str',
'*base': 'str', '*top-node': 'str', '*top': 'str',
'*base': { 'type': 'str', 'features': [ 'deprecated' ] },
'*top-node': 'str',
'*top': { 'type': 'str', 'features': [ 'deprecated' ] },
'*backing-file': 'str', '*speed': 'int',
'*on-error': 'BlockdevOnError',
'*filter-node-name': 'str',
@@ -2296,7 +2318,7 @@
#
# A set of parameters describing block throttling.
#
# @device: Block device name (deprecated, use @id instead)
# @device: Block device name
#
# @id: The name or QOM path of the guest device (since: 2.8)
#
@@ -2364,10 +2386,14 @@
#
# @group: throttle group name (Since 2.4)
#
# Features:
# @deprecated: Member @device is deprecated. Use @id instead.
#
# Since: 1.1
##
{ 'struct': 'BlockIOThrottle',
'data': { '*device': 'str', '*id': 'str', 'bps': 'int', 'bps_rd': 'int',
'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
'*id': 'str', 'bps': 'int', 'bps_rd': 'int',
'bps_wr': 'int', 'iops': 'int', 'iops_rd': 'int', 'iops_wr': 'int',
'*bps_max': 'int', '*bps_rd_max': 'int',
'*bps_wr_max': 'int', '*iops_max': 'int',
+21 -9
View File
@@ -90,15 +90,18 @@
##
# @eject:
#
# Ejects a device from a removable drive.
# Ejects the medium from a removable drive.
#
# @device: Block device name (deprecated, use @id instead)
# @device: Block device name
#
# @id: The name or QOM path of the guest device (since: 2.8)
#
# @force: If true, eject regardless of whether the drive is locked.
# If not specified, the default value is false.
#
# Features:
# @deprecated: Member @device is deprecated. Use @id instead.
#
# Returns: - Nothing on success
# - If @device is not a valid block device, DeviceNotFound
# Notes: Ejecting a device with no media results in success
@@ -111,7 +114,7 @@
# <- { "return": {} }
##
{ 'command': 'eject',
'data': { '*device': 'str',
'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
'*id': 'str',
'*force': 'bool' } }
@@ -134,7 +137,7 @@
# to it
# - if the guest device does not have an actual tray
#
# @device: Block device name (deprecated, use @id instead)
# @device: Block device name
#
# @id: The name or QOM path of the guest device (since: 2.8)
#
@@ -143,6 +146,9 @@
# immediately); if true, the tray will be opened regardless of whether
# it is locked
#
# Features:
# @deprecated: Member @device is deprecated. Use @id instead.
#
# Since: 2.5
#
# Example:
@@ -161,7 +167,7 @@
#
##
{ 'command': 'blockdev-open-tray',
'data': { '*device': 'str',
'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
'*id': 'str',
'*force': 'bool' } }
@@ -174,10 +180,13 @@
#
# If the tray was already closed before, this will be a no-op.
#
# @device: Block device name (deprecated, use @id instead)
# @device: Block device name
#
# @id: The name or QOM path of the guest device (since: 2.8)
#
# Features:
# @deprecated: Member @device is deprecated. Use @id instead.
#
# Since: 2.5
#
# Example:
@@ -196,7 +205,7 @@
#
##
{ 'command': 'blockdev-close-tray',
'data': { '*device': 'str',
'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
'*id': 'str' } }
##
@@ -303,7 +312,7 @@
# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
# and blockdev-close-tray).
#
# @device: Block device name (deprecated, use @id instead)
# @device: Block device name
#
# @id: The name or QOM path of the guest device
# (since: 2.8)
@@ -316,6 +325,9 @@
# @read-only-mode: change the read-only mode of the device; defaults
# to 'retain'
#
# Features:
# @deprecated: Member @device is deprecated. Use @id instead.
#
# Since: 2.5
#
# Examples:
@@ -350,7 +362,7 @@
#
##
{ 'command': 'blockdev-change-medium',
'data': { '*device': 'str',
'data': { '*device': { 'type': 'str', 'features': [ 'deprecated' ] },
'*id': 'str',
'filename': 'str',
'*format': 'str',
+1
View File
@@ -258,6 +258,7 @@
# @server: create server socket (default: true)
# @wait: wait for incoming connection on server
# sockets (default: false).
# Silently ignored with server: false. This use is deprecated.
# @nodelay: set TCP_NODELAY socket option (default: false)
# @telnet: enable telnet protocol on server
# sockets (default: false)
+7 -4
View File
@@ -174,13 +174,15 @@
#
# Return information on QMP events.
#
# Features:
# @deprecated: This command is deprecated, because its output doesn't
# reflect compile-time configuration. Use 'query-qmp-schema'
# instead.
#
# Returns: A list of @EventInfo.
#
# Since: 1.2.0
#
# Note: This command is deprecated, because its output doesn't reflect
# compile-time configuration. Use query-qmp-schema instead.
#
# Example:
#
# -> { "execute": "query-events" }
@@ -198,7 +200,8 @@
# Note: This example has been shortened as the real response is too long.
#
##
{ 'command': 'query-events', 'returns': ['EventInfo'] }
{ 'command': 'query-events', 'returns': ['EventInfo'],
'features': [ 'deprecated' ] }
##
# @quit:
+14 -12
View File
@@ -89,12 +89,18 @@
#
# @meta-type: the entity's meta type, inherited from @base.
#
# @features: names of features associated with the entity, in no
# particular order.
# (since 4.1 for object types, 4.2 for commands, 5.0 for
# the rest)
#
# Additional members depend on the value of @meta-type.
#
# Since: 2.5
##
{ 'union': 'SchemaInfo',
'base': { 'name': 'str', 'meta-type': 'SchemaMetaType' },
'base': { 'name': 'str', 'meta-type': 'SchemaMetaType',
'*features': [ 'str' ] },
'discriminator': 'meta-type',
'data': {
'builtin': 'SchemaInfoBuiltin',
@@ -174,9 +180,6 @@
# and may even differ from the order of the values of the
# enum type of the @tag.
#
# @features: names of features associated with the type, in no particular
# order. (since: 4.1)
#
# Values of this type are JSON object on the wire.
#
# Since: 2.5
@@ -184,8 +187,7 @@
{ 'struct': 'SchemaInfoObject',
'data': { 'members': [ 'SchemaInfoObjectMember' ],
'*tag': 'str',
'*variants': [ 'SchemaInfoObjectVariant' ],
'*features': [ 'str' ] } }
'*variants': [ 'SchemaInfoObjectVariant' ] } }
##
# @SchemaInfoObjectMember:
@@ -204,11 +206,15 @@
# Future extension: if present and non-null, the parameter
# is optional, and defaults to this value.
#
# @features: names of features associated with the member, in no
# particular order. (since 5.0)
#
# Since: 2.5
##
{ 'struct': 'SchemaInfoObjectMember',
'data': { 'name': 'str', 'type': 'str', '*default': 'any' } }
'data': { 'name': 'str', 'type': 'str', '*default': 'any',
# @default's type must be null or match @type
'*features': [ 'str' ] } }
##
# @SchemaInfoObjectVariant:
@@ -266,17 +272,13 @@
# @allow-oob: whether the command allows out-of-band execution,
# defaults to false (Since: 2.12)
#
# @features: names of features associated with the command, in no particular
# order. (since 4.2)
#
# TODO: @success-response (currently irrelevant, because it's QGA, not QMP)
#
# Since: 2.5
##
{ 'struct': 'SchemaInfoCommand',
'data': { 'arg-type': 'str', 'ret-type': 'str',
'*allow-oob': 'bool',
'*features': [ 'str' ] } }
'*allow-oob': 'bool' } }
##
# @SchemaInfoEvent:
+19 -15
View File
@@ -184,8 +184,11 @@
# 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.
#
# Features:
# @deprecated: This command is deprecated, because it interferes with
# the guest. Use 'query-cpus-fast' instead to avoid the vCPU
# interruption.
#
# Returns: a list of @CpuInfo for each virtual CPU
#
@@ -216,12 +219,9 @@
# ]
# }
#
# 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'] }
{ 'command': 'query-cpus', 'returns': ['CpuInfo'],
'features': [ 'deprecated' ] }
##
# @CpuInfoFast:
@@ -237,12 +237,14 @@
# @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
# @arch: base architecture of the cpu
#
# @target: the QEMU system emulation target, which determines which
# additional fields will be listed (since 3.0)
#
# Features:
# @deprecated: Member @arch is deprecated. Use @target instead.
#
# Since: 2.12
#
##
@@ -251,7 +253,8 @@
'qom-path' : 'str',
'thread-id' : 'int',
'*props' : 'CpuInstanceProperties',
'arch' : 'CpuInfoArch',
'arch' : { 'type': 'CpuInfoArch',
'features': [ 'deprecated' ] },
'target' : 'SysEmuTarget' },
'discriminator' : 'target',
'data' : { 's390x' : 'CpuInfoS390' } }
@@ -307,21 +310,22 @@
#
# @id: ID of CPU to be created, valid values [0..max_cpus)
#
# Features:
# @deprecated: This command is deprecated. Use `device_add` instead.
# See the `query-hotpluggable-cpus` command for details.
#
# 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'} }
{ 'command': 'cpu-add', 'data': {'id': 'int'},
'features': [ 'deprecated' ] }
##
# @MachineInfo:
+24 -12
View File
@@ -1210,9 +1210,11 @@
#
# @value: maximum downtime in seconds
#
# Returns: nothing on success
# Features:
# @deprecated: This command is deprecated. Use
# 'migrate-set-parameters' instead.
#
# Notes: This command is deprecated in favor of 'migrate-set-parameters'
# Returns: nothing on success
#
# Since: 0.14.0
#
@@ -1222,7 +1224,8 @@
# <- { "return": {} }
#
##
{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'} }
{ 'command': 'migrate_set_downtime', 'data': {'value': 'number'},
'features': [ 'deprecated' ] }
##
# @migrate_set_speed:
@@ -1231,9 +1234,11 @@
#
# @value: maximum speed in bytes per second.
#
# Returns: nothing on success
# Features:
# @deprecated: This command is deprecated. Use
# 'migrate-set-parameters' instead.
#
# Notes: This command is deprecated in favor of 'migrate-set-parameters'
# Returns: nothing on success
#
# Since: 0.14.0
#
@@ -1243,7 +1248,8 @@
# <- { "return": {} }
#
##
{ 'command': 'migrate_set_speed', 'data': {'value': 'int'} }
{ 'command': 'migrate_set_speed', 'data': {'value': 'int'},
'features': [ 'deprecated' ] }
##
# @migrate-set-cache-size:
@@ -1252,13 +1258,15 @@
#
# @value: cache size in bytes
#
# Features:
# @deprecated: This command is deprecated. Use
# 'migrate-set-parameters' instead.
#
# The size will be rounded down to the nearest power of 2.
# The cache size can be modified before and during ongoing migration
#
# Returns: nothing on success
#
# Notes: This command is deprecated in favor of 'migrate-set-parameters'
#
# Since: 1.2
#
# Example:
@@ -1268,16 +1276,19 @@
# <- { "return": {} }
#
##
{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'} }
{ 'command': 'migrate-set-cache-size', 'data': {'value': 'int'},
'features': [ 'deprecated' ] }
##
# @query-migrate-cache-size:
#
# Query migration XBZRLE cache size
#
# Returns: XBZRLE cache size in bytes
# Features:
# @deprecated: This command is deprecated. Use
# 'query-migrate-parameters' instead.
#
# Notes: This command is deprecated in favor of 'query-migrate-parameters'
# Returns: XBZRLE cache size in bytes
#
# Since: 1.2
#
@@ -1287,7 +1298,8 @@
# <- { "return": 67108864 }
#
##
{ 'command': 'query-migrate-cache-size', 'returns': 'int' }
{ 'command': 'query-migrate-cache-size', 'returns': 'int',
'features': [ 'deprecated' ] }
##
# @migrate:
+7 -6
View File
@@ -872,14 +872,14 @@
# If @device is 'vnc' and @target is 'password', this is the new VNC
# password to set. See change-vnc-password for additional notes.
#
# Features:
# @deprecated: This command is deprecated. For changing block
# devices, use 'blockdev-change-medium' instead; for changing VNC
# parameters, use 'change-vnc-password' instead.
#
# Returns: - Nothing on success.
# - If @device is not a valid block device, DeviceNotFound
#
# Notes: This interface is deprecated, and it is strongly recommended that you
# avoid using it. For changing block devices, use
# blockdev-change-medium; for changing VNC parameters, use
# change-vnc-password.
#
# Since: 0.14.0
#
# Example:
@@ -900,7 +900,8 @@
#
##
{ 'command': 'change',
'data': {'device': 'str', 'target': 'str', '*arg': 'str'} }
'data': {'device': 'str', 'target': 'str', '*arg': 'str'},
'features': [ 'deprecated' ] }
##
# @xen-set-global-dirty-log:
+1 -13
View File
@@ -39,18 +39,8 @@
#
# Add a network backend.
#
# @type: the type of network backend. Possible values are listed in
# NetClientDriver (excluding 'none' and 'nic')
#
# @id: the name of the new network backend
#
# Additional arguments depend on the type.
#
# 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.14.0
#
# Returns: Nothing on success
@@ -64,9 +54,7 @@
# <- { "return": {} }
#
##
{ 'command': 'netdev_add',
'data': {'type': 'str', 'id': 'str'},
'gen': false } # so we can get the additional arguments
{ 'command': 'netdev_add', 'data': 'Netdev', 'boxed': true }
##
# @netdev_del:
+89 -91
View File
@@ -19,20 +19,13 @@
#include "sysemu/runstate.h"
#include "qapi/qmp/qbool.h"
static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
static QDict *qmp_dispatch_check_obj(QDict *dict, bool allow_oob,
Error **errp)
{
const char *exec_key = NULL;
const QDictEntry *ent;
const char *arg_name;
const QObject *arg_obj;
QDict *dict;
dict = qobject_to(QDict, request);
if (!dict) {
error_setg(errp, "QMP input must be a JSON object");
return NULL;
}
for (ent = qdict_first(dict); ent;
ent = qdict_next(dict, ent)) {
@@ -75,75 +68,6 @@ static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
return dict;
}
static QObject *do_qmp_dispatch(QmpCommandList *cmds, QObject *request,
bool allow_oob, Error **errp)
{
Error *local_err = NULL;
bool oob;
const char *command;
QDict *args, *dict;
QmpCommand *cmd;
QObject *ret = NULL;
dict = qmp_dispatch_check_obj(request, allow_oob, errp);
if (!dict) {
return NULL;
}
command = qdict_get_try_str(dict, "execute");
oob = false;
if (!command) {
assert(allow_oob);
command = qdict_get_str(dict, "exec-oob");
oob = true;
}
cmd = qmp_find_command(cmds, command);
if (cmd == NULL) {
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has not been found", command);
return NULL;
}
if (!cmd->enabled) {
error_set(errp, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has been disabled for this instance",
command);
return NULL;
}
if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
error_setg(errp, "The command %s does not support OOB",
command);
return NULL;
}
if (runstate_check(RUN_STATE_PRECONFIG) &&
!(cmd->options & QCO_ALLOW_PRECONFIG)) {
error_setg(errp, "The command '%s' isn't permitted in '%s' state",
cmd->name, RunState_str(RUN_STATE_PRECONFIG));
return NULL;
}
if (!qdict_haskey(dict, "arguments")) {
args = qdict_new();
} else {
args = qdict_get_qdict(dict, "arguments");
qobject_ref(args);
}
cmd->fn(args, &ret, &local_err);
if (local_err) {
error_propagate(errp, local_err);
} else if (cmd->options & QCO_NO_SUCCESS_RESP) {
g_assert(!ret);
} else if (!ret) {
/* TODO turn into assertion */
ret = QOBJECT(qdict_new());
}
qobject_unref(args);
return ret;
}
QDict *qmp_error_response(Error *err)
{
QDict *rsp;
@@ -164,26 +88,100 @@ bool qmp_is_oob(const QDict *dict)
&& !qdict_haskey(dict, "execute");
}
QDict *qmp_dispatch(QmpCommandList *cmds, QObject *request,
QDict *qmp_dispatch(const QmpCommandList *cmds, QObject *request,
bool allow_oob)
{
Error *err = NULL;
QDict *dict = qobject_to(QDict, request);
QObject *ret, *id = dict ? qdict_get(dict, "id") : NULL;
QDict *rsp;
bool oob;
const char *command;
QDict *args;
const QmpCommand *cmd;
QDict *dict;
QObject *id;
QObject *ret = NULL;
QDict *rsp = NULL;
ret = do_qmp_dispatch(cmds, request, allow_oob, &err);
if (err) {
rsp = qmp_error_response(err);
} else if (ret) {
rsp = qdict_new();
qdict_put_obj(rsp, "return", ret);
} else {
/* Can only happen for commands with QCO_NO_SUCCESS_RESP */
rsp = NULL;
dict = qobject_to(QDict, request);
if (!dict) {
id = NULL;
error_setg(&err, "QMP input must be a JSON object");
goto out;
}
if (rsp && id) {
id = qdict_get(dict, "id");
if (!qmp_dispatch_check_obj(dict, allow_oob, &err)) {
goto out;
}
command = qdict_get_try_str(dict, "execute");
oob = false;
if (!command) {
assert(allow_oob);
command = qdict_get_str(dict, "exec-oob");
oob = true;
}
cmd = qmp_find_command(cmds, command);
if (cmd == NULL) {
error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has not been found", command);
goto out;
}
if (!cmd->enabled) {
error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
"The command %s has been disabled for this instance",
command);
goto out;
}
if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
error_setg(&err, "The command %s does not support OOB",
command);
goto out;
}
if (runstate_check(RUN_STATE_PRECONFIG) &&
!(cmd->options & QCO_ALLOW_PRECONFIG)) {
error_setg(&err, "The command '%s' isn't permitted in '%s' state",
cmd->name, RunState_str(RUN_STATE_PRECONFIG));
goto out;
}
if (!qdict_haskey(dict, "arguments")) {
args = qdict_new();
} else {
args = qdict_get_qdict(dict, "arguments");
qobject_ref(args);
}
cmd->fn(args, &ret, &err);
qobject_unref(args);
if (err) {
goto out;
}
if (cmd->options & QCO_NO_SUCCESS_RESP) {
g_assert(!ret);
return NULL;
} else if (!ret) {
/*
* When the command's schema has no 'returns', cmd->fn()
* leaves @ret null. The QMP spec calls for an empty object
* then; supply it.
*/
ret = QOBJECT(qdict_new());
}
rsp = qdict_new();
qdict_put_obj(rsp, "return", ret);
out:
if (err) {
assert(!rsp);
rsp = qmp_error_response(err);
}
assert(rsp);
if (id) {
qdict_put_obj(rsp, "id", qobject_ref(id));
}
+3 -3
View File
@@ -27,7 +27,7 @@ void qmp_register_command(QmpCommandList *cmds, const char *name,
QTAILQ_INSERT_TAIL(cmds, cmd, node);
}
QmpCommand *qmp_find_command(QmpCommandList *cmds, const char *name)
const QmpCommand *qmp_find_command(const QmpCommandList *cmds, const char *name)
{
QmpCommand *cmd;
@@ -77,10 +77,10 @@ bool qmp_has_success_response(const QmpCommand *cmd)
return !(cmd->options & QCO_NO_SUCCESS_RESP);
}
void qmp_for_each_command(QmpCommandList *cmds, qmp_cmd_callback_fn fn,
void qmp_for_each_command(const QmpCommandList *cmds, qmp_cmd_callback_fn fn,
void *opaque)
{
QmpCommand *cmd;
const QmpCommand *cmd;
QTAILQ_FOREACH(cmd, cmds, node) {
fn(cmd, opaque);
+1 -1
View File
@@ -54,7 +54,7 @@ void qmp_guest_ping(Error **errp)
slog("guest-ping called");
}
static void qmp_command_info(QmpCommand *cmd, void *opaque)
static void qmp_command_info(const QmpCommand *cmd, void *opaque)
{
GuestAgentInfo *info = opaque;
GuestAgentCommandInfo *cmd_info;

Some files were not shown because too many files have changed in this diff Show More