Looks like this ---> {"execute": "query-cpus"} <--- {"return": [...], "warnings": [{"class": "CommandNotFound", "desc": "command is deprecated"}]} Management applications may want to log such warnings. This commit is not for merging as is, because * docs/interop/qmp-spec.txt needs an update for the new success response member "warnings". * I'd like to see a prospective user before I extend the QMP protocol. If you have specific plans to put them to use, let me know. * The same warning should be included in a deprecated event. * Emitting the same warning over and over again might be annoying or slow. Perhaps warning just once would be better. Signed-off-by: Markus Armbruster <armbru@xxxxxxxxxx> --- qapi/qmp-dispatch.c | 8 ++++++++ tests/test-qmp-cmds.c | 43 +++++++++++++++++++++++++++++++++++++++++-- qemu-options.hx | 2 +- 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 6436417844..9c17a59f31 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -197,6 +197,14 @@ out: } else { rsp = qdict_new(); qdict_put_obj(rsp, "return", ret); + if (cmd->options & QCO_DEPRECATED) { + qdict_put_obj( + rsp, "warnings", + qobject_from_jsonf_nofail( + "[ { 'class': %s, 'desc': %s } ]", + QapiErrorClass_str(ERROR_CLASS_COMMAND_NOT_FOUND), + "command is deprecated")); + } } if (id) { diff --git a/tests/test-qmp-cmds.c b/tests/test-qmp-cmds.c index 005ea24a27..38d2e5b4a7 100644 --- a/tests/test-qmp-cmds.c +++ b/tests/test-qmp-cmds.c @@ -2,6 +2,7 @@ #include "qapi/compat-policy.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qjson.h" +#include "qapi/qmp/qlist.h" #include "qapi/qmp/qnum.h" #include "qapi/qmp/qstring.h" #include "qapi/error.h" @@ -164,6 +165,40 @@ static QObject *do_qmp_dispatch(bool allow_oob, const char *template, ...) return ret; } +static QObject *do_qmp_dispatch_warning(bool allow_oob, ErrorClass cls, + const char *template, ...) +{ + va_list ap; + QDict *req, *resp; + QObject *ret; + QList *warnings; + QDict *warning; + + va_start(ap, template); + req = qdict_from_vjsonf_nofail(template, ap); + va_end(ap); + + resp = qmp_dispatch(&qmp_commands, QOBJECT(req), allow_oob); + g_assert(resp); + ret = qdict_get(resp, "return"); + g_assert(ret); + warnings = qdict_get_qlist(resp, "warnings"); + g_assert(warnings); + warning = qobject_to(QDict, qlist_peek(warnings)); + g_assert(warning); + g_assert_cmpstr(qdict_get_try_str(warning, "class"), + ==, QapiErrorClass_str(cls)); + g_assert(qdict_get_try_str(warning, "desc")); + g_assert(qdict_size(warning) == 2); + g_assert(qlist_size(warnings) == 1); + g_assert(qdict_size(resp) == 2); + + qobject_ref(ret); + qobject_unref(resp); + qobject_unref(req); + return ret; +} + static void do_qmp_dispatch_error(bool allow_oob, ErrorClass cls, const char *template, ...) { @@ -242,13 +277,17 @@ static void test_dispatch_cmd_deprecated(void) QDict *ret; /* accept */ - ret = qobject_to(QDict, do_qmp_dispatch(false, cmd)); + ret = qobject_to(QDict, do_qmp_dispatch_warning( + false, ERROR_CLASS_COMMAND_NOT_FOUND, + "{ 'execute': 'test-command-features1' }")); assert(ret && qdict_size(ret) == 0); qobject_unref(ret); qapi_compat_policy.has_deprecated_input = true; qapi_compat_policy.deprecated_input = COMPAT_POLICY_INPUT_ACCEPT; - ret = qobject_to(QDict, do_qmp_dispatch(false, cmd)); + ret = qobject_to(QDict, do_qmp_dispatch_warning( + false, ERROR_CLASS_COMMAND_NOT_FOUND, + "{ 'execute': 'test-command-features1' }")); assert(ret && qdict_size(ret) == 0); qobject_unref(ret); diff --git a/qemu-options.hx b/qemu-options.hx index 3a740ea7b1..645629457a 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3330,7 +3330,7 @@ STEXI Set policy for handling deprecated management interfaces: @table @option @item deprecated-input=accept (default) -Accept deprecated commands +Accept deprecated commands with a warning @item deprecated-input=reject Reject deprecated commands @item deprecated-input=crash -- 2.21.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list