diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst index 0bed6ecb1d..be19317470 100644 --- a/docs/about/deprecated.rst +++ b/docs/about/deprecated.rst @@ -228,6 +228,12 @@ Use the more generic commands ``block-export-add`` and ``block-export-del`` instead. As part of this deprecation, where ``nbd-server-add`` used a single ``bitmap``, the new ``block-export-add`` uses a list of ``bitmaps``. +``query-qmp-schema`` return value member ``values`` (since 6.2) +''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +Member ``values`` in return value elements with meta-type ``enum`` is +deprecated. Use ``members`` instead. + System accelerators ------------------- diff --git a/docs/devel/qapi-code-gen.rst b/docs/devel/qapi-code-gen.rst index b2569de486..4071c9074a 100644 --- a/docs/devel/qapi-code-gen.rst +++ b/docs/devel/qapi-code-gen.rst @@ -200,7 +200,9 @@ Syntax:: '*if': COND, '*features': FEATURES } ENUM-VALUE = STRING - | { 'name': STRING, '*if': COND } + | { 'name': STRING, + '*if': COND, + '*features': FEATURES } Member 'enum' names the enum type. @@ -706,8 +708,10 @@ QEMU shows a certain behaviour. Special features ~~~~~~~~~~~~~~~~ -Feature "deprecated" marks a command, event, or struct member as -deprecated. It is not supported elsewhere so far. +Feature "deprecated" marks a command, event, enum value, or struct +member as deprecated. It is not supported elsewhere so far. +Interfaces so marked may be withdrawn in future releases in accordance +with QEMU's deprecation policy. Naming rules and reserved names @@ -1157,7 +1161,8 @@ and "variants". "members" is a JSON array describing the object's common members, if any. Each element is a JSON object with members "name" (the member's -name), "type" (the name of its type), and optionally "default". The +name), "type" (the name of its type), "features" (a JSON array of +feature strings), and "default". The latter two are optional. The member is optional if "default" is present. Currently, "default" can only have value null. Other values are reserved for future extensions. The "members" array is in no particular order; clients @@ -1231,14 +1236,22 @@ Example: the SchemaInfo for ['str'] :: "element-type": "str" } The SchemaInfo for an enumeration type has meta-type "enum" and -variant member "values". The values are listed in no particular -order; clients must search the entire enum when learning whether a -particular value is supported. +variant member "members". + +"members" is a JSON array describing the enumeration values. Each +element is a JSON object with member "name" (the member's name), and +optionally "features" (a JSON array of feature strings). The +"members" array is in no particular order; clients must search the +entire array when learning whether a particular value is supported. Example: the SchemaInfo for MyEnum from section `Enumeration types`_ :: { "name": "MyEnum", "meta-type": "enum", - "values": [ "value1", "value2", "value3" ] } + "members": [ + { "name": "value1" }, + { "name": "value2" }, + { "name": "value3" } + ] } The SchemaInfo for a built-in type has the same name as the type in the QAPI schema (see section `Built-in Types`_), with one exception diff --git a/include/qapi/qobject-input-visitor.h b/include/qapi/qobject-input-visitor.h index 8d69388810..95985e25e5 100644 --- a/include/qapi/qobject-input-visitor.h +++ b/include/qapi/qobject-input-visitor.h @@ -15,7 +15,6 @@ #ifndef QOBJECT_INPUT_VISITOR_H #define QOBJECT_INPUT_VISITOR_H -#include "qapi/qapi-types-compat.h" #include "qapi/visitor.h" typedef struct QObjectInputVisitor QObjectInputVisitor; @@ -59,9 +58,6 @@ 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/qobject-output-visitor.h b/include/qapi/qobject-output-visitor.h index f2a2f92a00..2b1726baf5 100644 --- a/include/qapi/qobject-output-visitor.h +++ b/include/qapi/qobject-output-visitor.h @@ -15,7 +15,6 @@ #define QOBJECT_OUTPUT_VISITOR_H #include "qapi/visitor.h" -#include "qapi/qapi-types-compat.h" typedef struct QObjectOutputVisitor QObjectOutputVisitor; @@ -54,7 +53,4 @@ 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/util.h b/include/qapi/util.h index d7bfb30e25..257c600f99 100644 --- a/include/qapi/util.h +++ b/include/qapi/util.h @@ -11,9 +11,13 @@ #ifndef QAPI_UTIL_H #define QAPI_UTIL_H +/* QEnumLookup flags */ +#define QAPI_ENUM_DEPRECATED 1 + typedef struct QEnumLookup { const char *const *array; - int size; + const unsigned char *const flags; + const int size; } QEnumLookup; const char *qapi_enum_lookup(const QEnumLookup *lookup, int val); diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h index 3b950f6e3d..72b6537bef 100644 --- a/include/qapi/visitor-impl.h +++ b/include/qapi/visitor-impl.h @@ -122,6 +122,9 @@ struct Visitor /* Must be set */ VisitorType type; + /* Optional */ + struct CompatPolicy compat_policy; + /* Must be set for output visitors, optional otherwise. */ void (*complete)(Visitor *v, void *opaque); diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h index b3c9ef7a81..dcb96018a9 100644 --- a/include/qapi/visitor.h +++ b/include/qapi/visitor.h @@ -16,6 +16,7 @@ #define QAPI_VISITOR_H #include "qapi/qapi-builtin-types.h" +#include "qapi/qapi-types-compat.h" /* * The QAPI schema defines both a set of C data types, and a QMP wire @@ -477,6 +478,14 @@ bool visit_deprecated_accept(Visitor *v, const char *name, Error **errp); */ bool visit_deprecated(Visitor *v, const char *name); +/* + * Set policy for handling deprecated management interfaces. + * + * Intended use: call visit_set_policy(v, &compat_policy) when + * visiting management interface input or output. + */ +void visit_set_policy(Visitor *v, CompatPolicy *policy); + /* * Visit an enum value. * diff --git a/qapi/compat.json b/qapi/compat.json index ae3afc22df..74a8493d3d 100644 --- a/qapi/compat.json +++ b/qapi/compat.json @@ -42,6 +42,9 @@ # with feature 'deprecated'. We may want to extend it to cover # semantic aspects, CLI, and experimental features. # +# Limitation: deprecated-output policy @hide is not implemented for +# enumeration values. They behave the same as with policy @accept. +# # @deprecated-input: how to handle deprecated input (default 'accept') # @deprecated-output: how to handle deprecated output (default 'accept') # diff --git a/qapi/introspect.json b/qapi/introspect.json index 39bd303778..183148b2e9 100644 --- a/qapi/introspect.json +++ b/qapi/introspect.json @@ -142,14 +142,38 @@ # # Additional SchemaInfo members for meta-type 'enum'. # -# @values: the enumeration type's values, in no particular order. +# @members: the enum type's members, in no particular order +# (since 6.2). +# +# @values: the enumeration type's member names, in no particular order. +# Redundant with @members. Just for backward compatibility. +# +# Features: +# @deprecated: Member @values is deprecated. Use @members instead. # # Values of this type are JSON string on the wire. # # Since: 2.5 ## { 'struct': 'SchemaInfoEnum', - 'data': { 'values': ['str'] } } + 'data': { 'members': [ 'SchemaInfoEnumMember' ], + 'values': { 'type': [ 'str' ], + 'features': [ 'deprecated' ] } } } + +## +# @SchemaInfoEnumMember: +# +# An object member. +# +# @name: the member's name, as defined in the QAPI schema. +# +# @features: names of features associated with the member, in no +# particular order. +# +# Since: 6.2 +## +{ 'struct': 'SchemaInfoEnumMember', + 'data': { 'name': 'str', '*features': [ 'str' ] } } ## # @SchemaInfoArray: diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c index a641adec51..617ef3fa46 100644 --- a/qapi/qapi-visit-core.c +++ b/qapi/qapi-visit-core.c @@ -19,6 +19,10 @@ #include "qapi/visitor-impl.h" #include "trace.h" +/* Zero-initialization must result in default policy */ +QEMU_BUILD_BUG_ON(COMPAT_POLICY_INPUT_ACCEPT || COMPAT_POLICY_OUTPUT_ACCEPT); + + void visit_complete(Visitor *v, void *opaque) { assert(v->type != VISITOR_OUTPUT || v->complete); @@ -153,6 +157,11 @@ bool visit_deprecated(Visitor *v, const char *name) return true; } +void visit_set_policy(Visitor *v, CompatPolicy *policy) +{ + v->compat_policy = *policy; +} + bool visit_is_input(Visitor *v) { return v->type == VISITOR_INPUT; @@ -384,7 +393,7 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, const QEnumLookup *lookup, Error **errp) { int64_t value; - char *enum_str; + g_autofree char *enum_str = NULL; if (!visit_type_str(v, name, &enum_str, errp)) { return false; @@ -392,12 +401,25 @@ static bool input_type_enum(Visitor *v, const char *name, int *obj, value = qapi_enum_parse(lookup, enum_str, -1, NULL); if (value < 0) { - error_setg(errp, QERR_INVALID_PARAMETER, enum_str); - g_free(enum_str); + error_setg(errp, "Parameter '%s' does not accept value '%s'", + name ? name : "null", enum_str); return false; } - g_free(enum_str); + if (lookup->flags && (lookup->flags[value] & QAPI_ENUM_DEPRECATED)) { + switch (v->compat_policy.deprecated_input) { + case COMPAT_POLICY_INPUT_ACCEPT: + break; + case COMPAT_POLICY_INPUT_REJECT: + error_setg(errp, "Deprecated value '%s' disabled by policy", + enum_str); + return false; + case COMPAT_POLICY_INPUT_CRASH: + default: + abort(); + } + } + *obj = value; return true; } diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c index 59600210ce..7e943a0af5 100644 --- a/qapi/qmp-dispatch.c +++ b/qapi/qmp-dispatch.c @@ -32,7 +32,7 @@ Visitor *qobject_input_visitor_new_qmp(QObject *obj) { Visitor *v = qobject_input_visitor_new(obj); - qobject_input_visitor_set_policy(v, compat_policy.deprecated_input); + visit_set_policy(v, &compat_policy); return v; } @@ -40,7 +40,7 @@ Visitor *qobject_output_visitor_new_qmp(QObject **result) { Visitor *v = qobject_output_visitor_new(result); - qobject_output_visitor_set_policy(v, compat_policy.deprecated_output); + visit_set_policy(v, &compat_policy); return v; } diff --git a/qapi/qobject-input-visitor.c b/qapi/qobject-input-visitor.c index 04b790412e..71b24a4429 100644 --- a/qapi/qobject-input-visitor.c +++ b/qapi/qobject-input-visitor.c @@ -14,7 +14,6 @@ #include "qemu/osdep.h" #include -#include "qapi/compat-policy.h" #include "qapi/error.h" #include "qapi/qobject-input-visitor.h" #include "qapi/visitor-impl.h" @@ -44,7 +43,6 @@ typedef struct StackObject { struct QObjectInputVisitor { Visitor visitor; - CompatPolicyInput deprecated_policy; /* Root of visit at visitor creation. */ QObject *root; @@ -667,9 +665,7 @@ static void qobject_input_optional(Visitor *v, const char *name, bool *present) static bool qobject_input_deprecated_accept(Visitor *v, const char *name, Error **errp) { - QObjectInputVisitor *qiv = to_qiv(v); - - switch (qiv->deprecated_policy) { + switch (v->compat_policy.deprecated_input) { case COMPAT_POLICY_INPUT_ACCEPT: return true; case COMPAT_POLICY_INPUT_REJECT: @@ -739,14 +735,6 @@ 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); diff --git a/qapi/qobject-output-visitor.c b/qapi/qobject-output-visitor.c index e4873308d4..9b7f510036 100644 --- a/qapi/qobject-output-visitor.c +++ b/qapi/qobject-output-visitor.c @@ -13,7 +13,6 @@ */ #include "qemu/osdep.h" -#include "qapi/compat-policy.h" #include "qapi/qobject-output-visitor.h" #include "qapi/visitor-impl.h" #include "qemu/queue.h" @@ -32,7 +31,6 @@ typedef struct QStackEntry { struct QObjectOutputVisitor { Visitor visitor; - CompatPolicyOutput deprecated_policy; QSLIST_HEAD(, QStackEntry) stack; /* Stack of unfinished containers */ QObject *root; /* Root of the output visit */ @@ -212,9 +210,7 @@ static bool qobject_output_type_null(Visitor *v, const char *name, static bool qobject_output_deprecated(Visitor *v, const char *name) { - QObjectOutputVisitor *qov = to_qov(v); - - return qov->deprecated_policy != COMPAT_POLICY_OUTPUT_HIDE; + return v->compat_policy.deprecated_output != COMPAT_POLICY_OUTPUT_HIDE; } /* Finish building, and return the root object. @@ -275,11 +271,3 @@ Visitor *qobject_output_visitor_new(QObject **result) return &v->visitor; } - -void qobject_output_visitor_set_policy(Visitor *v, - CompatPolicyOutput deprecated) -{ - QObjectOutputVisitor *qov = to_qov(v); - - qov->deprecated_policy = deprecated; -} diff --git a/scripts/qapi/expr.py b/scripts/qapi/expr.py index 819ea6ad97..3cb389e875 100644 --- a/scripts/qapi/expr.py +++ b/scripts/qapi/expr.py @@ -472,7 +472,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None: for m in members] for member in members: source = "'data' member" - check_keys(member, info, source, ['name'], ['if']) + check_keys(member, info, source, ['name'], ['if', 'features']) member_name = member['name'] check_name_is_str(member_name, info, source) source = "%s '%s'" % (source, member_name) @@ -483,6 +483,7 @@ def check_enum(expr: _JSONObject, info: QAPISourceInfo) -> None: permit_upper=permissive, permit_underscore=permissive) check_if(member, info, source) + check_features(member.get('features'), info) def check_struct(expr: _JSONObject, info: QAPISourceInfo) -> None: diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 4c079ee627..67c7d89aae 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -68,6 +68,7 @@ JSONValue = Union[_Value, 'Annotated[_Value]'] # TypedDict constructs, so they are broadly typed here as simple # Python Dicts. SchemaInfo = Dict[str, object] +SchemaInfoEnumMember = Dict[str, object] SchemaInfoObject = Dict[str, object] SchemaInfoObjectVariant = Dict[str, object] SchemaInfoObjectMember = Dict[str, object] @@ -274,8 +275,17 @@ const QLitObject %(c_name)s = %(c_string)s; obj['features'] = self._gen_features(features) self._trees.append(Annotated(obj, ifcond, comment)) - def _gen_member(self, member: QAPISchemaObjectTypeMember - ) -> Annotated[SchemaInfoObjectMember]: + def _gen_enum_member(self, member: QAPISchemaEnumMember + ) -> Annotated[SchemaInfoEnumMember]: + obj: SchemaInfoEnumMember = { + 'name': member.name, + } + if member.features: + obj['features'] = self._gen_features(member.features) + return Annotated(obj, member.ifcond) + + def _gen_object_member(self, member: QAPISchemaObjectTypeMember + ) -> Annotated[SchemaInfoObjectMember]: obj: SchemaInfoObjectMember = { 'name': member.name, 'type': self._use_type(member.type) @@ -305,7 +315,8 @@ const QLitObject %(c_name)s = %(c_string)s; prefix: Optional[str]) -> None: self._gen_tree( name, 'enum', - {'values': [Annotated(m.name, m.ifcond) for m in members]}, + {'members': [self._gen_enum_member(m) for m in members], + 'values': [Annotated(m.name, m.ifcond) for m in members]}, ifcond, features ) @@ -322,7 +333,7 @@ const QLitObject %(c_name)s = %(c_string)s; members: List[QAPISchemaObjectTypeMember], variants: Optional[QAPISchemaVariants]) -> None: obj: SchemaInfoObject = { - 'members': [self._gen_member(m) for m in members] + 'members': [self._gen_object_member(m) for m in members] } if variants: obj['tag'] = variants.tag_member.name diff --git a/scripts/qapi/schema.py b/scripts/qapi/schema.py index 004d7095ff..6d5f46509a 100644 --- a/scripts/qapi/schema.py +++ b/scripts/qapi/schema.py @@ -708,6 +708,19 @@ class QAPISchemaMember: class QAPISchemaEnumMember(QAPISchemaMember): role = 'value' + def __init__(self, name, info, ifcond=None, features=None): + super().__init__(name, info, ifcond) + for f in features or []: + assert isinstance(f, QAPISchemaFeature) + f.set_defined_in(name) + self.features = features or [] + + def connect_doc(self, doc): + super().connect_doc(doc) + if doc: + for f in self.features: + doc.connect_feature(f) + class QAPISchemaFeature(QAPISchemaMember): role = 'feature' @@ -980,9 +993,14 @@ class QAPISchema: QAPISchemaIfCond(f.get('if'))) for f in features] + def _make_enum_member(self, name, ifcond, features, info): + return QAPISchemaEnumMember(name, info, + QAPISchemaIfCond(ifcond), + self._make_features(features, info)) + def _make_enum_members(self, values, info): - return [QAPISchemaEnumMember(v['name'], info, - QAPISchemaIfCond(v.get('if'))) + return [self._make_enum_member(v['name'], v.get('if'), + v.get('features'), info) for v in values] def _make_array_type(self, element_type, info): diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 831294fe42..ab2441adc9 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -38,6 +38,8 @@ objects_seen = set() def gen_enum_lookup(name: str, members: List[QAPISchemaEnumMember], prefix: Optional[str] = None) -> str: + max_index = c_enum_const(name, '_MAX', prefix) + flags = '' ret = mcgen(''' const QEnumLookup %(c_name)s_lookup = { @@ -52,13 +54,26 @@ const QEnumLookup %(c_name)s_lookup = { ''', index=index, name=memb.name) ret += memb.ifcond.gen_endif() + if 'deprecated' in (f.name for f in memb.features): + flags += mcgen(''' + [%(index)s] = QAPI_ENUM_DEPRECATED, +''', + index=index) + + if flags: + ret += mcgen(''' + }, + .flags = (const unsigned char[%(max_index)s]) { +''', + max_index=max_index) + ret += flags ret += mcgen(''' }, .size = %(max_index)s }; ''', - max_index=c_enum_const(name, '_MAX', prefix)) + max_index=max_index) return ret diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json index 86dc25d2bd..74745fb405 100644 --- a/tests/qapi-schema/doc-good.json +++ b/tests/qapi-schema/doc-good.json @@ -58,11 +58,14 @@ # # Features: # @enum-feat: Also _one_ {and only} +# @enum-member-feat: a member feature # # @two is undocumented ## { 'enum': 'Enum', - 'data': [ { 'name': 'one', 'if': 'IFONE' }, 'two' ], + 'data': [ { 'name': 'one', 'if': 'IFONE', + 'features': [ 'enum-member-feat' ] }, + 'two' ], 'features': [ 'enum-feat' ], 'if': 'IFCOND' } diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out index 5a324e2627..9dd65b9d92 100644 --- a/tests/qapi-schema/doc-good.out +++ b/tests/qapi-schema/doc-good.out @@ -13,6 +13,7 @@ module doc-good.json enum Enum member one if IFONE + feature enum-member-feat member two if IFCOND feature enum-feat @@ -108,6 +109,8 @@ The _one_ {and only} feature=enum-feat Also _one_ {and only} + feature=enum-member-feat +a member feature section=None @two is undocumented doc symbol=Base diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt index 701402ee5e..b3b76bd43f 100644 --- a/tests/qapi-schema/doc-good.txt +++ b/tests/qapi-schema/doc-good.txt @@ -56,6 +56,9 @@ Features "enum-feat" Also _one_ {and only} +"enum-member-feat" + a member feature + "two" is undocumented diff --git a/tests/qapi-schema/enum-dict-member-unknown.err b/tests/qapi-schema/enum-dict-member-unknown.err index f8617ea179..235cde0c49 100644 --- a/tests/qapi-schema/enum-dict-member-unknown.err +++ b/tests/qapi-schema/enum-dict-member-unknown.err @@ -1,3 +1,3 @@ enum-dict-member-unknown.json: In enum 'MyEnum': enum-dict-member-unknown.json:2: 'data' member has unknown key 'bad-key' -Valid keys are 'if', 'name'. +Valid keys are 'features', 'if', 'name'. diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json index 2ec50109cb..b677ab861d 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -301,7 +301,8 @@ 'TEST_IF_COND_2'] } } ] } { 'enum': 'FeatureEnum1', - 'data': [ 'eins', 'zwei', 'drei' ], + 'data': [ 'eins', 'zwei', + { 'name': 'drei', 'features': [ 'deprecated' ] } ], 'features': [ 'feature1' ] } { 'union': 'FeatureUnion1', diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out index 9337adc9ea..16846dbeb8 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -341,6 +341,7 @@ enum FeatureEnum1 member eins member zwei member drei + feature deprecated feature feature1 object q_obj_FeatureUnion1-base member tag: FeatureEnum1 optional=False diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index c717a7a90b..2160cef082 100755 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -37,6 +37,7 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): for m in members: print(' member %s' % m.name) self._print_if(m.ifcond, indent=8) + self._print_features(m.features, indent=8) self._print_if(ifcond) self._print_features(features) diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index 01f7b1f240..8719c91b48 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -174,11 +174,11 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off comp qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=0.42 lazy_refcounts=off refcount_bits=16 -qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42' +qemu-img: TEST_DIR/t.qcow2: Parameter 'version' does not accept value '0.42' qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=67108864 compat=foobar lazy_refcounts=off refcount_bits=16 -qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar' +qemu-img: TEST_DIR/t.qcow2: Parameter 'version' does not accept value 'foobar' == Check preallocation option == @@ -190,7 +190,7 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off prea qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off preallocation=1234 compression_type=zlib size=67108864 lazy_refcounts=off refcount_bits=16 -qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234' +qemu-img: TEST_DIR/t.qcow2: Parameter 'preallocation' does not accept value '1234' == Check encryption option == diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index b68c443867..3593e8e9c2 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -192,7 +192,7 @@ Job failed: Could not resize image: Failed to grow the L1 table: File too large === Invalid version === {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 67108864, "version": "v1"}}} -{"error": {"class": "GenericError", "desc": "Invalid parameter 'v1'"}} +{"error": {"class": "GenericError", "desc": "Parameter 'version' does not accept value 'v1'"}} {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "lazy-refcounts": true, "size": 67108864, "version": "v2"}}} {"return": {}} diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out index aa94986803..2f09ff5512 100644 --- a/tests/qemu-iotests/237.out +++ b/tests/qemu-iotests/237.out @@ -116,13 +116,13 @@ Job failed: Cannot find device='this doesn't exist' nor node-name='this doesn't == Invalid adapter types == {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "foo", "driver": "vmdk", "file": "node0", "size": 33554432}}} -{"error": {"class": "GenericError", "desc": "Invalid parameter 'foo'"}} +{"error": {"class": "GenericError", "desc": "Parameter 'adapter-type' does not accept value 'foo'"}} {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "IDE", "driver": "vmdk", "file": "node0", "size": 33554432}}} -{"error": {"class": "GenericError", "desc": "Invalid parameter 'IDE'"}} +{"error": {"class": "GenericError", "desc": "Parameter 'adapter-type' does not accept value 'IDE'"}} {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "legacyesx", "driver": "vmdk", "file": "node0", "size": 33554432}}} -{"error": {"class": "GenericError", "desc": "Invalid parameter 'legacyesx'"}} +{"error": {"class": "GenericError", "desc": "Parameter 'adapter-type' does not accept value 'legacyesx'"}} {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": 1, "driver": "vmdk", "file": "node0", "size": 33554432}}} {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'options.adapter-type', expected: string"}} diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 index 9b12b42eed..24ac43f70e 100755 --- a/tests/qemu-iotests/245 +++ b/tests/qemu-iotests/245 @@ -149,7 +149,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): self.reopen(opts, {'node-name': ''}, "Failed to find node with node-name=''") self.reopen(opts, {'node-name': None}, "Invalid parameter type for 'options[0].node-name', expected: string") self.reopen(opts, {'driver': 'raw'}, "Cannot change the option 'driver'") - self.reopen(opts, {'driver': ''}, "Invalid parameter ''") + self.reopen(opts, {'driver': ''}, "Parameter 'driver' does not accept value ''") self.reopen(opts, {'driver': None}, "Invalid parameter type for 'options[0].driver', expected: string") self.reopen(opts, {'file': 'not-found'}, "Cannot find device='' nor node-name='not-found'") self.reopen(opts, {'file': ''}, "Cannot find device='' nor node-name=''") diff --git a/tests/qemu-iotests/287 b/tests/qemu-iotests/287 index 22ce9ff0e4..2d5334e8bf 100755 --- a/tests/qemu-iotests/287 +++ b/tests/qemu-iotests/287 @@ -53,7 +53,7 @@ CLUSTER_SIZE=65536 # Check if we can run this test. output=$(_make_test_img -o 'compression_type=zstd' 64M; _cleanup_test_img) -if echo "$output" | grep -q "Invalid parameter 'zstd'"; then +if echo "$output" | grep -q "Parameter 'compression-type' does not accept value 'zstd'"; then _notrun "ZSTD is disabled" fi diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308 index 6b386bd523..2e3f8f4282 100755 --- a/tests/qemu-iotests/308 +++ b/tests/qemu-iotests/308 @@ -148,7 +148,7 @@ rmdir "$EXT_MP" 2>/dev/null rm -f "$EXT_MP" output=$(fuse_export_add 'export-err' "'mountpoint': '$EXT_MP'" error) -if echo "$output" | grep -q "Invalid parameter 'fuse'"; then +if echo "$output" | grep -q "Parameter 'type' does not accept value 'fuse'"; then _notrun 'No FUSE support' fi diff --git a/tests/unit/check-qom-proplist.c b/tests/unit/check-qom-proplist.c index 48503e0dff..ed341088d3 100644 --- a/tests/unit/check-qom-proplist.c +++ b/tests/unit/check-qom-proplist.c @@ -488,7 +488,7 @@ static void test_dummy_badenum(void) g_assert(dobj == NULL); g_assert(err != NULL); g_assert_cmpstr(error_get_pretty(err), ==, - "Invalid parameter 'yeti'"); + "Parameter 'av' does not accept value 'yeti'"); g_assert(object_resolve_path_component(parent, "dummy0") == NULL);