[PATCH 9/9] qapi: Extend -compat to set policy for unstable interfaces

John Snow jsnow at redhat.com
Mon Oct 25 19:40:07 UTC 2021


On Mon, Oct 25, 2021 at 1:26 AM Markus Armbruster <armbru at redhat.com> wrote:

> New option parameters unstable-input and unstable-output set policy
> for unstable interfaces just like deprecated-input and
> deprecated-output set policy for deprecated interfaces (see commit
> 6dd75472d5 "qemu-options: New -compat to set policy for deprecated
> interfaces").  This is intended for testing users of the management
> interfaces.  It is experimental.
>
> For now, this covers only syntactic aspects of QMP, i.e. stuff tagged
> with feature 'unstable'.  We may want to extend it to cover semantic
> aspects, or the command line.
>
> Note that there is no good way for management application to detect
> presence of these new option parameters: they are 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 <armbru at redhat.com>
> ---
>  qapi/compat.json              |  6 +++++-
>  include/qapi/util.h           |  1 +
>  qapi/qmp-dispatch.c           |  6 ++++++
>  qapi/qobject-output-visitor.c |  8 ++++++--
>  qemu-options.hx               | 20 +++++++++++++++++++-
>  scripts/qapi/events.py        | 10 ++++++----
>  scripts/qapi/schema.py        | 10 ++++++----
>  7 files changed, 49 insertions(+), 12 deletions(-)
>
> diff --git a/qapi/compat.json b/qapi/compat.json
> index 74a8493d3d..9bc9804abb 100644
> --- a/qapi/compat.json
> +++ b/qapi/compat.json
> @@ -47,9 +47,13 @@
>  #
>  # @deprecated-input: how to handle deprecated input (default 'accept')
>  # @deprecated-output: how to handle deprecated output (default 'accept')
> +# @unstable-input: how to handle unstable input (default 'accept')
> +# @unstable-output: how to handle unstable output (default 'accept')
>  #
>  # Since: 6.0
>  ##
>  { 'struct': 'CompatPolicy',
>    'data': { '*deprecated-input': 'CompatPolicyInput',
> -            '*deprecated-output': 'CompatPolicyOutput' } }
> +            '*deprecated-output': 'CompatPolicyOutput',
> +            '*unstable-input': 'CompatPolicyInput',
> +            '*unstable-output': 'CompatPolicyOutput' } }
> diff --git a/include/qapi/util.h b/include/qapi/util.h
> index 0cc98db9f9..81a2b13a33 100644
> --- a/include/qapi/util.h
> +++ b/include/qapi/util.h
> @@ -13,6 +13,7 @@
>
>  typedef enum {
>      QAPI_DEPRECATED,
> +    QAPI_UNSTABLE,
>  } QapiSpecialFeature;
>
>  typedef struct QEnumLookup {
> diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> index e29ade134c..c5c6e521a2 100644
> --- a/qapi/qmp-dispatch.c
> +++ b/qapi/qmp-dispatch.c
> @@ -59,6 +59,12 @@ bool compat_policy_input_ok(unsigned special_features,
>                                      error_class, kind, name, errp)) {
>          return false;
>      }
> +    if ((special_features & (1u << QAPI_UNSTABLE))
> +        && !compat_policy_input_ok1("Unstable",
> +                                    policy->unstable_input,
> +                                    error_class, kind, name, errp)) {
> +        return false;
> +    }
>      return true;
>  }
>
> diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c
> index b5c6564cbb..74770edd73 100644
> --- a/qapi/qobject-output-visitor.c
> +++ b/qapi/qobject-output-visitor.c
> @@ -212,8 +212,12 @@ static bool qobject_output_type_null(Visitor *v,
> const char *name,
>  static bool qobject_output_policy_skip(Visitor *v, const char *name,
>                                         unsigned special_features)
>  {
> -    return !(special_features && 1u << QAPI_DEPRECATED)
> -        || v->compat_policy.deprecated_output ==
> COMPAT_POLICY_OUTPUT_HIDE;
> +    CompatPolicy *pol = &v->compat_policy;
> +
> +    return ((special_features & 1u << QAPI_DEPRECATED)
> +            && pol->deprecated_output == COMPAT_POLICY_OUTPUT_HIDE)
> +        || ((special_features & 1u << QAPI_UNSTABLE)
> +            && pol->unstable_output == COMPAT_POLICY_OUTPUT_HIDE);
>  }
>
>  /* Finish building, and return the root object.
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 5f375bbfa6..f051536b63 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -3641,7 +3641,9 @@ DEFHEADING(Debug/Expert options:)
>
>  DEF("compat", HAS_ARG, QEMU_OPTION_compat,
>      "-compat
> [deprecated-input=accept|reject|crash][,deprecated-output=accept|hide]\n"
> -    "                Policy for handling deprecated management
> interfaces\n",
> +    "                Policy for handling deprecated management
> interfaces\n"
> +    "-compat
> [unstable-input=accept|reject|crash][,unstable-output=accept|hide]\n"
> +    "                Policy for handling unstable management
> interfaces\n",
>      QEMU_ARCH_ALL)
>  SRST
>  ``-compat
> [deprecated-input=@var{input-policy}][,deprecated-output=@var{output-policy}]``
> @@ -3659,6 +3661,22 @@ SRST
>          Suppress deprecated command results and events
>
>      Limitation: covers only syntactic aspects of QMP.
> +
> +``-compat
> [unstable-input=@var{input-policy}][,unstable-output=@var{output-policy}]``
> +    Set policy for handling unstable management interfaces (experimental):
> +
> +    ``unstable-input=accept`` (default)
> +        Accept unstable commands and arguments
> +    ``unstable-input=reject``
> +        Reject unstable commands and arguments
> +    ``unstable-input=crash``
> +        Crash on unstable commands and arguments
> +    ``unstable-output=accept`` (default)
> +        Emit unstable command results and events
> +    ``unstable-output=hide``
> +        Suppress unstable command results and events
> +
> +    Limitation: covers only syntactic aspects of QMP.
>  ERST
>
>  DEF("fw_cfg", HAS_ARG, QEMU_OPTION_fwcfg,
> diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
> index 82475e84ec..27b44c49f5 100644
> --- a/scripts/qapi/events.py
> +++ b/scripts/qapi/events.py
> @@ -109,13 +109,15 @@ def gen_event_send(name: str,
>          if not boxed:
>              ret += gen_param_var(arg_type)
>
> -    if 'deprecated' in [f.name for f in features]:
> -        ret += mcgen('''
> +    for f in features:
> +        if f.is_special():
> +            ret += mcgen('''
>
> -    if (compat_policy.deprecated_output == COMPAT_POLICY_OUTPUT_HIDE) {
> +    if (compat_policy.%(feat)s_output == COMPAT_POLICY_OUTPUT_HIDE) {
>          return;
>      }
> -''')
> +''',
> +                         feat=f.name)
>
>      ret += mcgen('''
>
> diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py
> index 55f82d7389..b7b3fc0ce4 100644
> --- a/scripts/qapi/schema.py
> +++ b/scripts/qapi/schema.py
> @@ -254,9 +254,11 @@ def doc_type(self):
>
>      def check(self, schema):
>          QAPISchemaEntity.check(self, schema)
> -        if 'deprecated' in [f.name for f in self.features]:
> -            raise QAPISemError(
> -                self.info, "feature 'deprecated' is not supported for
> types")
> +        for feat in self.features:
> +            if feat.is_special():
> +                raise QAPISemError(
> +                    self.info,
> +                    f"feature '{feat.name}' is not supported for types")
>
>      def describe(self):
>          assert self.meta
> @@ -726,7 +728,7 @@ class QAPISchemaFeature(QAPISchemaMember):
>      role = 'feature'
>
>      def is_special(self):
> -        return self.name in ('deprecated')
> +        return self.name in ('deprecated', 'unstable')
>
>
>  class QAPISchemaObjectTypeMember(QAPISchemaMember):
> --
> 2.31.1
>
>
Python bits: Acked-by: John Snow <jsnow at redhat.com>

Looks good overall from what I can see, minor style quibbles that I'd
probably fold on if you frowned at me.

--js
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20211025/64dbdd96/attachment-0001.htm>


More information about the libvir-list mailing list