Declare that the server supports async. Check if the client supports it: the following patch will suspend the qmp monitor if an async command is ongoing but the client doesn't support async.
Signed-off-by: Marc-André Lureau <[email protected]> --- qapi-schema.json | 16 ++++++++++++++-- include/qapi/qmp/dispatch.h | 1 + monitor.c | 19 ++++++++++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/qapi-schema.json b/qapi-schema.json index ddc878390e..8366206415 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -72,11 +72,23 @@ ## ## +# @QMPCapability: +# +# QMP protocol capabilities +# +# @async: enables async messages +# +# Since: 2.9 +## +{ 'enum': 'QMPCapability', + 'data': ['async'] } + +## # @qmp_capabilities: # # Enable QMP capabilities. # -# Arguments: None. +# @capabilities: #optional an array of @QMPCapability (since 2.9) # # Example: # @@ -90,7 +102,7 @@ # Since: 0.13 # ## -{ 'command': 'qmp_capabilities' } +{ 'command': 'qmp_capabilities', 'data': { '*capabilities': ['QMPCapability'] } } ## # @LostTickPolicy: diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index e13e381834..4dd6de5ab2 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -32,6 +32,7 @@ struct QmpClient { QmpDispatchReturn *return_cb; QLIST_HEAD(, QmpReturn) pending; + bool has_async; /* the client has async capability */ }; typedef void (QmpCommandFunc)(QDict *, QObject **, Error **); diff --git a/monitor.c b/monitor.c index 98ba40b573..585f7b6a1a 100644 --- a/monitor.c +++ b/monitor.c @@ -563,9 +563,22 @@ 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_capabilities, + QMPCapabilityList *capabilities, Error **errp) { + bool has_async = false; + + if (has_capabilities) { + while (capabilities) { + if (capabilities->value == QMP_CAPABILITY_ASYNC) { + has_async = true; + } + capabilities = capabilities->next; + } + } + cur_mon->qmp.in_command_mode = true; + cur_mon->qmp.client.has_async = has_async; } static void handle_hmp_command(Monitor *mon, const char *cmdline); @@ -3845,8 +3858,8 @@ static QObject *get_qmp_greeting(void) qmp_marshal_query_version(NULL, &ver, NULL); - return qobject_from_jsonf("{'QMP': {'version': %p, 'capabilities': []}}", - ver); + return qobject_from_jsonf("{'QMP': {'version': %p, 'capabilities': [" + "'async']}}", ver); } static void monitor_qmp_event(void *opaque, int event) -- 2.11.0.295.gd7dffce1c
