@@ -247,6 +247,22 @@ Clients should use the qmp_capabilities command to enable capabilities
advertised in the Server's greeting (section '2.2 Server Greeting') they
support.
+With a new enough server, the client can pass an argument 'errors'
+with a list of error class strings that the server must support; if
+the server does not recognize one of the error classes, the command
+will fail and the Server remains in negotiation mode.
+
+C: { "execute": "qmp_capabilities",
+ "arguments": { "errors": [ "None" ] } }
+S: { "error": { "class": "GenericError",
+ "desc": "Invalid parameter 'None'" } }
+C: { "execute": "qmp_capabilities",
+ "arguments": { "errors": [ "GenericError" ] } }
+S: { "return": {} }
+
+However, the Server is still free to return error classes not
+mentioned by the Client.
+
When the qmp_capabilities command is issued, and if it does not return an
error, the Server enters in Command mode where capabilities changes take
effect, all commands (except qmp_capabilities) are allowed and asynchronous
@@ -599,8 +599,12 @@ static void monitor_qapi_event_init(void)
qmp_event_set_func_emit(monitor_qapi_event_queue);
}
-void qmp_qmp_capabilities(Error **errp)
+void qmp_qmp_capabilities(bool has_errors, ErrorClassList *errors,
+ Error **errp)
{
+ /* If we get here, the qapi front end has already validated that
+ * any errors supplied by the user are recognized, so we have
+ * nothing further to do */
cur_mon->qmp.in_command_mode = true;
}
@@ -23,18 +23,22 @@
##
# @Capabilities
#
-# The set of recognized QMP capabilities; currently empty.
+# Used to determine the set of recognized QMP capabilities.
+#
+# @errors: #optional A list of ErrorClass strings that the server
+# must recognize (however, the server is free to return
+# errors that were not in the list supplied by the client).
#
# Since 2.5
##
-{ 'struct': 'Capabilities', 'data': {} }
+{ 'struct': 'Capabilities', 'data': { '*errors': ['ErrorClass'] } }
##
# @qmp_capabilities:
#
# Enable QMP capabilities.
#
-# Arguments: None.
+# Arguments: See documentation of Capabilities.
#
# Example:
#
@@ -2087,7 +2087,7 @@ Example:
EQMP
{
.name = "qmp_capabilities",
- .args_type = "",
+ .args_type = "errors:q?",
.params = "",
.help = "enable QMP capabilities",
.mhandler.cmd_new = qmp_marshal_qmp_capabilities,
Introspection is already able to describe all possible commands and their valid argument types. But consider what happens if a future qemu extends the ErrorClass enum. It is feasible that a client will want to know whether the server is new enough to send the new error class as a result of a particular failure scenario, or even desire to refuse to talk to a server too old to know about the error class. But since no existing commands reference the ErrorClass type, introspection was silent on the set of recognized error classes. Solve this by adding a new optional parameter to qmp_capabilities. Because it is optional, no existing client is broken, but now it is referenced in introspection. Meanwhile, a client can supply a list of error class strings that it expects the server to know about, and the qapi parser will accept the command only if all the client's strings were recognized. Note that we are using this only as a one-way verification, and not a two-way negotiation method (that is, a client omitting an error class string does NOT require the server to avoid sending that error class, and the server's output is unchanged except for whether it rejects the attempt with an error). Signed-off-by: Eric Blake <eblake@redhat.com> --- docs/qmp-spec.txt | 16 ++++++++++++++++ monitor.c | 6 +++++- qapi-schema.json | 10 +++++++--- qmp-commands.hx | 2 +- 4 files changed, 29 insertions(+), 5 deletions(-)