qapi: Implement deprecated-input=reject for QMP command arguments

This policy rejects deprecated input, and thus permits "testing the
future".  Implement it for QMP command arguments: reject commands with
deprecated ones.  Example: when QEMU is run with -compat
deprecated-input=reject, then

    {"execute": "eject", "arguments": {"device": "cd"}}

fails like this

    {"error": {"class": "GenericError", "desc": "Deprecated parameter 'device' disabled by policy"}}

When the deprecated parameter is removed, the error will change to

    {"error": {"class": "GenericError", "desc": "Parameter 'device' is unexpected"}}

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-Id: <20210318155519.1224118-11-armbru@redhat.com>
This commit is contained in:
Markus Armbruster 2021-03-18 16:55:18 +01:00
parent d2032598c4
commit db29164103
11 changed files with 101 additions and 2 deletions

View file

@ -14,6 +14,7 @@
#include "qemu/osdep.h"
#include <math.h>
#include "qapi/compat-policy.h"
#include "qapi/error.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/visitor-impl.h"
@ -43,6 +44,7 @@ typedef struct StackObject {
struct QObjectInputVisitor {
Visitor visitor;
CompatPolicyInput deprecated_policy;
/* Root of visit at visitor creation. */
QObject *root;
@ -662,6 +664,23 @@ static void qobject_input_optional(Visitor *v, const char *name, bool *present)
*present = true;
}
static bool qobject_input_deprecated_accept(Visitor *v, const char *name,
Error **errp)
{
QObjectInputVisitor *qiv = to_qiv(v);
switch (qiv->deprecated_policy) {
case COMPAT_POLICY_INPUT_ACCEPT:
return true;
case COMPAT_POLICY_INPUT_REJECT:
error_setg(errp, "Deprecated parameter '%s' disabled by policy",
name);
return false;
default:
abort();
}
}
static void qobject_input_free(Visitor *v)
{
QObjectInputVisitor *qiv = to_qiv(v);
@ -696,6 +715,7 @@ static QObjectInputVisitor *qobject_input_visitor_base_new(QObject *obj)
v->visitor.end_list = qobject_input_end_list;
v->visitor.start_alternate = qobject_input_start_alternate;
v->visitor.optional = qobject_input_optional;
v->visitor.deprecated_accept = qobject_input_deprecated_accept;
v->visitor.free = qobject_input_free;
v->root = qobject_ref(obj);
@ -718,6 +738,14 @@ Visitor *qobject_input_visitor_new(QObject *obj)
return &v->visitor;
}
void qobject_input_visitor_set_policy(Visitor *v,
CompatPolicyInput deprecated)
{
QObjectInputVisitor *qiv = to_qiv(v);
qiv->deprecated_policy = deprecated;
}
Visitor *qobject_input_visitor_new_keyval(QObject *obj)
{
QObjectInputVisitor *v = qobject_input_visitor_base_new(obj);