new file mode 100644
@@ -0,0 +1,51 @@
+# -*- Mode: Python -*-
+
+##
+# = Compatibility policy
+##
+
+##
+# @CompatPolicyInput:
+#
+# Policy for handling "funny" input.
+#
+# @accept: Accept silently
+# @reject: Reject with an error
+#
+# Since: 5.0
+##
+{ 'enum': 'CompatPolicyInput',
+ 'data': [ 'accept', 'reject' ] }
+
+##
+# @CompatPolicyOutput:
+#
+# Policy for handling "funny" output.
+#
+# @accept: Pass on unchanged
+# @hide: Filter out
+#
+# Since: 5.0
+##
+{ 'enum': 'CompatPolicyOutput',
+ 'data': [ 'accept', 'hide' ] }
+
+##
+# @CompatPolicy:
+#
+# Policy for handling deprecated management interfaces.
+#
+# This is intended for testing users of the management interfaces.
+#
+# Limitation: 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.
+#
+# @deprecated-input: how to handle deprecated input (default 'accept')
+# @deprecated-output: how to handle deprecated output (default 'accept')
+#
+# Since: 5.0
+##
+{ 'struct': 'CompatPolicy',
+ 'data': { '*deprecated-input': 'CompatPolicyInput',
+ '*deprecated-output': 'CompatPolicyOutput' } }
@@ -98,6 +98,7 @@
{ 'include': 'migration.json' }
{ 'include': 'transaction.json' }
{ 'include': 'trace.json' }
+{ 'include': 'compat.json' }
{ 'include': 'control.json' }
{ 'include': 'introspect.json' }
{ 'include': 'qom.json' }
new file mode 100644
@@ -0,0 +1,20 @@
+/*
+ * Policy for handling "funny" management interfaces
+ *
+ * Copyright (C) 2019 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <armbru@redhat.com>,
+ *
+ * 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
@@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/compat-policy.h"
#include "qapi/error.h"
#include "qapi/qmp/dispatch.h"
#include "qapi/qmp/qdict.h"
@@ -19,6 +20,8 @@
#include "sysemu/runstate.h"
#include "qapi/qmp/qbool.h"
+CompatPolicy compat_policy;
+
static QDict *qmp_dispatch_check_obj(const QObject *request, bool allow_oob,
QObject **id, Error **errp)
{
@@ -26,6 +26,7 @@
#include "qemu-common.h"
#include "qemu/units.h"
#include "hw/qdev-properties.h"
+#include "qapi/compat-policy.h"
#include "qapi/error.h"
#include "qemu-version.h"
#include "qemu/cutils.h"
@@ -104,6 +105,7 @@
#include "sysemu/replay.h"
#include "qapi/qapi-events-run-state.h"
#include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-visit-compat.h"
#include "qapi/qapi-visit-ui.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qapi-commands-run-state.h"
@@ -3748,6 +3750,21 @@ void qemu_init(int argc, char **argv, char **envp)
qemu_opt_get_bool(opts, "mem-lock", false);
enable_cpu_pm = qemu_opt_get_bool(opts, "cpu-pm", false);
break;
+ case QEMU_OPTION_compat:
+ {
+ CompatPolicy *opts;
+ Visitor *v;
+
+ v = qobject_input_visitor_new_str(optarg, NULL,
+ &error_fatal);
+
+ visit_type_CompatPolicy(v, NULL, &opts, &error_fatal);
+ QAPI_CLONE_MEMBERS(CompatPolicy, &compat_policy, opts);
+
+ qapi_free_CompatPolicy(opts);
+ visit_free(v);
+ break;
+ }
case QEMU_OPTION_msg:
opts = qemu_opts_parse_noisily(qemu_find_opts("msg"), optarg,
false);
@@ -5,10 +5,10 @@ util-obj-y += opts-visitor.o qapi-clone-visitor.o
util-obj-y += qmp-event.o
util-obj-y += qapi-util.o
-QAPI_COMMON_MODULES = audio authz block-core block char common control crypto
-QAPI_COMMON_MODULES += dump error introspect job machine migration misc
-QAPI_COMMON_MODULES += net qdev qom rdma rocker run-state sockets tpm
-QAPI_COMMON_MODULES += trace transaction ui
+QAPI_COMMON_MODULES = audio authz block-core block char common compat
+QAPI_COMMON_MODULES += control crypto dump error introspect job
+QAPI_COMMON_MODULES += machine migration misc net qdev qom rdma rocker
+QAPI_COMMON_MODULES += run-state sockets tpm trace transaction ui
QAPI_TARGET_MODULES = machine-target misc-target
QAPI_MODULES = $(QAPI_COMMON_MODULES) $(QAPI_TARGET_MODULES)
@@ -3360,6 +3360,27 @@ STEXI
@table @option
ETEXI
+DEF("compat", HAS_ARG, QEMU_OPTION_compat,
+ "-compat [deprecated-input=accept|reject][,deprecated-output=accept|hide]\n"
+ " Policy for handling deprecated management interfaces\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -compat [deprecated-input=@var{input-policy}][,deprecated-output=@var{output-policy}]
+@findex -compat
+Set policy for handling deprecated management interfaces (experimental):
+@table @option
+@item deprecated-input=accept (default)
+Accept deprecated commands and arguments
+@item deprecated-input=reject
+Reject deprecated commands and arguments
+@item deprecated-output=accept (default)
+Emit deprecated command results and events
+@item deprecated-output=hide
+Suppress deprecated command results and events
+@end table
+Limitation: covers only syntactic aspects of QMP.
+ETEXI
+
DEF("fw_cfg", HAS_ARG, QEMU_OPTION_fwcfg,
"-fw_cfg [name=]<name>,file=<file>\n"
" add named fw_cfg entry with contents from file\n"
Policy is separate for input and output. Input policy can be "accept" (accept silently), or "reject" (reject the request with an error). 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. The option is experimental. Signed-off-by: Markus Armbruster <armbru@redhat.com> --- qapi/compat.json | 51 ++++++++++++++++++++++++++++++++++++ qapi/qapi-schema.json | 1 + include/qapi/compat-policy.h | 20 ++++++++++++++ qapi/qmp-dispatch.c | 3 +++ softmmu/vl.c | 17 ++++++++++++ qapi/Makefile.objs | 8 +++--- qemu-options.hx | 21 +++++++++++++++ 7 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 qapi/compat.json create mode 100644 include/qapi/compat-policy.h