From 6dd75472d58d3d199eb5003a8d2ec2334c68f18f Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 18 Mar 2021 16:55:10 +0100 Subject: qemu-options: New -compat to set policy for deprecated interfaces New option -compat lets you configure what to do when deprecated interfaces get used. This is intended for testing users of the management interfaces. It is experimental. -compat deprecated-input= configures what to do when deprecated input is received. Input policy can be "accept" (accept silently), or "reject" (reject the request with an error). -compat deprecated-output= configures what to do when deprecated output is sent. Output policy can be "accept" (pass on unchanged), or "hide" (filter out the deprecated parts). Default is "accept". Policies other than "accept" are implemented later in this series. For now, -compat covers only syntactic aspects of QMP, i.e. stuff tagged with feature 'deprecated'. We may want to extend it to cover semantic aspects, CLI, and experimental features. Note that there is no good way for management application to detect presence of -compat: it's not visible output of query-qmp-schema or query-command-line-options. Tolerable, because it's meant for testing. If running with -compat fails, skip the test. Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <20210318155519.1224118-3-armbru@redhat.com> --- include/qapi/compat-policy.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 include/qapi/compat-policy.h (limited to 'include') diff --git a/include/qapi/compat-policy.h b/include/qapi/compat-policy.h new file mode 100644 index 0000000..b8c6638 --- /dev/null +++ b/include/qapi/compat-policy.h @@ -0,0 +1,20 @@ +/* + * Policy for handling "funny" management interfaces + * + * Copyright (C) 2020 Red Hat, Inc. + * + * Authors: + * Markus Armbruster + * + * This work is licensed under the terms of the GNU GPL, version 2 or + * later. See the COPYING file in the top-level directory. + */ + +#ifndef QAPI_COMPAT_POLICY_H +#define QAPI_COMPAT_POLICY_H + +#include "qapi/qapi-types-compat.h" + +extern CompatPolicy compat_policy; + +#endif -- cgit v1.1 From 91fa93e516d080d440ead2ad4f88960545bd5b2c Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 18 Mar 2021 16:55:11 +0100 Subject: qapi: Implement deprecated-output=hide for QMP command results This policy suppresses deprecated bits in output, and thus permits "testing the future". Implement it for QMP command results. Example: when QEMU is run with -compat deprecated-output=hide, then {"execute": "query-cpus-fast"} yields {"return": [{"thread-id": 9805, "props": {"core-id": 0, "thread-id": 0, "socket-id": 0}, "qom-path": "/machine/unattached/device[0]", "cpu-index": 0, "target": "x86_64"}]} instead of {"return": [{"arch": "x86", "thread-id": 22436, "props": {"core-id": 0, "thread-id": 0, "socket-id": 0}, "qom-path": "/machine/unattached/device[0]", "cpu-index": 0, "target": "x86_64"}]} Note the suppression of deprecated member "arch". Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <20210318155519.1224118-4-armbru@redhat.com> --- include/qapi/compat-policy.h | 9 +++++++++ include/qapi/qobject-output-visitor.h | 4 ++++ include/qapi/visitor-impl.h | 3 +++ include/qapi/visitor.h | 9 +++++++++ 4 files changed, 25 insertions(+) (limited to 'include') diff --git a/include/qapi/compat-policy.h b/include/qapi/compat-policy.h index b8c6638..94c8bbd 100644 --- a/include/qapi/compat-policy.h +++ b/include/qapi/compat-policy.h @@ -17,4 +17,13 @@ extern CompatPolicy compat_policy; +/* + * Create a QObject output visitor for @obj for use with QMP + * + * This is like qobject_output_visitor_new(), except it obeys the + * policy for handling deprecated management interfaces set with + * -compat. + */ +Visitor *qobject_output_visitor_new_qmp(QObject **result); + #endif diff --git a/include/qapi/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h index 2b1726b..f2a2f92 100644 --- a/include/qapi/qobject-output-visitor.h +++ b/include/qapi/qobject-output-visitor.h @@ -15,6 +15,7 @@ #define QOBJECT_OUTPUT_VISITOR_H #include "qapi/visitor.h" +#include "qapi/qapi-types-compat.h" typedef struct QObjectOutputVisitor QObjectOutputVisitor; @@ -53,4 +54,7 @@ typedef struct QObjectOutputVisitor QObjectOutputVisitor; */ Visitor *qobject_output_visitor_new(QObject **result); +void qobject_output_visitor_set_policy(Visitor *v, + CompatPolicyOutput deprecated); + #endif diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 7362c04..2d85325 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -113,6 +113,9 @@ struct Visitor The core takes care of the return type in the public interface. */ void (*optional)(Visitor *v, const char *name, bool *present); + /* Optional */ + bool (*deprecated)(Visitor *v, const char *name); + /* Must be set */ VisitorType type; diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index ebc19ed..4d23b59 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -460,6 +460,15 @@ void visit_end_alternate(Visitor *v, void **obj); bool visit_optional(Visitor *v, const char *name, bool *present); /* + * Should we visit deprecated member @name? + * + * @name must not be NULL. This function is only useful between + * visit_start_struct() and visit_end_struct(), since only objects + * have deprecated members. + */ +bool visit_deprecated(Visitor *v, const char *name); + +/* * Visit an enum value. * * @name expresses the relationship of this enum to its parent -- cgit v1.1 From d2032598c434fe385145ee6ea58007a19ef7e723 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 18 Mar 2021 16:55:17 +0100 Subject: qapi: Implement deprecated-input=reject for QMP commands This policy rejects deprecated input, and thus permits "testing the future". Implement it for QMP commands: make deprecated ones fail. Example: when QEMU is run with -compat deprecated-input=reject, then {"execute": "query-cpus"} fails like this {"error": {"class": "CommandNotFound", "desc": "Deprecated command query-cpus disabled by policy"}} When the deprecated command is removed, the error will change to {"error": {"class": "CommandNotFound", "desc": "The command query-cpus has not been found"}} Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Message-Id: <20210318155519.1224118-10-armbru@redhat.com> --- include/qapi/qmp/dispatch.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h index 135dfde..075203d 100644 --- a/include/qapi/qmp/dispatch.h +++ b/include/qapi/qmp/dispatch.h @@ -26,6 +26,7 @@ typedef enum QmpCommandOptions QCO_ALLOW_OOB = (1U << 1), QCO_ALLOW_PRECONFIG = (1U << 2), QCO_COROUTINE = (1U << 3), + QCO_DEPRECATED = (1U << 4), } QmpCommandOptions; typedef struct QmpCommand -- cgit v1.1 From db29164103e53ae7c112086127e3d1c92b1d4d89 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Thu, 18 Mar 2021 16:55:18 +0100 Subject: 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 Reviewed-by: Eric Blake Message-Id: <20210318155519.1224118-11-armbru@redhat.com> --- include/qapi/compat-policy.h | 9 +++++++++ include/qapi/qobject-input-visitor.h | 4 ++++ include/qapi/visitor-impl.h | 3 +++ include/qapi/visitor.h | 9 +++++++++ 4 files changed, 25 insertions(+) (limited to 'include') diff --git a/include/qapi/compat-policy.h b/include/qapi/compat-policy.h index 94c8bbd..1083f95 100644 --- a/include/qapi/compat-policy.h +++ b/include/qapi/compat-policy.h @@ -18,6 +18,15 @@ extern CompatPolicy compat_policy; /* + * Create a QObject input visitor for @obj for use with QMP + * + * This is like qobject_input_visitor_new(), except it obeys the + * policy for handling deprecated management interfaces set with + * -compat. + */ +Visitor *qobject_input_visitor_new_qmp(QObject *obj); + +/* * Create a QObject output visitor for @obj for use with QMP * * This is like qobject_output_visitor_new(), except it obeys the diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h index 95985e2..8d69388 100644 --- a/include/qapi/qobject-input-visitor.h +++ b/include/qapi/qobject-input-visitor.h @@ -15,6 +15,7 @@ #ifndef QOBJECT_INPUT_VISITOR_H #define QOBJECT_INPUT_VISITOR_H +#include "qapi/qapi-types-compat.h" #include "qapi/visitor.h" typedef struct QObjectInputVisitor QObjectInputVisitor; @@ -58,6 +59,9 @@ typedef struct QObjectInputVisitor QObjectInputVisitor; */ Visitor *qobject_input_visitor_new(QObject *obj); +void qobject_input_visitor_set_policy(Visitor *v, + CompatPolicyInput deprecated); + /* * Create a QObject input visitor for @obj for use with keyval_parse() * diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 2d85325..3b950f6 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -114,6 +114,9 @@ struct Visitor void (*optional)(Visitor *v, const char *name, bool *present); /* Optional */ + bool (*deprecated_accept)(Visitor *v, const char *name, Error **errp); + + /* Optional */ bool (*deprecated)(Visitor *v, const char *name); /* Must be set */ diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index 4d23b59..b3c9ef7 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -460,6 +460,15 @@ void visit_end_alternate(Visitor *v, void **obj); bool visit_optional(Visitor *v, const char *name, bool *present); /* + * Should we reject deprecated member @name? + * + * @name must not be NULL. This function is only useful between + * visit_start_struct() and visit_end_struct(), since only objects + * have deprecated members. + */ +bool visit_deprecated_accept(Visitor *v, const char *name, Error **errp); + +/* * Should we visit deprecated member @name? * * @name must not be NULL. This function is only useful between -- cgit v1.1