From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398166; cv=none; d=zoho.com; s=zohoarc; b=AitTnHiDx8F1hzBUoC8O1lOiYzrFX7UEQBc4JOb0s40et6JnjRbPNqKrzrmuRPv7Gh6WahgPnKbikBzNeRBRIHCpMOK6xzNHfk0IV3SPaK7+3CY8W6kyPPZO0EqjWFGUC/Cun8DlN2wm3o2kif7LDg4Xg10+oU3cd6aT15+teL4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398166; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=eN952DneJV5jaQPrb4PkK1dy7u6rVOdLfuEicNLFJTg=; b=ApSz8WNfdLZ1a0HzLIVlIPjyzZlew5dX7x7lRqes97h5gcWCeyEOA2CkGWxssf3RV7aPUdKkowNbWg+ZgIxlMFfNIjh1akQzIpGB56uWhwK0S2y5UO1DzxoFrLkENhyjsqftRhYKht4tEwEp6/npRDjVoukPbNl1q0pvzkU//mk= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398166946731.160789068473; Mon, 24 Jun 2019 10:42:46 -0700 (PDT) Received: from localhost ([::1]:53458 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSzK-0003It-Mm for importer@patchew.org; Mon, 24 Jun 2019 13:42:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48755) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwj-00018S-8W for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwc-0004em-6c for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:39:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34352) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwV-00047e-EV; Mon, 24 Jun 2019 13:39:49 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E8A84882FB; Mon, 24 Jun 2019 17:39:39 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 80D6A60BE2; Mon, 24 Jun 2019 17:39:39 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:21 +0200 Message-Id: <20190624173935.25747-2-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Mon, 24 Jun 2019 17:39:39 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 01/14] qapi: Parse numeric values X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Max Reitz --- tests/qapi-schema/bad-type-int.json | 1 - tests/qapi-schema/enum-int-member.json | 1 - scripts/qapi/common.py | 25 ++++++++++++++++++++---- scripts/qapi/introspect.py | 2 ++ tests/qapi-schema/bad-type-int.err | 2 +- tests/qapi-schema/enum-int-member.err | 2 +- tests/qapi-schema/leading-comma-list.err | 2 +- 7 files changed, 26 insertions(+), 9 deletions(-) diff --git a/tests/qapi-schema/bad-type-int.json b/tests/qapi-schema/bad-ty= pe-int.json index 56fc6f8126..81355eb196 100644 --- a/tests/qapi-schema/bad-type-int.json +++ b/tests/qapi-schema/bad-type-int.json @@ -1,3 +1,2 @@ # we reject an expression with a metatype that is not a string -# FIXME: once the parser understands integer inputs, improve the error mes= sage { 'struct': 1, 'data': { } } diff --git a/tests/qapi-schema/enum-int-member.json b/tests/qapi-schema/enu= m-int-member.json index 6c9c32e149..6958440c6d 100644 --- a/tests/qapi-schema/enum-int-member.json +++ b/tests/qapi-schema/enum-int-member.json @@ -1,3 +1,2 @@ # we reject any enum member that is not a string -# FIXME: once the parser understands integer inputs, improve the error mes= sage { 'enum': 'MyEnum', 'data': [ 1 ] } diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index d61bfdc526..3396ea4a09 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -498,6 +498,8 @@ class QAPISchemaParser(object): raise QAPISemError(info, "Unknown pragma '%s'" % name) =20 def accept(self, skip_comment=3DTrue): + num_match =3D re.compile(r'([-+]?inf|nan|[-+0-9.][0-9a-f.ex]*)') + while True: self.tok =3D self.src[self.cursor] self.pos =3D self.cursor @@ -584,7 +586,22 @@ class QAPISchemaParser(object): return self.line +=3D 1 self.line_pos =3D self.cursor - elif not self.tok.isspace(): + elif self.tok.isspace(): + pass + elif num_match.match(self.src[self.pos:]): + match =3D num_match.match(self.src[self.pos:]).group(0) + try: + self.val =3D int(match, 0) + except ValueError: + try: + self.val =3D float(match) + except ValueError: + raise QAPIParseError(self, + '"%s" is not a valid integer or float' % m= atch) + + self.cursor +=3D len(match) - 1 + return + else: raise QAPIParseError(self, 'Stray "%s"' % self.tok) =20 def get_members(self): @@ -617,9 +634,9 @@ class QAPISchemaParser(object): if self.tok =3D=3D ']': self.accept() return expr - if self.tok not in "{['tfn": + if self.tok not in "{['tfn-+0123456789.i": raise QAPIParseError(self, 'Expected "{", "[", "]", string, ' - 'boolean or "null"') + 'boolean, number or "null"') while True: expr.append(self.get_expr(True)) if self.tok =3D=3D ']': @@ -638,7 +655,7 @@ class QAPISchemaParser(object): elif self.tok =3D=3D '[': self.accept() expr =3D self.get_values() - elif self.tok in "'tfn": + elif self.tok in "'tfn-+0123456789.i": expr =3D self.val self.accept() else: diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index f62cf0a2e1..6a61dd831f 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -57,6 +57,8 @@ def to_qlit(obj, level=3D0, suppress_first_indent=3DFalse= ): ret +=3D indent(level) + '}))' elif isinstance(obj, bool): ret +=3D 'QLIT_QBOOL(%s)' % ('true' if obj else 'false') + elif isinstance(obj, int) and obj >=3D -(2 ** 63) and obj < 2 ** 63: + ret +=3D 'QLIT_QNUM(%i)' % obj else: assert False # not implemented if level > 0: diff --git a/tests/qapi-schema/bad-type-int.err b/tests/qapi-schema/bad-typ= e-int.err index da89895404..e22fb4f655 100644 --- a/tests/qapi-schema/bad-type-int.err +++ b/tests/qapi-schema/bad-type-int.err @@ -1 +1 @@ -tests/qapi-schema/bad-type-int.json:3:13: Stray "1" +tests/qapi-schema/bad-type-int.json:2: 'struct' key must have a string val= ue diff --git a/tests/qapi-schema/enum-int-member.err b/tests/qapi-schema/enum= -int-member.err index 071c5213d8..112175f79d 100644 --- a/tests/qapi-schema/enum-int-member.err +++ b/tests/qapi-schema/enum-int-member.err @@ -1 +1 @@ -tests/qapi-schema/enum-int-member.json:3:31: Stray "1" +tests/qapi-schema/enum-int-member.json:2: Member of enum 'MyEnum' requires= a string name diff --git a/tests/qapi-schema/leading-comma-list.err b/tests/qapi-schema/l= eading-comma-list.err index f5c870bb9c..fa9c80aa57 100644 --- a/tests/qapi-schema/leading-comma-list.err +++ b/tests/qapi-schema/leading-comma-list.err @@ -1 +1 @@ -tests/qapi-schema/leading-comma-list.json:2:13: Expected "{", "[", "]", st= ring, boolean or "null" +tests/qapi-schema/leading-comma-list.json:2:13: Expected "{", "[", "]", st= ring, boolean, number or "null" --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398161; cv=none; d=zoho.com; s=zohoarc; b=Pl8OjG3Xh1cfVqGzPSn4SgKwJMg5PUou7pYeslixpa1Ymy/5E+H/Yrqx2n2LKHY8pUerPpmC9iDyR+03atiUs7sEVfZrmesXDPUrDtqO8ZyvK+kdheuAI2bp229ajGCLiXg8MS+FN6vUaNu781L1FdUPdxzQ8uOlLOZbF5elYiI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398161; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=HyYwWfM7v41K20Klynjo5p52bRcLGrbOFWbIJzTUH8g=; b=J/hDf6058MrbFH2ZRn+35DijMNx/55SKJCsudyD9nHOmSkBWZMISP6U9XHfQKOS5NtwF+9N2WcOp1gYgoz3vyChD3gtJ/2ZSpqp3CwwerbBBAYWXRq24GFgL3Dyr/9L3oy3tzzceEyNZRm9ev7WwifQHMMiWmzE5unNej3fFNR4= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398161638718.7082215448862; Mon, 24 Jun 2019 10:42:41 -0700 (PDT) Received: from localhost ([::1]:53456 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSzE-0003AB-0n for importer@patchew.org; Mon, 24 Jun 2019 13:42:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48766) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwj-00018b-AT for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwd-0004jo-La for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:39:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36692) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwX-0004BT-Vk; Mon, 24 Jun 2019 13:39:50 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 43F2E30832E4; Mon, 24 Jun 2019 17:39:42 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D38E660BE2; Mon, 24 Jun 2019 17:39:41 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:22 +0200 Message-Id: <20190624173935.25747-3-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Mon, 24 Jun 2019 17:39:42 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 02/14] qapi: Move to_c_string() to common.py X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This function will be useful for code generation once we allow default values, so move it to the other "C helper functions". In the process, rewrite it so it supports all nonprintable and non-ASCII characters. Signed-off-by: Max Reitz --- scripts/qapi/common.py | 26 ++++++++++++++++++++++++++ scripts/qapi/introspect.py | 4 ---- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 3396ea4a09..c6754a5856 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -2208,6 +2208,32 @@ def c_fname(filename): return re.sub(r'[^A-Za-z0-9_]', '_', filename) =20 =20 +# Translates a string to a valid C constant +def to_c_string(string): + result =3D '"' + + python2 =3D isinstance(string, bytes) + if not python2: + # Will return integers when iterated over + string =3D string.encode() + + for c in string: + value =3D ord(c) if python2 else c + if value < 0x20 or value > 0x7e: + result +=3D '\\%03o' % value + else: + c =3D chr(value) + if c =3D=3D '"': + result +=3D '\\"' + elif c =3D=3D '\\': + result +=3D '\\\\' + else: + result +=3D c + + result +=3D '"' + return result + + def guardstart(name): return mcgen(''' #ifndef %(name)s diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 6a61dd831f..572e0b8331 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -66,10 +66,6 @@ def to_qlit(obj, level=3D0, suppress_first_indent=3DFals= e): return ret =20 =20 -def to_c_string(string): - return '"' + string.replace('\\', r'\\').replace('"', r'\"') + '"' - - class QAPISchemaGenIntrospectVisitor(QAPISchemaMonolithicCVisitor): =20 def __init__(self, prefix, unmask): --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398640; cv=none; d=zoho.com; s=zohoarc; b=NBMzXM8RFoMy2TKXykBGdtAeYzwaPqqODzHrdpK4ssSTdv+qOXKPRETF/+UmEuPzRZ/Sma/QgzG49f4wfZSlehVK7gLzOD2dfHqA5rNTBDi+drZbgx5TmmUSwm1KRr0EaZgSQO9p/h3O7PboVPGbQk1TXFXKpbw9EExAx8XSpLM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398640; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=wsDGZYfOqHfwJbMQuh1gcGIxvFmiLMM1LC8B7qzSrJw=; b=PL6gATyU783veQ3a856/eiFVwUyjbq7+igrtz8kyK380NIx6PhyITul7C4dLrtwTgNVTxmkWW8upo6qjf6M2mpcZYE/k0dTMHvXvV0t4mCw49xJ5GbuVv3rWigTtRufKbGXqCHcy7I43vcnzkISTXq16z6yICwaQxpkN3PuyUJQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398640847354.19326763109393; Mon, 24 Jun 2019 10:50:40 -0700 (PDT) Received: from localhost ([::1]:53504 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfT6v-0008MY-1E for importer@patchew.org; Mon, 24 Jun 2019 13:50:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48923) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwq-0001Ge-Gp for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwn-00050f-J2 for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34438) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwc-0004RG-Ro; Mon, 24 Jun 2019 13:39:55 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3006630001D8; Mon, 24 Jun 2019 17:39:45 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 37483608BA; Mon, 24 Jun 2019 17:39:44 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:23 +0200 Message-Id: <20190624173935.25747-4-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Mon, 24 Jun 2019 17:39:45 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 03/14] qapi: Introduce default values for struct members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" With this change, it is possible to give default values for struct members, as follows: What you had to do so far: # @member: Some description, defaults to 42. { 'struct': 'Foo', 'data': { '*member': 'int' } } What you can do now: { 'struct': 'Foo', 'data': { '*member': { 'type': 'int', 'default': 42 } } On the C side, this change would remove Foo.has_member, because Foo.member is always valid now. The input visitor deals with setting it. (Naturally, this means that such defaults are useful only for input parameters.) At least three things are left unimplemented: First, support for alternate data types. This is because supporting them would mean having to allocate the object in the input visitor, and then potentially going through multiple levels of nested types. In any case, it would have been difficult and I do not think there is need for such support at this point. Second, support for null. The most important reason for this is that introspection already uses "'default': null" for "no default, but this field is optional". The second reason is that without support for alternate data types, there is not really a point in supporting null. Third, full support for default lists. This has a similar reason to the lack of support for alternate data types: Allocating a default list is not trivial -- unless the list is empty, which is exactly what we have support for. Signed-off-by: Max Reitz --- qapi/introspect.json | 9 +- scripts/qapi/commands.py | 2 +- scripts/qapi/common.py | 167 +++++++++++++++++++++++++++++++++++-- scripts/qapi/doc.py | 20 ++++- scripts/qapi/introspect.py | 2 +- scripts/qapi/types.py | 2 +- scripts/qapi/visit.py | 38 ++++++++- 7 files changed, 217 insertions(+), 23 deletions(-) diff --git a/qapi/introspect.json b/qapi/introspect.json index 1843c1cb17..db703135f9 100644 --- a/qapi/introspect.json +++ b/qapi/introspect.json @@ -198,11 +198,10 @@ # # @default: default when used as command parameter. # If absent, the parameter is mandatory. -# If present, the value must be null. The parameter is -# optional, and behavior when it's missing is not specified -# here. -# Future extension: if present and non-null, the parameter -# is optional, and defaults to this value. +# If present and null, the parameter is optional, and +# behavior when it's missing is not specified here. +# If present and non-null, the parameter is optional, and +# defaults to this value. # # Since: 2.5 ## diff --git a/scripts/qapi/commands.py b/scripts/qapi/commands.py index b929e07be4..6c407cd4ba 100644 --- a/scripts/qapi/commands.py +++ b/scripts/qapi/commands.py @@ -35,7 +35,7 @@ def gen_call(name, arg_type, boxed, ret_type): elif arg_type: assert not arg_type.variants for memb in arg_type.members: - if memb.optional: + if memb.optional and memb.default is None: argstr +=3D 'arg.has_%s, ' % c_name(memb.name) argstr +=3D 'arg.%s, ' % c_name(memb.name) =20 diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index c6754a5856..8c57d0c67a 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -14,6 +14,7 @@ from __future__ import print_function from contextlib import contextmanager import errno +import math import os import re import string @@ -800,6 +801,136 @@ def check_if(expr, info): check_if_str(ifcond, info) =20 =20 +def check_value_str(info, value): + return 'g_strdup(%s)' % to_c_string(value) if type(value) is str else = False + +def check_value_number(info, value): + if type(value) is not float: + return False + if math.isinf(value): + return 'INFINITY' if value > 0 else '-INFINITY' + elif math.isnan(value): + return 'NAN' + else: + return '%.16e' % value + +def check_value_bool(info, value): + if type(value) is not bool: + return False + return 'true' if value else 'false' + +def is_int_type(value): + if type(value) is int: + return True + # 'long' does not exist in Python 3 + try: + if type(value) is long: + return True + except NameError: + pass + + return False + +def gen_check_value_int(bits): + def check_value_int(info, value): + if not is_int_type(value) or \ + value < -(2 ** (bits - 1)) or value >=3D 2 ** (bits - 1): + return False + if bits > 32: + return '%ill' % value + else: + return '%i' % value + + return check_value_int + +def gen_check_value_uint(bits): + def check_value_uint(info, value): + if not is_int_type(value) or value < 0 or value >=3D 2 ** bits: + return False + if bits > 32: + return '%uull' % value + elif bits > 16: + return '%uu' % value + else: + return '%u' % value + + return check_value_uint + +# Check whether the given value fits the given QAPI type. +# If so, return a C representation of the value (pointers point to +# newly allocated objects). +# Otherwise, raise an exception. +def check_value(info, qapi_type, value): + builtin_type_checks =3D { + 'str': check_value_str, + 'int': gen_check_value_int(64), + 'number': check_value_number, + 'bool': check_value_bool, + 'int8': gen_check_value_int(8), + 'int16': gen_check_value_int(16), + 'int32': gen_check_value_int(32), + 'int64': gen_check_value_int(64), + 'uint8': gen_check_value_uint(8), + 'uint16': gen_check_value_uint(16), + 'uint32': gen_check_value_uint(32), + 'uint64': gen_check_value_uint(64), + 'size': gen_check_value_uint(64), + } + + # Cannot support null because that would require a value of "None" + # (which is reserved for no default) + unsupported_builtin_types =3D ['null', 'any', 'QType'] + + if type(qapi_type) is list: + has_list =3D True + qapi_type =3D qapi_type[0] + elif qapi_type.endswith('List'): + has_list =3D True + qapi_type =3D qapi_type[:-4] + else: + has_list =3D False + + if has_list: + if value =3D=3D []: + return 'NULL' + else: + raise QAPISemError(info, + "Support for non-empty lists as default values has not bee= n " \ + "implemented yet: '{}'".format(value)) + + if qapi_type in builtin_type_checks: + c_val =3D builtin_type_checks[qapi_type](info, value) + if not c_val: + raise QAPISemError(info, + "Value '{}' does not match type {}".format(value, qapi_typ= e)) + return c_val + + if qapi_type in unsupported_builtin_types: + raise QAPISemError(info, + "Cannot specify values for type %s" % qapi_type) + + if qapi_type in enum_types: + if not check_value_str(info, value): + raise QAPISemError(info, + "Enum values must be strings, but '{}' is no string" \ + .format(value)) + + enum_values =3D enum_types[qapi_type]['data'] + for ev in enum_values: + if ev['name'] =3D=3D value: + return c_enum_const(qapi_type, value, + enum_types[qapi_type].get('prefix')) + + raise QAPISemError(info, + "Value '{}' does not occur in enum {}".format(value, qapi_type= )) + + # TODO: Support alternates + + raise QAPISemError(info, + "Cannot specify values for type %s (not built-in or an enum)" % + qapi_type) + + def check_type(info, source, value, allow_array=3DFalse, allow_dict=3DFalse, allow_optional=3DFalse, allow_metas=3D[]): @@ -842,15 +973,22 @@ def check_type(info, source, value, allow_array=3DFal= se, if c_name(key, False) =3D=3D 'u' or c_name(key, False).startswith(= 'has_'): raise QAPISemError(info, "Member of %s uses reserved name '%s'" % (source, key)) - # Todo: allow dictionaries to represent default values of - # an optional argument. + check_known_keys(info, "member '%s' of %s" % (key, source), - arg, ['type'], ['if']) + arg, ['type'], ['if', 'default']) check_type(info, "Member '%s' of %s" % (key, source), arg['type'], allow_array=3DTrue, allow_metas=3D['built-in', 'union', 'alternate', 'struc= t', 'enum']) =20 + if 'default' in arg: + if key[0] !=3D '*': + raise QAPISemError(info, + "'%s' is not optional, so it cannot have a default val= ue" % + key) + + check_value(info, arg['type'], arg['default']) + =20 def check_command(expr, info): name =3D expr['command'] @@ -1601,13 +1739,14 @@ class QAPISchemaFeature(QAPISchemaMember): =20 =20 class QAPISchemaObjectTypeMember(QAPISchemaMember): - def __init__(self, name, typ, optional, ifcond=3DNone): + def __init__(self, name, typ, optional, ifcond=3DNone, default=3DNone): QAPISchemaMember.__init__(self, name, ifcond) assert isinstance(typ, str) assert isinstance(optional, bool) self._type_name =3D typ self.type =3D None self.optional =3D optional + self.default =3D default =20 def check(self, schema): assert self.owner @@ -1917,7 +2056,7 @@ class QAPISchema(object): name, info, doc, ifcond, self._make_enum_members(data), prefix)) =20 - def _make_member(self, name, typ, ifcond, info): + def _make_member(self, name, typ, ifcond, default, info): optional =3D False if name.startswith('*'): name =3D name[1:] @@ -1925,10 +2064,11 @@ class QAPISchema(object): if isinstance(typ, list): assert len(typ) =3D=3D 1 typ =3D self._make_array_type(typ[0], info) - return QAPISchemaObjectTypeMember(name, typ, optional, ifcond) + return QAPISchemaObjectTypeMember(name, typ, optional, ifcond, def= ault) =20 def _make_members(self, data, info): - return [self._make_member(key, value['type'], value.get('if'), inf= o) + return [self._make_member(key, value['type'], value.get('if'), + value.get('default'), info) for (key, value) in data.items()] =20 def _def_struct_type(self, expr, info, doc): @@ -1951,7 +2091,7 @@ class QAPISchema(object): typ =3D self._make_array_type(typ[0], info) typ =3D self._make_implicit_object_type( typ, info, None, self.lookup_type(typ), - 'wrapper', [self._make_member('data', typ, None, info)]) + 'wrapper', [self._make_member('data', typ, None, None, info)]) return QAPISchemaObjectTypeVariant(case, typ, ifcond) =20 def _def_union_type(self, expr, info, doc): @@ -2234,6 +2374,15 @@ def to_c_string(string): return result =20 =20 +# Translates a value for the given QAPI type to its C representation. +# The caller must have called check_value() during parsing to be sure +# that the given value fits the type. +def c_value(qapi_type, value): + pseudo_info =3D {'file': '(generator bug)', 'line': 0, 'parent': None} + # The caller guarantees this does not raise an exception + return check_value(pseudo_info, qapi_type, value) + + def guardstart(name): return mcgen(''' #ifndef %(name)s @@ -2356,7 +2505,7 @@ def build_params(arg_type, boxed, extra=3DNone): for memb in arg_type.members: ret +=3D sep sep =3D ', ' - if memb.optional: + if memb.optional and memb.default is None: ret +=3D 'bool has_%s, ' % c_name(memb.name) ret +=3D '%s %s' % (memb.type.c_param_type(), c_name(memb.name)) diff --git a/scripts/qapi/doc.py b/scripts/qapi/doc.py index 5fc0fc7e06..78a9052738 100755 --- a/scripts/qapi/doc.py +++ b/scripts/qapi/doc.py @@ -139,13 +139,29 @@ def texi_enum_value(value, desc, suffix): value.name, desc, texi_if(value.ifcond, prefix=3D'@*')) =20 =20 +def doc_value(value): + if value is True: + return 'true' + elif value is False: + return 'false' + elif value is None: + return 'null' + else: + return '{}'.format(value) + def texi_member(member, desc, suffix): """Format a table of members item for an object type member""" typ =3D member.type.doc_type() membertype =3D ': ' + typ if typ else '' + + optional_info =3D '' + if member.default is not None: + optional_info =3D ' (optional, default: %s)' % doc_value(member.de= fault) + elif member.optional: + optional_info =3D ' (optional)' + return '@item @code{%s%s}%s%s\n%s%s' % ( - member.name, membertype, - ' (optional)' if member.optional else '', + member.name, membertype, optional_info, suffix, desc, texi_if(member.ifcond, prefix=3D'@*')) =20 =20 diff --git a/scripts/qapi/introspect.py b/scripts/qapi/introspect.py index 572e0b8331..7d73020a42 100644 --- a/scripts/qapi/introspect.py +++ b/scripts/qapi/introspect.py @@ -159,7 +159,7 @@ const QLitObject %(c_name)s =3D %(c_string)s; def _gen_member(self, member): ret =3D {'name': member.name, 'type': self._use_type(member.type)} if member.optional: - ret['default'] =3D None + ret['default'] =3D member.default if member.ifcond: ret =3D (ret, {'if': member.ifcond}) return ret diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py index 3edd9374aa..46a6d33379 100644 --- a/scripts/qapi/types.py +++ b/scripts/qapi/types.py @@ -44,7 +44,7 @@ def gen_struct_members(members): ret =3D '' for memb in members: ret +=3D gen_if(memb.ifcond) - if memb.optional: + if memb.optional and memb.default is None: ret +=3D mcgen(''' bool has_%(c_name)s; ''', diff --git a/scripts/qapi/visit.py b/scripts/qapi/visit.py index 484ebb66ad..0960e25a25 100644 --- a/scripts/qapi/visit.py +++ b/scripts/qapi/visit.py @@ -40,10 +40,14 @@ def gen_visit_object_members(name, base, members, varia= nts): void visit_type_%(c_name)s_members(Visitor *v, %(c_name)s *obj, Error **er= rp) { Error *err =3D NULL; - ''', c_name=3Dc_name(name)) =20 + if len([m for m in members if m.default is not None]) > 0: + ret +=3D mcgen(''' + bool has_optional; +''') + if base: ret +=3D mcgen(''' visit_type_%(c_type)s_members(v, (%(c_type)s *)obj, &err); @@ -53,13 +57,28 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name= )s *obj, Error **errp) ''', c_type=3Dbase.c_name()) =20 + ret +=3D mcgen(''' + +''') + for memb in members: ret +=3D gen_if(memb.ifcond) if memb.optional: + if memb.default is not None: + optional_target =3D 'has_optional' + # Visitors other than the input visitor do not have to imp= lement + # .optional(). Therefore, we have to initialize has_optio= nal. + # Initialize it to true, because the field's value is alwa= ys + # present when using any visitor but the input visitor. + ret +=3D mcgen(''' + has_optional =3D true; +''') + else: + optional_target =3D 'obj->has_' + c_name(memb.name) ret +=3D mcgen(''' - if (visit_optional(v, "%(name)s", &obj->has_%(c_name)s)) { + if (visit_optional(v, "%(name)s", &%(opt_target)s)) { ''', - name=3Dmemb.name, c_name=3Dc_name(memb.name)) + name=3Dmemb.name, opt_target=3Doptional_target) push_indent() ret +=3D mcgen(''' visit_type_%(c_type)s(v, "%(name)s", &obj->%(c_name)s, &err); @@ -69,7 +88,16 @@ void visit_type_%(c_name)s_members(Visitor *v, %(c_name)= s *obj, Error **errp) ''', c_type=3Dmemb.type.c_name(), name=3Dmemb.name, c_name=3Dc_name(memb.name)) - if memb.optional: + if memb.default is not None: + pop_indent() + ret +=3D mcgen(''' + } else { + obj->%(c_name)s =3D %(c_value)s; + } +''', + c_name=3Dc_name(memb.name), + c_value=3Dc_value(memb._type_name, memb.default)) + elif memb.optional: pop_indent() ret +=3D mcgen(''' } @@ -287,6 +315,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisit= or): self._add_system_module(None, ' * Built-in QAPI visitors') self._genc.preamble_add(mcgen(''' #include "qemu/osdep.h" +#include #include "qapi/error.h" #include "qapi/qapi-builtin-visit.h" ''')) @@ -302,6 +331,7 @@ class QAPISchemaGenVisitVisitor(QAPISchemaModularCVisit= or): visit =3D self._module_basename('qapi-visit', name) self._genc.preamble_add(mcgen(''' #include "qemu/osdep.h" +#include #include "qapi/error.h" #include "qapi/qmp/qerror.h" #include "%(visit)s.h" --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398184; cv=none; d=zoho.com; s=zohoarc; b=dJYYy3MgceMu+YSW1aYKLax08VeDM/TdW0p5Htp/hjwljzsQxlx7+VpEoyIX/b93T4bD6kJYoHE2al90a6/UQyuVuhF/bfG3VQs4OnyrSflZRiasKFtTAQGu1AGg9XxmKqJb63+8Z/tCxoLETNeJQ3UQHdB0oMUNMS0yK8xEOv8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398184; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=3jqLrUwZBCmkq7WnTAvHajYoNJoNeyyFdZfrSpjMS/4=; b=KNKPs/He5T0dp/lknBIm3DAYfXdyWywldt5ctaub29qy9ZkcuoHyflP7zJ39Bfqe5xD6jnJxsANsNMEpnhftuMEW5BCm1VjEPCXOGqMydGXgJpRyhIwSQT5biODMgJr3B7rexu95R5RbMFWfmUdnH9/IAFwlwcNdTTy8DAKy1c4= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398184842544.1194435811931; Mon, 24 Jun 2019 10:43:04 -0700 (PDT) Received: from localhost ([::1]:53462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSzc-0003Wv-LT for importer@patchew.org; Mon, 24 Jun 2019 13:43:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48810) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwl-0001As-F6 for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwj-0004sG-6z for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34424) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwZ-0004LB-Uq; Mon, 24 Jun 2019 13:39:52 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 82D823082E63; Mon, 24 Jun 2019 17:39:47 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 193415D71A; Mon, 24 Jun 2019 17:39:46 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:24 +0200 Message-Id: <20190624173935.25747-5-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Mon, 24 Jun 2019 17:39:47 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 04/14] qapi: Allow optional discriminators X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Optional discriminators are fine, as long as there is a default value. Signed-off-by: Max Reitz --- scripts/qapi/common.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/qapi/common.py b/scripts/qapi/common.py index 8c57d0c67a..203623795b 100644 --- a/scripts/qapi/common.py +++ b/scripts/qapi/common.py @@ -1052,11 +1052,21 @@ def check_union(expr, info): base_members =3D find_base_members(base) assert base_members is not None =20 - # The value of member 'discriminator' must name a non-optional - # member of the base struct. + # The value of member 'discriminator' must name a member of + # the base struct. (Optional members are allowed, but the + # discriminator name must not start with '*', so keep + # allow_optional=3DFalse.) check_name(info, "Discriminator of flat union '%s'" % name, discriminator) + discriminator_value =3D base_members.get(discriminator) + if not discriminator_value: + discriminator_value =3D base_members.get('*' + discriminator) + if discriminator_value and 'default' not in discriminator_valu= e: + raise QAPISemError(info, + "Optional discriminator '%s' has no default value" % + discriminator) + if not discriminator_value: raise QAPISemError(info, "Discriminator '%s' is not a member of base= " --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398698; cv=none; d=zoho.com; s=zohoarc; b=i+IDRXtrmbCOojj6phlb+8pV0s0ZuQIVHgnWtunwFf/cGWXZQLhAStpmlGnS4T1VC/JtepPPWWfZLA823WmPFqSsxSG70fEZe7GIZjsNsRPyuurMgAaAJyVBjoTZGzUfxoj0Ip19bbfxyfzREOBCrGTW+W+U/GtmKQ5PTWQE9ZQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398698; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=FJ6pOjeEgIdIbrrUSLUEHQhwmH856LJ5NS0TR9FXHF8=; b=NdURb0tOJFHsO2M1WDYmTHDvRwPruEm5xdNiszdVdGNJScDIxE/ldkDedgv6hFpgU6JpaQ730v/hiSzcVByFr0BF4luh4otc21frezZlr/7JFkyqFIeXl0nB08p6pd2BR6pvma+rui7z4NDQQhf/1NkesLXtGjUyR27wfBF12Z0= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398698015736.363067054594; Mon, 24 Jun 2019 10:51:38 -0700 (PDT) Received: from localhost ([::1]:53508 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfT7x-0000ca-1u for importer@patchew.org; Mon, 24 Jun 2019 13:51:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48837) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwn-0001Df-LQ for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwl-0004wQ-FL for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59502) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwc-0004QO-Lp; Mon, 24 Jun 2019 13:39:54 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 118B93082B5A; Mon, 24 Jun 2019 17:39:50 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6EB31600C0; Mon, 24 Jun 2019 17:39:49 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:25 +0200 Message-Id: <20190624173935.25747-6-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Mon, 24 Jun 2019 17:39:50 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 05/14] qapi: Document default values for struct members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Max Reitz --- docs/devel/qapi-code-gen.txt | 81 ++++++++++++++++++++++++++++++------ 1 file changed, 69 insertions(+), 12 deletions(-) diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt index e8ec8ac1de..9dd7816701 100644 --- a/docs/devel/qapi-code-gen.txt +++ b/docs/devel/qapi-code-gen.txt @@ -334,11 +334,15 @@ Usage: { 'struct': STRING, 'data': DICT, '*base': STR= UCT-NAME } A struct is a dictionary containing a single 'data' key whose value is a dictionary; the dictionary may be empty. This corresponds to a struct in C or an Object in JSON. Each value of the 'data' dictionary -must be the name of a type, or a one-element array containing a type -name. An example of a struct is: +must be the name of a type, a one-element array containing a type +name, or a dictionary whose 'type' key gives a type name. An example +of a struct is: =20 { 'struct': 'MyType', - 'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } } + 'data': { 'member1': 'str', + 'member2': 'int', + '*member3': 'str', + '*member4': { 'type': 'bool' } } } =20 The use of '*' as a prefix to the name means the member is optional in the corresponding JSON protocol usage. @@ -371,6 +375,21 @@ A structure that is used in both input and output of v= arious commands must consider the backwards compatibility constraints of both directions of use. =20 +Instead of describing the default values for input structures' members +in the documentation, it is possible to specify it explicitly in the +struct definition. In the following example, we let the optional +'member4' of the above 'MyType' struct default to true: + +{ 'struct': 'MyType', + 'data': { 'member1': 'str', + 'member2': 'int', + '*member3': 'str', + '*member4': { 'type': 'bool', 'default': true } } } + +In the resulting C interface in QEMU 'member4' will then appear as +non-optional. If the client does not specify it, it will be +automatically set to true. + A struct definition can specify another struct as its base. In this case, the members of the base type are included as top-level membe= rs of the new struct's dictionary in the Client JSON Protocol wire @@ -472,8 +491,9 @@ All branches of the union must be complex types, and th= e top-level members of the union dictionary on the wire will be combination of members from both the base type and the appropriate branch type (when merging two dictionaries, there must be no keys in common). The -'discriminator' member must be the name of a non-optional enum-typed -member of the base struct. +'discriminator' member must be the name of an enum-typed member of the +base struct. If that member is optional, a default value must be +given. =20 The following example enhances the above simple union example by adding an optional common member 'read-only', renaming the @@ -504,6 +524,24 @@ In the resulting generated C data types, a flat union = is represented as a struct with the base members included directly, and then a union of structures for each branch of the struct. =20 +In the following example, the above BlockdevOptions struct is changed +so it defaults to the 'file' driver is that field is omitted on the +wire: + + { 'union': 'BlockdevOptions', + 'base': { + '*driver': { 'type': 'BlockdevDriver', 'default': 'file' }, + '*read-only': 'bool' + }, + 'discriminator': 'driver', + 'data': { 'file': 'BlockdevOptionsFile', + 'qcow2': 'BlockdevOptionsQcow2' } } + +Now the 'file' JSON object can be abbreviated to: + + { "read-only": true, + "filename": "/some/place/my-image" } + A simple union can always be re-written as a flat union where the base class has a single member named 'type', and where each branch of the union has a struct with a single member named 'data'. That is, @@ -922,11 +960,11 @@ 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 -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 -must search the entire object when learning whether a particular -member is supported. +member is optional if "default" is present. If "default" has any +value but null, that value will be used as the default if the member +is not specified. The "members" array is in no particular order; +clients must search the entire object when learning whether a +particular member is supported. =20 Example: the SchemaInfo for MyType from section Struct types =20 @@ -934,7 +972,8 @@ Example: the SchemaInfo for MyType from section Struct = types "members": [ { "name": "member1", "type": "str" }, { "name": "member2", "type": "int" }, - { "name": "member3", "type": "str", "default": null } ] } + { "name": "member3", "type": "str", "default": null }, + { "name": "member4", "type": "bool", "default": true } ] } =20 "tag" is the name of the common member serving as type tag. "variants" is a JSON array describing the object's variant members. @@ -1052,7 +1091,9 @@ qmp_my_command(); everything else is produced by the = generator. =20 $ cat example-schema.json { 'struct': 'UserDefOne', - 'data': { 'integer': 'int', '*string': 'str' } } + 'data': { 'integer': 'int', + '*string': 'str', + '*defaultbool': { 'type': 'bool', 'default': true } } } =20 { 'command': 'my-command', 'data': { 'arg1': ['UserDefOne'] }, @@ -1104,6 +1145,7 @@ Example: int64_t integer; bool has_string; char *string; + bool defaultbool; }; =20 void qapi_free_UserDefOne(UserDefOne *obj); @@ -1207,6 +1249,7 @@ Example: void visit_type_UserDefOne_members(Visitor *v, UserDefOne *obj, Error = **errp) { Error *err =3D NULL; + bool has_optional; =20 visit_type_int(v, "integer", &obj->integer, &err); if (err) { @@ -1218,6 +1261,14 @@ Example: goto out; } } + if (visit_optional(v, "defaultbool", &has_optional)) { + visit_type_bool(v, "defaultbool", &obj->defaultbool, &err); + if (err) { + goto out; + } + } else { + obj->defaultbool =3D true; + } =20 out: error_propagate(errp, err); @@ -1563,6 +1614,12 @@ Example: { "type", QLIT_QSTR("str"), }, {} })), + QLIT_QDICT(((QLitDictEntry[]) { + { "default", QLIT_QBOOL(true), }, + { "name", QLIT_QSTR("defaultbool"), }, + { "type", QLIT_QSTR("bool"), }, + {} + })), {} })), }, { "meta-type", QLIT_QSTR("object"), }, --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398935; cv=none; d=zoho.com; s=zohoarc; b=lSr1olrdHV4pussH21z7j86zTqhLnOxIb9Wcmhp/zOz+NU1xJfiscGrWsHg491ZYhgDG3Afku0u8FSAS3Ti5s8uoP12qx9+125tIPZLDgeC5B4ixmCU5wVGKvN10B2VombauBH7+Cnittb8PjC08iFmNG7b169R476G0ivqb6Mk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398935; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=pOXZAnZ4JmrNlYoTjinLrPZvgHWYMLy21lsl65xhjeo=; b=Ag/F6hiIeNiFOlMif//bq9KRoUmxDC2+fWNkjW5+t4WIio+rIObDWo92D56F85jMJLbOJdvDHS03J7PzvZnxcjfr4/8MoUrDzJAaMdhtJR7Kv7XttKHUOU5hmfJ6nu+cH0oYYX3ayEKY/FqBxD3bxSzSVLpVHK2w9LN8C+Hqxrc= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398935368926.5035943239096; Mon, 24 Jun 2019 10:55:35 -0700 (PDT) Received: from localhost ([::1]:53540 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTBm-0004gT-Cs for importer@patchew.org; Mon, 24 Jun 2019 13:55:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48974) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSws-0001Lw-HZ for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwr-0005BQ-5M for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40862) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwl-0004j4-Ge; Mon, 24 Jun 2019 13:40:05 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6E2AB307D850; Mon, 24 Jun 2019 17:39:52 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 04213600C0; Mon, 24 Jun 2019 17:39:51 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:26 +0200 Message-Id: <20190624173935.25747-7-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.48]); Mon, 24 Jun 2019 17:39:52 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 06/14] test-qapi: Print struct members' default values X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Max Reitz --- tests/qapi-schema/test-qapi.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py index b0f770b9bd..320e027d28 100644 --- a/tests/qapi-schema/test-qapi.py +++ b/tests/qapi-schema/test-qapi.py @@ -44,8 +44,12 @@ class QAPISchemaTestVisitor(QAPISchemaVisitor): if base: print(' base %s' % base.name) for m in members: - print(' member %s: %s optional=3D%s' - % (m.name, m.type.name, m.optional)) + if m.default is not None: + default =3D ' default=3D{}'.format(m.default) + else: + default =3D '' + print(' member %s: %s optional=3D%s%s' + % (m.name, m.type.name, m.optional, default)) self._print_if(m.ifcond, 8) self._print_variants(variants) self._print_if(ifcond) --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398945; cv=none; d=zoho.com; s=zohoarc; b=SmZleRW02SAgRXBWtfgCoT2puJnj7UR3JCFFhBiqbX2H4IjS1dYZS0Cba9tkSj30GQZWI2zUpukCWh2rmjHVMjky6B0QZcRt5l/llpm4ZXig25bSH9+qNqhJZPS59RMTgdLS9iIsfwe8MYfhS7XCOl+YuqLLHuurWIXB9V2Kuc8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398945; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=aLnks33CPPEFCSjCAVlRHsfPeci2agICjLktdcUkXXc=; b=Kijanelekt2ZhXp39HPlEb3MdLo74QZxZbk3o61R1RXxvF2ILNsl0vu+dDSaFSw8EyDz6rYKOaq1PosK6H1dC0lkXdZPm7MEkW5exbAmUheZBnfsXLwmQ7JTK0wLQBAvaDBZUQcR8r/P72NEvjamAOUoINN2/ksMYa/9cCBMVuI= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398945027118.52372045612424; Mon, 24 Jun 2019 10:55:45 -0700 (PDT) Received: from localhost ([::1]:53538 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTBg-0004Ia-Es for importer@patchew.org; Mon, 24 Jun 2019 13:55:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49189) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSxA-0001j9-Sf for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwz-0005V1-Lj for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56364) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwl-0004rY-Hm; Mon, 24 Jun 2019 13:40:05 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 32B8E30872EA; Mon, 24 Jun 2019 17:39:55 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 60894600C0; Mon, 24 Jun 2019 17:39:54 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:27 +0200 Message-Id: <20190624173935.25747-8-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Mon, 24 Jun 2019 17:39:55 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 07/14] tests: Test QAPI default values for struct members X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This patch adds a number of tests for how not to specify a default for an optional struct member, and one rather large test on how to do it right (in qapi-schema-test.json). As a side effect, this patch tests the QAPI code generator's integer and float parsing capability. Signed-off-by: Max Reitz --- tests/Makefile.include | 14 ++++++++++ tests/qapi-schema/qapi-schema-test.json | 28 +++++++++++++++++++ .../struct-member-alternate-default.json | 10 +++++++ ...struct-member-bool-wrong-default-type.json | 3 ++ .../struct-member-enum-invalid-default.json | 4 +++ ...struct-member-enum-wrong-default-type.json | 4 +++ .../struct-member-float-invalid-default.json | 4 +++ ...truct-member-float-wrong-default-type.json | 3 ++ .../struct-member-int-wrong-default-type.json | 3 ++ .../struct-member-int8-erange-default.json | 3 ++ .../struct-member-list-nonempty-default.json | 4 +++ .../struct-member-non-optional-default.json | 3 ++ .../struct-member-null-default.json | 6 ++++ .../struct-member-str-wrong-default-type.json | 3 ++ .../struct-member-uint8-erange-default.json | 3 ++ .../struct-member-uint8-negative-default.json | 3 ++ tests/qapi-schema/qapi-schema-test.out | 24 ++++++++++++++++ .../struct-member-alternate-default.err | 1 + .../struct-member-alternate-default.exit | 1 + .../struct-member-alternate-default.out | 0 .../struct-member-bool-wrong-default-type.err | 1 + ...struct-member-bool-wrong-default-type.exit | 1 + .../struct-member-bool-wrong-default-type.out | 0 .../struct-member-enum-invalid-default.err | 1 + .../struct-member-enum-invalid-default.exit | 1 + .../struct-member-enum-invalid-default.out | 0 .../struct-member-enum-wrong-default-type.err | 1 + ...struct-member-enum-wrong-default-type.exit | 1 + .../struct-member-enum-wrong-default-type.out | 0 .../struct-member-float-invalid-default.err | 1 + .../struct-member-float-invalid-default.exit | 1 + .../struct-member-float-invalid-default.out | 0 ...struct-member-float-wrong-default-type.err | 1 + ...truct-member-float-wrong-default-type.exit | 1 + ...struct-member-float-wrong-default-type.out | 0 .../struct-member-int-wrong-default-type.err | 1 + .../struct-member-int-wrong-default-type.exit | 1 + .../struct-member-int-wrong-default-type.out | 0 .../struct-member-int8-erange-default.err | 1 + .../struct-member-int8-erange-default.exit | 1 + .../struct-member-int8-erange-default.out | 0 .../struct-member-list-nonempty-default.err | 1 + .../struct-member-list-nonempty-default.exit | 1 + .../struct-member-list-nonempty-default.out | 0 .../struct-member-non-optional-default.err | 1 + .../struct-member-non-optional-default.exit | 1 + .../struct-member-non-optional-default.out | 0 .../struct-member-null-default.err | 1 + .../struct-member-null-default.exit | 1 + .../struct-member-null-default.out | 0 .../struct-member-str-wrong-default-type.err | 1 + .../struct-member-str-wrong-default-type.exit | 1 + .../struct-member-str-wrong-default-type.out | 0 .../struct-member-uint8-erange-default.err | 1 + .../struct-member-uint8-erange-default.exit | 1 + .../struct-member-uint8-erange-default.out | 0 .../struct-member-uint8-negative-default.err | 1 + .../struct-member-uint8-negative-default.exit | 1 + .../struct-member-uint8-negative-default.out | 0 59 files changed, 150 insertions(+) create mode 100644 tests/qapi-schema/struct-member-alternate-default.json create mode 100644 tests/qapi-schema/struct-member-bool-wrong-default-type= .json create mode 100644 tests/qapi-schema/struct-member-enum-invalid-default.js= on create mode 100644 tests/qapi-schema/struct-member-enum-wrong-default-type= .json create mode 100644 tests/qapi-schema/struct-member-float-invalid-default.j= son create mode 100644 tests/qapi-schema/struct-member-float-wrong-default-typ= e.json create mode 100644 tests/qapi-schema/struct-member-int-wrong-default-type.= json create mode 100644 tests/qapi-schema/struct-member-int8-erange-default.json create mode 100644 tests/qapi-schema/struct-member-list-nonempty-default.j= son create mode 100644 tests/qapi-schema/struct-member-non-optional-default.js= on create mode 100644 tests/qapi-schema/struct-member-null-default.json create mode 100644 tests/qapi-schema/struct-member-str-wrong-default-type.= json create mode 100644 tests/qapi-schema/struct-member-uint8-erange-default.js= on create mode 100644 tests/qapi-schema/struct-member-uint8-negative-default.= json create mode 100644 tests/qapi-schema/struct-member-alternate-default.err create mode 100644 tests/qapi-schema/struct-member-alternate-default.exit create mode 100644 tests/qapi-schema/struct-member-alternate-default.out create mode 100644 tests/qapi-schema/struct-member-bool-wrong-default-type= .err create mode 100644 tests/qapi-schema/struct-member-bool-wrong-default-type= .exit create mode 100644 tests/qapi-schema/struct-member-bool-wrong-default-type= .out create mode 100644 tests/qapi-schema/struct-member-enum-invalid-default.err create mode 100644 tests/qapi-schema/struct-member-enum-invalid-default.ex= it create mode 100644 tests/qapi-schema/struct-member-enum-invalid-default.out create mode 100644 tests/qapi-schema/struct-member-enum-wrong-default-type= .err create mode 100644 tests/qapi-schema/struct-member-enum-wrong-default-type= .exit create mode 100644 tests/qapi-schema/struct-member-enum-wrong-default-type= .out create mode 100644 tests/qapi-schema/struct-member-float-invalid-default.e= rr create mode 100644 tests/qapi-schema/struct-member-float-invalid-default.e= xit create mode 100644 tests/qapi-schema/struct-member-float-invalid-default.o= ut create mode 100644 tests/qapi-schema/struct-member-float-wrong-default-typ= e.err create mode 100644 tests/qapi-schema/struct-member-float-wrong-default-typ= e.exit create mode 100644 tests/qapi-schema/struct-member-float-wrong-default-typ= e.out create mode 100644 tests/qapi-schema/struct-member-int-wrong-default-type.= err create mode 100644 tests/qapi-schema/struct-member-int-wrong-default-type.= exit create mode 100644 tests/qapi-schema/struct-member-int-wrong-default-type.= out create mode 100644 tests/qapi-schema/struct-member-int8-erange-default.err create mode 100644 tests/qapi-schema/struct-member-int8-erange-default.exit create mode 100644 tests/qapi-schema/struct-member-int8-erange-default.out create mode 100644 tests/qapi-schema/struct-member-list-nonempty-default.e= rr create mode 100644 tests/qapi-schema/struct-member-list-nonempty-default.e= xit create mode 100644 tests/qapi-schema/struct-member-list-nonempty-default.o= ut create mode 100644 tests/qapi-schema/struct-member-non-optional-default.err create mode 100644 tests/qapi-schema/struct-member-non-optional-default.ex= it create mode 100644 tests/qapi-schema/struct-member-non-optional-default.out create mode 100644 tests/qapi-schema/struct-member-null-default.err create mode 100644 tests/qapi-schema/struct-member-null-default.exit create mode 100644 tests/qapi-schema/struct-member-null-default.out create mode 100644 tests/qapi-schema/struct-member-str-wrong-default-type.= err create mode 100644 tests/qapi-schema/struct-member-str-wrong-default-type.= exit create mode 100644 tests/qapi-schema/struct-member-str-wrong-default-type.= out create mode 100644 tests/qapi-schema/struct-member-uint8-erange-default.err create mode 100644 tests/qapi-schema/struct-member-uint8-erange-default.ex= it create mode 100644 tests/qapi-schema/struct-member-uint8-erange-default.out create mode 100644 tests/qapi-schema/struct-member-uint8-negative-default.= err create mode 100644 tests/qapi-schema/struct-member-uint8-negative-default.= exit create mode 100644 tests/qapi-schema/struct-member-uint8-negative-default.= out diff --git a/tests/Makefile.include b/tests/Makefile.include index db750dd6d0..76dc581096 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -451,6 +451,20 @@ qapi-schema +=3D returns-whitelist.json qapi-schema +=3D struct-base-clash-deep.json qapi-schema +=3D struct-base-clash.json qapi-schema +=3D struct-data-invalid.json +qapi-schema +=3D struct-member-alternate-default.json +qapi-schema +=3D struct-member-bool-wrong-default-type.json +qapi-schema +=3D struct-member-enum-invalid-default.json +qapi-schema +=3D struct-member-enum-wrong-default-type.json +qapi-schema +=3D struct-member-float-invalid-default.json +qapi-schema +=3D struct-member-float-wrong-default-type.json +qapi-schema +=3D struct-member-int-wrong-default-type.json +qapi-schema +=3D struct-member-int8-erange-default.json +qapi-schema +=3D struct-member-list-nonempty-default.json +qapi-schema +=3D struct-member-non-optional-default.json +qapi-schema +=3D struct-member-null-default.json +qapi-schema +=3D struct-member-str-wrong-default-type.json +qapi-schema +=3D struct-member-uint8-erange-default.json +qapi-schema +=3D struct-member-uint8-negative-default.json qapi-schema +=3D struct-member-invalid-dict.json qapi-schema +=3D struct-member-invalid.json qapi-schema +=3D trailing-comma-list.json diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qa= pi-schema-test.json index c6d59acc3e..12ae387d46 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -281,3 +281,31 @@ 'cfs1': 'CondFeatureStruct1', 'cfs2': 'CondFeatureStruct2', 'cfs3': 'CondFeatureStruct3' } } + +# test defaults for optional struct members + +{ 'enum': 'TestDefaultEnum', + 'data': [ 'value1', 'value2', 'value3' ] } + +{ 'struct': 'TestDefaultSubStruct', + 'data': { 'member': 'int' } } + +{ 'struct': 'TestDefaultStruct', + 'data': { + '*bool_false': { 'type': 'bool', 'default': false }, + '*bool_true': { 'type': 'bool', 'default': true }, + '*integer': { 'type': 'int', 'default': -42 }, + '*int8_low': { 'type': 'int8', 'default': -0x80 }, + '*int8_high': { 'type': 'int8', 'default': 0x7f }, + '*uint8_high': { 'type': 'uint8', 'default': 0xff }, + '*size': { 'type': 'size', 'default': 0xffffffffffffffff }, + '*fpneg': { 'type': 'number', 'default': -.375e3 }, + '*fppos': { 'type': 'number', 'default': +42. }, + '*fpposinf': { 'type': 'number', 'default': inf }, + '*fpneginf': { 'type': 'number', 'default': -inf }, + '*fpnan': { 'type': 'number', 'default': nan }, + '*str': { 'type': 'str', 'default': 'foo \\=E9=B9=BF"\u007f\b"\'' }, + '*enum_value2': { 'type': 'TestDefaultEnum', 'default': 'value2' }, + '*list_scalar': { 'type': ['int'], 'default': [] }, + '*list_struct': { 'type': ['TestDefaultSubStruct'], 'default': [] } + } } diff --git a/tests/qapi-schema/struct-member-alternate-default.json b/tests= /qapi-schema/struct-member-alternate-default.json new file mode 100644 index 0000000000..0441b3af80 --- /dev/null +++ b/tests/qapi-schema/struct-member-alternate-default.json @@ -0,0 +1,10 @@ +# Check defaults for unsupported types (alternates, here) +# TODO: Implement support for alternates, and then add a test where +# default=3Dnull so we can see that that is another thing that +# should be implemented +{ 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } +{ 'alternate': 'TestAlt', + 'data': { 'alt1': 'TestEnum', + 'alt2': 'null' } } +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'TestAlt', 'default': 'value1' } } } diff --git a/tests/qapi-schema/struct-member-bool-wrong-default-type.json b= /tests/qapi-schema/struct-member-bool-wrong-default-type.json new file mode 100644 index 0000000000..c9f9c45a87 --- /dev/null +++ b/tests/qapi-schema/struct-member-bool-wrong-default-type.json @@ -0,0 +1,3 @@ +# Check that booleans do not accept non-booleans +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'bool', 'default': 0 } } } diff --git a/tests/qapi-schema/struct-member-enum-invalid-default.json b/te= sts/qapi-schema/struct-member-enum-invalid-default.json new file mode 100644 index 0000000000..d5724970be --- /dev/null +++ b/tests/qapi-schema/struct-member-enum-invalid-default.json @@ -0,0 +1,4 @@ +# Check that enum values do not accept anything that is not part of the en= um +{ 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'TestEnum', 'default': 'value3' } } } diff --git a/tests/qapi-schema/struct-member-enum-wrong-default-type.json b= /tests/qapi-schema/struct-member-enum-wrong-default-type.json new file mode 100644 index 0000000000..98f18b462c --- /dev/null +++ b/tests/qapi-schema/struct-member-enum-wrong-default-type.json @@ -0,0 +1,4 @@ +# Check that enum values do not accept non-strings +{ 'enum': 'TestEnum', 'data': [ 'value1', 'value2' ] } +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'TestEnum', 'default': 0 } } } diff --git a/tests/qapi-schema/struct-member-float-invalid-default.json b/t= ests/qapi-schema/struct-member-float-invalid-default.json new file mode 100644 index 0000000000..ba351a91c8 --- /dev/null +++ b/tests/qapi-schema/struct-member-float-invalid-default.json @@ -0,0 +1,4 @@ +# This matches our number regex, but it is an invalid float still -- +# test that it is rejected +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'number', 'default': 4.42. } } } diff --git a/tests/qapi-schema/struct-member-float-wrong-default-type.json = b/tests/qapi-schema/struct-member-float-wrong-default-type.json new file mode 100644 index 0000000000..89b6863307 --- /dev/null +++ b/tests/qapi-schema/struct-member-float-wrong-default-type.json @@ -0,0 +1,3 @@ +# Check that floats do not accept non-floats +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'number', 'default': 42 } } } diff --git a/tests/qapi-schema/struct-member-int-wrong-default-type.json b/= tests/qapi-schema/struct-member-int-wrong-default-type.json new file mode 100644 index 0000000000..6c6c752176 --- /dev/null +++ b/tests/qapi-schema/struct-member-int-wrong-default-type.json @@ -0,0 +1,3 @@ +# Check that integers do not accept non-integers +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'int', 'default': 0.0 } } } diff --git a/tests/qapi-schema/struct-member-int8-erange-default.json b/tes= ts/qapi-schema/struct-member-int8-erange-default.json new file mode 100644 index 0000000000..a0093bc4b9 --- /dev/null +++ b/tests/qapi-schema/struct-member-int8-erange-default.json @@ -0,0 +1,3 @@ +# int8 does not accept out-of-range values +{ 'struct': 'Test', + 'data': { '*s8': { 'type': 'int8', 'default': -0x81 } } } diff --git a/tests/qapi-schema/struct-member-list-nonempty-default.json b/t= ests/qapi-schema/struct-member-list-nonempty-default.json new file mode 100644 index 0000000000..604692631b --- /dev/null +++ b/tests/qapi-schema/struct-member-list-nonempty-default.json @@ -0,0 +1,4 @@ +# Currently, we do not support nonempty defaults for lists +# TODO: Implement support +{ 'struct': 'Test', + 'data': { '*member': { 'type': ['int'], 'default': [42] } } } diff --git a/tests/qapi-schema/struct-member-non-optional-default.json b/te= sts/qapi-schema/struct-member-non-optional-default.json new file mode 100644 index 0000000000..354b34167d --- /dev/null +++ b/tests/qapi-schema/struct-member-non-optional-default.json @@ -0,0 +1,3 @@ +# Only optional members can have defaults +{ 'struct': 'Test', + 'data': { 'member': { 'type': 'int', 'default': 42 } } } diff --git a/tests/qapi-schema/struct-member-null-default.json b/tests/qapi= -schema/struct-member-null-default.json new file mode 100644 index 0000000000..c0cf70b984 --- /dev/null +++ b/tests/qapi-schema/struct-member-null-default.json @@ -0,0 +1,6 @@ +# Currently, you cannot give a default for null members, because +# 'None' is reserved for 'no default'. +# TODO: Fix that, though it would only really make sense for +# alternates (which currently cannot receive defaults either) +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'null', 'default': null } } } diff --git a/tests/qapi-schema/struct-member-str-wrong-default-type.json b/= tests/qapi-schema/struct-member-str-wrong-default-type.json new file mode 100644 index 0000000000..d460d3a9b4 --- /dev/null +++ b/tests/qapi-schema/struct-member-str-wrong-default-type.json @@ -0,0 +1,3 @@ +# Check that strings do not accept non-strings +{ 'struct': 'Test', + 'data': { '*member': { 'type': 'str', 'default': null } } } diff --git a/tests/qapi-schema/struct-member-uint8-erange-default.json b/te= sts/qapi-schema/struct-member-uint8-erange-default.json new file mode 100644 index 0000000000..a4fe7fd918 --- /dev/null +++ b/tests/qapi-schema/struct-member-uint8-erange-default.json @@ -0,0 +1,3 @@ +# uint8 does not accept out-of-range values +{ 'struct': 'Test', + 'data': { '*u8': { 'type': 'uint8', 'default': 0x100 } } } diff --git a/tests/qapi-schema/struct-member-uint8-negative-default.json b/= tests/qapi-schema/struct-member-uint8-negative-default.json new file mode 100644 index 0000000000..62bbf86af9 --- /dev/null +++ b/tests/qapi-schema/struct-member-uint8-negative-default.json @@ -0,0 +1,3 @@ +# uint8 does not accept negative values +{ 'struct': 'Test', + 'data': { '*u8': { 'type': 'uint8', 'default': -1 } } } diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qap= i-schema-test.out index 85d510bc00..724276f5de 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -397,3 +397,27 @@ object q_obj_test-features-arg member cfs3: CondFeatureStruct3 optional=3DFalse command test-features q_obj_test-features-arg -> None gen=3DTrue success_response=3DTrue boxed=3DFalse oob=3DFalse preconfig= =3DFalse +enum TestDefaultEnum + member value1 + member value2 + member value3 +object TestDefaultSubStruct + member member: int optional=3DFalse +array TestDefaultSubStructList TestDefaultSubStruct +object TestDefaultStruct + member bool_false: bool optional=3DTrue default=3DFalse + member bool_true: bool optional=3DTrue default=3DTrue + member integer: int optional=3DTrue default=3D-42 + member int8_low: int8 optional=3DTrue default=3D-128 + member int8_high: int8 optional=3DTrue default=3D127 + member uint8_high: uint8 optional=3DTrue default=3D255 + member size: size optional=3DTrue default=3D18446744073709551615 + member fpneg: number optional=3DTrue default=3D-375.0 + member fppos: number optional=3DTrue default=3D42.0 + member fpposinf: number optional=3DTrue default=3Dinf + member fpneginf: number optional=3DTrue default=3D-inf + member fpnan: number optional=3DTrue default=3Dnan + member str: str optional=3DTrue default=3Dfoo \=E9=B9=BF"=7F=08"' + member enum_value2: TestDefaultEnum optional=3DTrue default=3Dvalue2 + member list_scalar: intList optional=3DTrue default=3D[] + member list_struct: TestDefaultSubStructList optional=3DTrue default= =3D[] diff --git a/tests/qapi-schema/struct-member-alternate-default.err b/tests/= qapi-schema/struct-member-alternate-default.err new file mode 100644 index 0000000000..48314475f9 --- /dev/null +++ b/tests/qapi-schema/struct-member-alternate-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-alternate-default.json:9: Cannot specify v= alues for type TestAlt (not built-in or an enum) diff --git a/tests/qapi-schema/struct-member-alternate-default.exit b/tests= /qapi-schema/struct-member-alternate-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-alternate-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-alternate-default.out b/tests/= qapi-schema/struct-member-alternate-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-bool-wrong-default-type.err b/= tests/qapi-schema/struct-member-bool-wrong-default-type.err new file mode 100644 index 0000000000..a0095e5c83 --- /dev/null +++ b/tests/qapi-schema/struct-member-bool-wrong-default-type.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-bool-wrong-default-type.json:2: Value '0' = does not match type bool diff --git a/tests/qapi-schema/struct-member-bool-wrong-default-type.exit b= /tests/qapi-schema/struct-member-bool-wrong-default-type.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-bool-wrong-default-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-bool-wrong-default-type.out b/= tests/qapi-schema/struct-member-bool-wrong-default-type.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-enum-invalid-default.err b/tes= ts/qapi-schema/struct-member-enum-invalid-default.err new file mode 100644 index 0000000000..6aa3684a28 --- /dev/null +++ b/tests/qapi-schema/struct-member-enum-invalid-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-enum-invalid-default.json:3: Value 'value3= ' does not occur in enum TestEnum diff --git a/tests/qapi-schema/struct-member-enum-invalid-default.exit b/te= sts/qapi-schema/struct-member-enum-invalid-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-enum-invalid-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-enum-invalid-default.out b/tes= ts/qapi-schema/struct-member-enum-invalid-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-enum-wrong-default-type.err b/= tests/qapi-schema/struct-member-enum-wrong-default-type.err new file mode 100644 index 0000000000..846dad0316 --- /dev/null +++ b/tests/qapi-schema/struct-member-enum-wrong-default-type.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-enum-wrong-default-type.json:3: Enum value= s must be strings, but '0' is no string diff --git a/tests/qapi-schema/struct-member-enum-wrong-default-type.exit b= /tests/qapi-schema/struct-member-enum-wrong-default-type.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-enum-wrong-default-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-enum-wrong-default-type.out b/= tests/qapi-schema/struct-member-enum-wrong-default-type.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-float-invalid-default.err b/te= sts/qapi-schema/struct-member-float-invalid-default.err new file mode 100644 index 0000000000..1ae241641f --- /dev/null +++ b/tests/qapi-schema/struct-member-float-invalid-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-float-invalid-default.json:4:55: "4.42." i= s not a valid integer or float diff --git a/tests/qapi-schema/struct-member-float-invalid-default.exit b/t= ests/qapi-schema/struct-member-float-invalid-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-float-invalid-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-float-invalid-default.out b/te= sts/qapi-schema/struct-member-float-invalid-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-float-wrong-default-type.err b= /tests/qapi-schema/struct-member-float-wrong-default-type.err new file mode 100644 index 0000000000..8f8bf68d23 --- /dev/null +++ b/tests/qapi-schema/struct-member-float-wrong-default-type.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-float-wrong-default-type.json:2: Value '42= ' does not match type number diff --git a/tests/qapi-schema/struct-member-float-wrong-default-type.exit = b/tests/qapi-schema/struct-member-float-wrong-default-type.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-float-wrong-default-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-float-wrong-default-type.out b= /tests/qapi-schema/struct-member-float-wrong-default-type.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-int-wrong-default-type.err b/t= ests/qapi-schema/struct-member-int-wrong-default-type.err new file mode 100644 index 0000000000..a6b93e8403 --- /dev/null +++ b/tests/qapi-schema/struct-member-int-wrong-default-type.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-int-wrong-default-type.json:2: Value '0.0'= does not match type int diff --git a/tests/qapi-schema/struct-member-int-wrong-default-type.exit b/= tests/qapi-schema/struct-member-int-wrong-default-type.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-int-wrong-default-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-int-wrong-default-type.out b/t= ests/qapi-schema/struct-member-int-wrong-default-type.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-int8-erange-default.err b/test= s/qapi-schema/struct-member-int8-erange-default.err new file mode 100644 index 0000000000..e58bf7279c --- /dev/null +++ b/tests/qapi-schema/struct-member-int8-erange-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-int8-erange-default.json:2: Value '-129' d= oes not match type int8 diff --git a/tests/qapi-schema/struct-member-int8-erange-default.exit b/tes= ts/qapi-schema/struct-member-int8-erange-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-int8-erange-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-int8-erange-default.out b/test= s/qapi-schema/struct-member-int8-erange-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-list-nonempty-default.err b/te= sts/qapi-schema/struct-member-list-nonempty-default.err new file mode 100644 index 0000000000..48b6fd61a6 --- /dev/null +++ b/tests/qapi-schema/struct-member-list-nonempty-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-list-nonempty-default.json:3: Support for = non-empty lists as default values has not been implemented yet: '[42]' diff --git a/tests/qapi-schema/struct-member-list-nonempty-default.exit b/t= ests/qapi-schema/struct-member-list-nonempty-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-list-nonempty-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-list-nonempty-default.out b/te= sts/qapi-schema/struct-member-list-nonempty-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-non-optional-default.err b/tes= ts/qapi-schema/struct-member-non-optional-default.err new file mode 100644 index 0000000000..ba79cb43fa --- /dev/null +++ b/tests/qapi-schema/struct-member-non-optional-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-non-optional-default.json:2: 'member' is n= ot optional, so it cannot have a default value diff --git a/tests/qapi-schema/struct-member-non-optional-default.exit b/te= sts/qapi-schema/struct-member-non-optional-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-non-optional-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-non-optional-default.out b/tes= ts/qapi-schema/struct-member-non-optional-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-null-default.err b/tests/qapi-= schema/struct-member-null-default.err new file mode 100644 index 0000000000..6a37655f3d --- /dev/null +++ b/tests/qapi-schema/struct-member-null-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-null-default.json:5: Cannot specify values= for type null diff --git a/tests/qapi-schema/struct-member-null-default.exit b/tests/qapi= -schema/struct-member-null-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-null-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-null-default.out b/tests/qapi-= schema/struct-member-null-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-str-wrong-default-type.err b/t= ests/qapi-schema/struct-member-str-wrong-default-type.err new file mode 100644 index 0000000000..597165e22a --- /dev/null +++ b/tests/qapi-schema/struct-member-str-wrong-default-type.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-str-wrong-default-type.json:2: Value 'None= ' does not match type str diff --git a/tests/qapi-schema/struct-member-str-wrong-default-type.exit b/= tests/qapi-schema/struct-member-str-wrong-default-type.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-str-wrong-default-type.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-str-wrong-default-type.out b/t= ests/qapi-schema/struct-member-str-wrong-default-type.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-uint8-erange-default.err b/tes= ts/qapi-schema/struct-member-uint8-erange-default.err new file mode 100644 index 0000000000..a870c7074e --- /dev/null +++ b/tests/qapi-schema/struct-member-uint8-erange-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-uint8-erange-default.json:2: Value '256' d= oes not match type uint8 diff --git a/tests/qapi-schema/struct-member-uint8-erange-default.exit b/te= sts/qapi-schema/struct-member-uint8-erange-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-uint8-erange-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-uint8-erange-default.out b/tes= ts/qapi-schema/struct-member-uint8-erange-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/struct-member-uint8-negative-default.err b/t= ests/qapi-schema/struct-member-uint8-negative-default.err new file mode 100644 index 0000000000..e17ef38e15 --- /dev/null +++ b/tests/qapi-schema/struct-member-uint8-negative-default.err @@ -0,0 +1 @@ +tests/qapi-schema/struct-member-uint8-negative-default.json:2: Value '-1' = does not match type uint8 diff --git a/tests/qapi-schema/struct-member-uint8-negative-default.exit b/= tests/qapi-schema/struct-member-uint8-negative-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/struct-member-uint8-negative-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/struct-member-uint8-negative-default.out b/t= ests/qapi-schema/struct-member-uint8-negative-default.out new file mode 100644 index 0000000000..e69de29bb2 --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561399107; cv=none; d=zoho.com; s=zohoarc; b=UK9ReHaGB/Q/NtaCA3Ss9YEVXAWdrUH0HBceQSvIpIKZEmrPWdgHvCExCYz0H1dvRH7pbNRD3v9olcIBcvpqo8IQXbcRE278Oze43FuMzoR0iNFQTGfJKL43DblSReFj9yinPOp3ZR/LfjEYAKTw31Mz7gUyH0P+tPjkczlGURk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561399107; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=b/tNwSSGE32vs7jSJcuAiBU82hJQNPIkrkULLNwMsSw=; b=XXc0W35KbYyTvkT9Bzx0O4eJWjNYZMZBldW7TX07PvrWhW6XVAyhDkRyv5ayHfm461sEIckyL6S4saP5MXQ61czT0L7efQiq+SeiACpYGBvAl6yns+V/QOIi9Fj2/YeSNsKAmzG4LEN3Qwevj2oiGB4woMfEGIqLx1SC3HDY/Cs= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561399107673817.6699474052107; Mon, 24 Jun 2019 10:58:27 -0700 (PDT) Received: from localhost ([::1]:53572 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTEY-00083p-Bv for importer@patchew.org; Mon, 24 Jun 2019 13:58:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49079) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSww-0001YC-Us for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwv-0005MX-3U for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33182) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwn-0004vB-MX; Mon, 24 Jun 2019 13:40:06 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B7CCE3162912; Mon, 24 Jun 2019 17:39:57 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1DF9F600C0; Mon, 24 Jun 2019 17:39:56 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:28 +0200 Message-Id: <20190624173935.25747-9-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Mon, 24 Jun 2019 17:39:57 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 08/14] tests: Add QAPI optional discriminator tests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" There already is an optional discriminator test, although it also noted the discriminator name itself as optional. This already gives us one error test case, to which this patch adds one other, namely whether that using an optional discriminator requires the respective field to have a default value. Furthermore, a passing test case is added to qapi-schema-test. Signed-off-by: Max Reitz --- tests/Makefile.include | 3 ++- ...-optional-discriminator-invalid-specification.json | 11 +++++++++++ ...flat-union-optional-discriminator-no-default.json} | 5 +++-- tests/qapi-schema/qapi-schema-test.json | 10 ++++++++++ ...n-optional-discriminator-invalid-specification.err | 1 + ...optional-discriminator-invalid-specification.exit} | 0 ...-optional-discriminator-invalid-specification.out} | 0 .../flat-union-optional-discriminator-no-default.err | 1 + .../flat-union-optional-discriminator-no-default.exit | 1 + .../flat-union-optional-discriminator-no-default.out | 0 .../qapi-schema/flat-union-optional-discriminator.err | 1 - tests/qapi-schema/qapi-schema-test.out | 9 +++++++++ 12 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 tests/qapi-schema/flat-union-optional-discriminator-inv= alid-specification.json rename tests/qapi-schema/{flat-union-optional-discriminator.json =3D> flat= -union-optional-discriminator-no-default.json} (68%) create mode 100644 tests/qapi-schema/flat-union-optional-discriminator-inv= alid-specification.err rename tests/qapi-schema/{flat-union-optional-discriminator.exit =3D> flat= -union-optional-discriminator-invalid-specification.exit} (100%) rename tests/qapi-schema/{flat-union-optional-discriminator.out =3D> flat-= union-optional-discriminator-invalid-specification.out} (100%) create mode 100644 tests/qapi-schema/flat-union-optional-discriminator-no-= default.err create mode 100644 tests/qapi-schema/flat-union-optional-discriminator-no-= default.exit create mode 100644 tests/qapi-schema/flat-union-optional-discriminator-no-= default.out delete mode 100644 tests/qapi-schema/flat-union-optional-discriminator.err diff --git a/tests/Makefile.include b/tests/Makefile.include index 76dc581096..3202ddab10 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -398,7 +398,8 @@ qapi-schema +=3D flat-union-invalid-branch-key.json qapi-schema +=3D flat-union-invalid-discriminator.json qapi-schema +=3D flat-union-invalid-if-discriminator.json qapi-schema +=3D flat-union-no-base.json -qapi-schema +=3D flat-union-optional-discriminator.json +qapi-schema +=3D flat-union-optional-discriminator-invalid-specification.j= son +qapi-schema +=3D flat-union-optional-discriminator-no-default.json qapi-schema +=3D flat-union-string-discriminator.json qapi-schema +=3D funny-char.json qapi-schema +=3D ident-with-escape.json diff --git a/tests/qapi-schema/flat-union-optional-discriminator-invalid-sp= ecification.json b/tests/qapi-schema/flat-union-optional-discriminator-inva= lid-specification.json new file mode 100644 index 0000000000..d20a2cd295 --- /dev/null +++ b/tests/qapi-schema/flat-union-optional-discriminator-invalid-specifica= tion.json @@ -0,0 +1,11 @@ +# For using optional discriminators, only the field in the base struct +# must be marked optional, not the discriminator name itself +{ 'enum': 'Enum', 'data': [ 'one', 'two' ] } +{ 'struct': 'Base', + 'data': { '*switch': { 'type': 'Enum', 'default': 'one' } } } +{ 'struct': 'Branch', 'data': { 'name': 'str' } } +{ 'union': 'MyUnion', + 'base': 'Base', + 'discriminator': '*switch', + 'data': { 'one': 'Branch', + 'two': 'Branch' } } diff --git a/tests/qapi-schema/flat-union-optional-discriminator.json b/tes= ts/qapi-schema/flat-union-optional-discriminator-no-default.json similarity index 68% rename from tests/qapi-schema/flat-union-optional-discriminator.json rename to tests/qapi-schema/flat-union-optional-discriminator-no-default.js= on index 08a8f7ef8b..31ebb85afb 100644 --- a/tests/qapi-schema/flat-union-optional-discriminator.json +++ b/tests/qapi-schema/flat-union-optional-discriminator-no-default.json @@ -1,10 +1,11 @@ -# we require the discriminator to be non-optional +# Using an optional discriminator requires the respective field to +# have a default { 'enum': 'Enum', 'data': [ 'one', 'two' ] } { 'struct': 'Base', 'data': { '*switch': 'Enum' } } { 'struct': 'Branch', 'data': { 'name': 'str' } } { 'union': 'MyUnion', 'base': 'Base', - 'discriminator': '*switch', + 'discriminator': 'switch', 'data': { 'one': 'Branch', 'two': 'Branch' } } diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qa= pi-schema-test.json index 12ae387d46..0f4b123a82 100644 --- a/tests/qapi-schema/qapi-schema-test.json +++ b/tests/qapi-schema/qapi-schema-test.json @@ -104,6 +104,16 @@ { 'struct': 'UserDefC', 'data': { 'string1': 'str', 'string2': 'str' } } =20 +# for testing unions with an optional discriminator +{ 'union': 'UserDefFlatUnion3', + 'base': { '*enum1': { 'type': 'EnumOne', 'default': 'value1' } }, + 'discriminator': 'enum1', + 'data': { 'value1' : 'UserDefA', + 'value2' : 'UserDefB', + 'value3' : 'UserDefB' + # 'value4' defaults to empty + } } + # for testing use of 'number' within alternates { 'alternate': 'AltEnumBool', 'data': { 'e': 'EnumOne', 'b': 'bool' } } { 'alternate': 'AltEnumNum', 'data': { 'e': 'EnumOne', 'n': 'number' } } diff --git a/tests/qapi-schema/flat-union-optional-discriminator-invalid-sp= ecification.err b/tests/qapi-schema/flat-union-optional-discriminator-inval= id-specification.err new file mode 100644 index 0000000000..cbf154e726 --- /dev/null +++ b/tests/qapi-schema/flat-union-optional-discriminator-invalid-specifica= tion.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-optional-discriminator-invalid-specification.= json:7: Discriminator of flat union 'MyUnion' does not allow optional name = '*switch' diff --git a/tests/qapi-schema/flat-union-optional-discriminator.exit b/tes= ts/qapi-schema/flat-union-optional-discriminator-invalid-specification.exit similarity index 100% rename from tests/qapi-schema/flat-union-optional-discriminator.exit rename to tests/qapi-schema/flat-union-optional-discriminator-invalid-speci= fication.exit diff --git a/tests/qapi-schema/flat-union-optional-discriminator.out b/test= s/qapi-schema/flat-union-optional-discriminator-invalid-specification.out similarity index 100% rename from tests/qapi-schema/flat-union-optional-discriminator.out rename to tests/qapi-schema/flat-union-optional-discriminator-invalid-speci= fication.out diff --git a/tests/qapi-schema/flat-union-optional-discriminator-no-default= .err b/tests/qapi-schema/flat-union-optional-discriminator-no-default.err new file mode 100644 index 0000000000..5a022a0bc7 --- /dev/null +++ b/tests/qapi-schema/flat-union-optional-discriminator-no-default.err @@ -0,0 +1 @@ +tests/qapi-schema/flat-union-optional-discriminator-no-default.json:7: Opt= ional discriminator 'switch' has no default value diff --git a/tests/qapi-schema/flat-union-optional-discriminator-no-default= .exit b/tests/qapi-schema/flat-union-optional-discriminator-no-default.exit new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/tests/qapi-schema/flat-union-optional-discriminator-no-default.exit @@ -0,0 +1 @@ +1 diff --git a/tests/qapi-schema/flat-union-optional-discriminator-no-default= .out b/tests/qapi-schema/flat-union-optional-discriminator-no-default.out new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qapi-schema/flat-union-optional-discriminator.err b/test= s/qapi-schema/flat-union-optional-discriminator.err deleted file mode 100644 index aaabedb3bd..0000000000 --- a/tests/qapi-schema/flat-union-optional-discriminator.err +++ /dev/null @@ -1 +0,0 @@ -tests/qapi-schema/flat-union-optional-discriminator.json:6: Discriminator = of flat union 'MyUnion' does not allow optional name '*switch' diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qap= i-schema-test.out index 724276f5de..3729736747 100644 --- a/tests/qapi-schema/qapi-schema-test.out +++ b/tests/qapi-schema/qapi-schema-test.out @@ -96,6 +96,15 @@ alternate UserDefAlternate object UserDefC member string1: str optional=3DFalse member string2: str optional=3DFalse +object q_obj_UserDefFlatUnion3-base + member enum1: EnumOne optional=3DTrue default=3Dvalue1 +object UserDefFlatUnion3 + base q_obj_UserDefFlatUnion3-base + tag enum1 + case value1: UserDefA + case value2: UserDefB + case value3: UserDefB + case value4: q_empty alternate AltEnumBool tag type case e: EnumOne --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398914; cv=none; d=zoho.com; s=zohoarc; b=MGeTmMIzGXON+jZHYvZbRczSVN2SWux43uvaYQ1rii2+Jr5xvAgewUBwcblbTxPvqHACZ0HwutkC1y24E3ksfWEkzaPGvCve3JKdJ0UMR6uRnsO/4Z4w2s8pHZyMr5VidqsatIfk56SGkXVBZRzsQl1OUr19t7km8gs547bOgFE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398914; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=/HiKI1lZy7oOvbDTD1wi3yTriIHB8j1ejNfMdlCEm6Q=; b=MlgYzXi7ZnXXexmbkXqEscAVJYGoAf+6mWnyLy8XYAKmT2utRrURR0CuZS8e8Xn6XWe/3+gXpJZC8dIiWK5EiLk/RPOhA7LWEivwV6/HGqA+IGHqyIcQI3B9Blzj8rZcUTveWC7XYIt3odbUwlus8auntNyQWEwC48doXDaz9vQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 156139891459172.11687918108112; Mon, 24 Jun 2019 10:55:14 -0700 (PDT) Received: from localhost ([::1]:53534 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTBQ-0003mT-TN for importer@patchew.org; Mon, 24 Jun 2019 13:55:12 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49049) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwv-0001UE-CQ for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwt-0005Jh-UJ for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:62827) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwp-0004zz-QS; Mon, 24 Jun 2019 13:40:08 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 160BC81F1B; Mon, 24 Jun 2019 17:40:00 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A4D6B5C22F; Mon, 24 Jun 2019 17:39:59 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:29 +0200 Message-Id: <20190624173935.25747-10-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 24 Jun 2019 17:40:00 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 09/14] qapi: Formalize qcow2 encryption probing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Currently, you can give no encryption format for a qcow2 file while still passing a key-secret. That does not conform to the schema, so this patch changes the schema to allow it. Signed-off-by: Max Reitz --- qapi/block-core.json | 32 +++++++++++++++++++++++++++++--- block/qcow2.c | 3 +++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 0d43d4f37c..9df3fc8bd7 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -47,6 +47,9 @@ ## # @ImageInfoSpecificQCow2Encryption: # +# @format will never be "auto", as this pseudo-format just tells the +# qcow2 driver to read the actual format from the image header. +# # Since: 2.10 ## { 'union': 'ImageInfoSpecificQCow2Encryption', @@ -3081,10 +3084,30 @@ # @BlockdevQcow2EncryptionFormat: # @aes: AES-CBC with plain64 initialization vectors # +# @auto: Determine the encryption format from the image +# header. This only allows the use of the +# key-secret option. (Since: 4.1) +# # Since: 2.10 ## { 'enum': 'BlockdevQcow2EncryptionFormat', - 'data': [ 'aes', 'luks' ] } + 'data': [ 'aes', 'luks', 'auto' ] } + +## +# @BlockdevQcow2EncryptionSecret: +# +# Allows specifying a key-secret without specifying the exact +# encryption format, which is determined automatically from the image +# header. +# +# @key-secret: The ID of a QCryptoSecret object providing the +# decryption key. Mandatory except when probing +# image for metadata only. +# +# Since: 4.1 +## +{ 'struct': 'BlockdevQcow2EncryptionSecret', + 'data': { '*key-secret': 'str' } } =20 ## # @BlockdevQcow2Encryption: @@ -3092,10 +3115,13 @@ # Since: 2.10 ## { 'union': 'BlockdevQcow2Encryption', - 'base': { 'format': 'BlockdevQcow2EncryptionFormat' }, + 'base': { + '*format': { 'type': 'BlockdevQcow2EncryptionFormat', 'default': 'au= to' } + }, 'discriminator': 'format', 'data': { 'aes': 'QCryptoBlockOptionsQCow', - 'luks': 'QCryptoBlockOptionsLUKS'} } + 'luks': 'QCryptoBlockOptionsLUKS', + 'auto': 'BlockdevQcow2EncryptionSecret' } } =20 ## # @BlockdevOptionsQcow2: diff --git a/block/qcow2.c b/block/qcow2.c index 9396d490d5..95de19d906 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -930,6 +930,9 @@ static int qcow2_update_options_prepare(BlockDriverStat= e *bs, =20 qdict_extract_subqdict(options, &encryptopts, "encrypt."); encryptfmt =3D qdict_get_try_str(encryptopts, "format"); + if (!g_strcmp0(encryptfmt, "auto")) { + encryptfmt =3D NULL; + } =20 opts =3D qemu_opts_create(&qcow2_runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398207; cv=none; d=zoho.com; s=zohoarc; b=AEXMmKwdBUaj3H5sxlPLGEEPoxHBBSaZRnPU1o7eJRWRutD5wG/IHJ0eRCcHV/FftFMOGoiRyU0Sd6tsXrN+hZbPlXFgAbZ7TuMdyCk2ZM5vGQdBUtNKwkjsMBT3SsdA54KTU9DN1zMP2ANdsFnkcQIpIBi4b3q3wxzAYcA54PU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398207; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=gVwjvPukrNReC8HVWx0G6pb2kW3CYrUbLopPG3SZCLQ=; b=bx/kxwA396bryF/4poI3big8qHeE3feBxXFFmCYsm0KAfBmJ4ICVpdAO1zQ7qI51iWyOaheAkH4KhucJKpvv2xr7KEYR3FZiXTC08HcBpcGXlSwFPMbryeX9do/rH2IcsJRmeHIbxm+GbclRpSoMvN0d0zEo4MphQRgDJZ5dA7Y= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 156139820715616.164489502354627; Mon, 24 Jun 2019 10:43:27 -0700 (PDT) Received: from localhost ([::1]:53466 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSzx-00040t-3w for importer@patchew.org; Mon, 24 Jun 2019 13:43:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48986) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSwt-0001NT-1t for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:12 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwr-0005BH-4g for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:10 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33192) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwn-0004yO-JM; Mon, 24 Jun 2019 13:40:05 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A9D5D3079B60; Mon, 24 Jun 2019 17:40:03 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 083A55D9C5; Mon, 24 Jun 2019 17:40:01 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:30 +0200 Message-Id: <20190624173935.25747-11-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Mon, 24 Jun 2019 17:40:03 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 10/14] qapi: Formalize qcow encryption probing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" qcow only supports a single encryption (and there is no reason why that would change in the future), so we can make it the default. Signed-off-by: Max Reitz --- qapi/block-core.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 9df3fc8bd7..b30a19bf8e 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3059,7 +3059,9 @@ # Since: 2.10 ## { 'union': 'BlockdevQcowEncryption', - 'base': { 'format': 'BlockdevQcowEncryptionFormat' }, + 'base': { + '*format': { 'type': 'BlockdevQcowEncryptionFormat', 'default': 'aes= ' } + }, 'discriminator': 'format', 'data': { 'aes': 'QCryptoBlockOptionsQCow' } } =20 --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398688; cv=none; d=zoho.com; s=zohoarc; b=mXMsnb7CKzZTLOC1EP2LAA0KDFB0c8JpFJ5ndBKhV2aR3RjCrVv8AonKaaz6JJg6XrxVqzEEYbHpdim2t4IAE9B2aYvhrJr4nD+Cm7EkoAfaDhfCg8UDm1LNDilioLdii23pFr2//FXBNX7Uy7Ywh0OEFnNpSVxqTMdka5t2GCs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398688; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=3hKjGENQclsdQfakq4lHEdq1efj2mCQXbL7mbHxphSE=; b=HejE9UltasbrdhWQptBlcnvSUC4gNr3RXTFZw/zXLt7b/N9feqtKjq/XxmgWqAv9ejxthkP0UDgLO4wOIrL7tb8t30Ppm6dIGwu2P/cNcddZX7N+SOOXiwcFwoB9dwYGvD/uZSMtwe/ByzdZWLaqC37o5pt3k23SiP0ZB2rWYO4= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561398688351168.99718577659633; Mon, 24 Jun 2019 10:51:28 -0700 (PDT) Received: from localhost ([::1]:53506 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfT7n-0000WM-CM for importer@patchew.org; Mon, 24 Jun 2019 13:51:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49158) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSx2-0001g7-R1 for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSx0-0005Vy-0F for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43256) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwv-0005K1-0b; Mon, 24 Jun 2019 13:40:13 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C99835D61E; Mon, 24 Jun 2019 17:40:06 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8D1E15D9C5; Mon, 24 Jun 2019 17:40:05 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:31 +0200 Message-Id: <20190624173935.25747-12-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 24 Jun 2019 17:40:06 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 11/14] block: Try to create well typed json:{} filenames X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" By applying qdict_flatten(), the flat-confused input visitor, and the output visitor, we can at least try to bring bs->full_open_options into accordance with the QAPI schema. This may not always work (there are some options left that have not been QAPI-fied yet), but in practice it usually will. In any case, sometimes emitting wrongly typed json:{} filenames is better than doing it effectively half the time. This affects some iotests because json:{} filenames are now usually crumpled. In 198, "format": "auto" now appears in the qcow2 encryption options because going through a visitor makes optional members' default values explicit. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=3D1534396 Signed-off-by: Max Reitz --- block.c | 68 +++++++++++++++++++++++++++++++++++++- tests/qemu-iotests/059.out | 2 +- tests/qemu-iotests/099.out | 4 +-- tests/qemu-iotests/110.out | 2 +- tests/qemu-iotests/198.out | 4 +-- 5 files changed, 73 insertions(+), 7 deletions(-) diff --git a/block.c b/block.c index c139540f2b..d3c1041087 100644 --- a/block.c +++ b/block.c @@ -36,6 +36,7 @@ #include "qapi/qmp/qjson.h" #include "qapi/qmp/qnull.h" #include "qapi/qmp/qstring.h" +#include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" #include "qapi/qapi-visit-block-core.h" #include "sysemu/block-backend.h" @@ -6283,6 +6284,56 @@ static bool bdrv_backing_overridden(BlockDriverState= *bs) } } =20 +/** + * Take a blockdev @options QDict and convert its values to the + * correct type. + * + * Fail if @options does not match the QAPI schema of BlockdevOptions. + * + * In case of failure, return NULL and set @errp. + * + * In case of success, return a correctly typed new QDict. + */ +static QDict *bdrv_type_blockdev_opts(const QDict *options, Error **errp) +{ + Visitor *v; + BlockdevOptions *blockdev_options; + QObject *typed_opts; + QDict *string_options; + Error *local_err =3D NULL; + + string_options =3D qdict_clone_shallow(options); + + qdict_flatten(string_options); + v =3D qobject_input_visitor_new_flat_confused(string_options, errp); + if (!v) { + error_prepend(errp, "Failed to prepare options: "); + return NULL; + } + + visit_type_BlockdevOptions(v, NULL, &blockdev_options, &local_err); + visit_free(v); + if (local_err) { + error_propagate(errp, local_err); + error_prepend(errp, "Not a valid BlockdevOptions object: "); + return NULL; + } + + v =3D qobject_output_visitor_new(&typed_opts); + visit_type_BlockdevOptions(v, NULL, &blockdev_options, &local_err); + if (!local_err) { + visit_complete(v, &typed_opts); + } + visit_free(v); + qapi_free_BlockdevOptions(blockdev_options); + if (local_err) { + error_propagate(errp, local_err); + return NULL; + } + + return qobject_to(QDict, typed_opts); +} + /* Updates the following BDS fields: * - exact_filename: A filename which may be used for opening a block dev= ice * which (mostly) equals the given BDS (even without any @@ -6400,10 +6451,25 @@ void bdrv_refresh_filename(BlockDriverState *bs) if (bs->exact_filename[0]) { pstrcpy(bs->filename, sizeof(bs->filename), bs->exact_filename); } else { - QString *json =3D qobject_to_json(QOBJECT(bs->full_open_options)); + QString *json; + QDict *typed_opts, *json_opts; + + typed_opts =3D bdrv_type_blockdev_opts(bs->full_open_options, NULL= ); + + /* + * We cannot be certain that bs->full_open_options matches + * BlockdevOptions, so bdrv_type_blockdev_opts() may fail. + * That is not fatal, we can just emit bs->full_open_options + * directly -- qemu will accept that, even if it does not + * match the schema. + */ + json_opts =3D typed_opts ?: bs->full_open_options; + + json =3D qobject_to_json(QOBJECT(json_opts)); snprintf(bs->filename, sizeof(bs->filename), "json:%s", qstring_get_str(json)); qobject_unref(json); + qobject_unref(typed_opts); } } =20 diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out index 4fab42a28c..53109b2d49 100644 --- a/tests/qemu-iotests/059.out +++ b/tests/qemu-iotests/059.out @@ -2050,7 +2050,7 @@ wrote 512/512 bytes at offset 10240 =20 =3D=3D=3D Testing monolithicFlat with internally generated JSON file name = =3D=3D=3D Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 subformat=3Dm= onolithicFlat -qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor= file 'json:{"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, = "driver": "blkdebug", "inject-error.0.event": "read_aio"}' +qemu-io: can't open: Cannot use relative extent paths with VMDK descriptor= file 'json:{"inject-error": [{"event": "read_aio"}], "image": {"driver": "= file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug"}' =20 =3D=3D=3D Testing version 3 =3D=3D=3D image: TEST_DIR/iotest-version3.IMGFMT diff --git a/tests/qemu-iotests/099.out b/tests/qemu-iotests/099.out index 8cce627529..0a9c434148 100644 --- a/tests/qemu-iotests/099.out +++ b/tests/qemu-iotests/099.out @@ -12,11 +12,11 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT =20 =3D=3D=3D Testing JSON filename for blkdebug =3D=3D=3D =20 -json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename":= "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_up= date"}} +json:{"driver": "IMGFMT", "file": {"inject-error": [{"event": "l1_update"}= ], "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": = "blkdebug"}} =20 =3D=3D=3D Testing indirectly enforced JSON filename =3D=3D=3D =20 -json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"ima= ge": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdeb= ug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {= "driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}} +json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"inj= ect-error": [{"event": "l1_update"}], "image": {"driver": "file", "filename= ": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug"}}, "driver": "blkverify", "ra= w": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}} =20 =3D=3D=3D Testing plain filename for blkdebug =3D=3D=3D =20 diff --git a/tests/qemu-iotests/110.out b/tests/qemu-iotests/110.out index f60b26390e..d95b92bee7 100644 --- a/tests/qemu-iotests/110.out +++ b/tests/qemu-iotests/110.out @@ -11,7 +11,7 @@ backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGF= MT.base) =20 =3D=3D=3D Non-reconstructable filename =3D=3D=3D =20 -image: json:{"driver": "IMGFMT", "file": {"set-state.0.event": "read_aio",= "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "b= lkdebug", "set-state.0.new_state": 42}} +image: json:{"driver": "IMGFMT", "file": {"set-state": [{"new_state": 42, = "event": "read_aio"}], "image": {"driver": "file", "filename": "TEST_DIR/t.= IMGFMT"}, "driver": "blkdebug"}} file format: IMGFMT virtual size: 64 MiB (67108864 bytes) backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base) diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out index e86b175e39..eef8af3cdc 100644 --- a/tests/qemu-iotests/198.out +++ b/tests/qemu-iotests/198.out @@ -32,7 +32,7 @@ read 16777216/16777216 bytes at offset 0 16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) =20 =3D=3D checking image base =3D=3D -image: json:{"encrypt.key-secret": "sec0", "driver": "IMGFMT", "file": {"d= river": "file", "filename": "TEST_DIR/t.IMGFMT.base"}} +image: json:{"driver": "IMGFMT", "encrypt": {"format": "auto", "key-secret= ": "sec0"}, "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.base"= }} file format: IMGFMT virtual size: 16 MiB (16777216 bytes) Format specific information: @@ -74,7 +74,7 @@ Format specific information: master key iters: 1024 =20 =3D=3D checking image layer =3D=3D -image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"d= river": "file", "filename": "TEST_DIR/t.IMGFMT"}} +image: json:{"driver": "IMGFMT", "encrypt": {"format": "auto", "key-secret= ": "sec1"}, "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}} file format: IMGFMT virtual size: 16 MiB (16777216 bytes) backing file: TEST_DIR/t.IMGFMT.base --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561399360; cv=none; d=zoho.com; s=zohoarc; b=JFHpz6pu0Yl9aUZCzzBWOGzJgL/9Za8g0vHJzEBTMB2YQ2ruOajau51Yg/WgFxGS0GIOcUHD2SwOHlNAs46ZIr6mH2dmCJQYt5keDDkaitEv/VriebqW2AVEn3kfJ4eHVOpTkVCnyM8KdoRPMrMVTA5tzDn/RABThcUoW/wAZBM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561399360; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=SgtwnesFl1wAlFsmICcdubwlZua5eEB8zxbBY3aQhQI=; b=cbk2r7l0/QaMd4eFcd+o1HQZNuUVQQeW7HeE4aN4uURmU+dITTQiVl7z61PczgccJWonN6TkayrGK+++wcdOMe71hUKdJtkIDQsgZ33X760iEh9h4IpundA15t0h/kD/MnUfFJjDfyR5dQY0e9RAYDsxvOKERiYFgW1TuwGl+bw= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1561399360205624.1668025993451; Mon, 24 Jun 2019 11:02:40 -0700 (PDT) Received: from localhost ([::1]:53618 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTIc-0003Rz-A0 for importer@patchew.org; Mon, 24 Jun 2019 14:02:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49226) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSxD-0001lF-8n for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSxA-0005k1-Qm for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39786) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwy-0005SF-R8; Mon, 24 Jun 2019 13:40:17 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AC8D5C057E9F; Mon, 24 Jun 2019 17:40:10 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BD6165D9D3; Mon, 24 Jun 2019 17:40:08 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:32 +0200 Message-Id: <20190624173935.25747-13-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 24 Jun 2019 17:40:10 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 12/14] iotests: Test internal option typing X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" It would be nice if qemu used the correct types for blockdev options internally, even if the user specified string values (either through -drive or by being not so nice and using json:{} with string values). This patch adds a test verifying that fact. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- tests/qemu-iotests/089 | 25 +++++++++++++++++++++++++ tests/qemu-iotests/089.out | 9 +++++++++ 2 files changed, 34 insertions(+) diff --git a/tests/qemu-iotests/089 b/tests/qemu-iotests/089 index ad029f1f09..156a8af85c 100755 --- a/tests/qemu-iotests/089 +++ b/tests/qemu-iotests/089 @@ -35,6 +35,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 # get standard environment, filters and checks . ./common.rc . ./common.filter +. ./common.qemu =20 _supported_fmt qcow2 _supported_proto file @@ -143,6 +144,30 @@ $QEMU_IO -c "open -o driver=3Dqcow2 json:{\"file.filen= ame\":\"$TEST_IMG\"}" \ $QEMU_IO -c "open -o driver=3Dqcow2 json:{\"driver\":\"raw\",\"file.filena= me\":\"$TEST_IMG\"}" \ -c "info" 2>&1 | _filter_img_info =20 +echo +echo "=3D=3D=3D Testing option typing =3D=3D=3D" +echo + +# json:{} accepts both strings and correctly typed values (even mixed, +# although we probably do not want to support that...), but when +# creating a json:{} filename, it should be correctly typed. +# Therefore, both of these should make the "size" value an integer. + +TEST_IMG=3D"json:{'driver': 'null-co', 'size': 42 }" _img_info | grep '^i= mage' +TEST_IMG=3D"json:{'driver': 'null-co', 'size': '42'}" _img_info | grep '^i= mage' + +echo + +# This should even work when some driver abuses bs->options to store +# non-QAPI options (and the given -drive options are not complete) +# (Watch for whether file.align appears as an int or a string) +qemu_comm_method=3Dmonitor _launch_qemu \ + -drive if=3Dnone,id=3Ddrv0,node-name=3Dnode0,format=3Draw,file=3Dblkde= bug::null-co://,file.align=3D512 + +_send_qemu_cmd $QEMU_HANDLE 'info block' 'json:' + +_cleanup_qemu + =20 # success, all done echo "*** done" diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out index 20c8ce8f0e..a43dfd3cf8 100644 --- a/tests/qemu-iotests/089.out +++ b/tests/qemu-iotests/089.out @@ -49,4 +49,13 @@ vm state offset: 512 MiB format name: IMGFMT cluster size: 64 KiB vm state offset: 512 MiB + +=3D=3D=3D Testing option typing =3D=3D=3D + +image: json:{"driver": "null-co", "size": 42} +image: json:{"driver": "null-co", "size": 42} + +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) info block +drv0 (node0): json:{"driver": "raw", "file": {"image": {"driver": "null-co= "}, "driver": "blkdebug", "align": 512}} (raw) *** done --=20 2.21.0 From nobody Mon May 13 23:12:21 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1561398919; cv=none; d=zoho.com; s=zohoarc; b=ksbgfeZN23gDK0RWJSVGMPCU9fa1JwJtTQBhUv7DKWskE077B+8v4KXV5/5q8d8eKGHTsRM53dUKpIvxATWkgoPVUdNRHrZUPhHeWcF/PSdetSW20beEnSJ6wHS98aCoq43uMtbpVFAvKjO1kQ6MwB1bOn/dSSPtWYsc3v2O9o8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1561398919; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=R4lBlU0WLc3jgT2wqWehGW+tEHNu5WWkyJMXTdLSQLo=; b=IQLyWQxPpUaLjdYIUb9wZOqMOjwMywEvrBVB//L3Wjud20yphNeq+ml8i/oMgdzEfkHKI8W1Ee9iGDnQwgMHa4hQ2y645BjsffSN/vKkr01N3N4E3jFuANYQKp+mRMILtvGfzkwq5vM8dHXTOZkbap3/G/5MuLGp/LGogB2l2gM= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15613989195382.8005920396172996; Mon, 24 Jun 2019 10:55:19 -0700 (PDT) Received: from localhost ([::1]:53536 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTBW-00040V-Id for importer@patchew.org; Mon, 24 Jun 2019 13:55:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49156) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSx2-0001g6-Qr for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSwz-0005Vq-Vv for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:20 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39606) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSwv-0005Mp-Pv; Mon, 24 Jun 2019 13:40:13 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D7043092654; Mon, 24 Jun 2019 17:40:13 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9478D608BA; Mon, 24 Jun 2019 17:40:12 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:33 +0200 Message-Id: <20190624173935.25747-14-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Mon, 24 Jun 2019 17:40:13 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 13/14] iotests: qcow2's encrypt.format is now optional X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Remove the encrypt.format option from the two blockdev-add test cases for encrypted qcow2 images in 087 to explicitly test that this parameter is now optional. Additionally, show that explicitly specifying encrypt.format=3Dauto works just as well, the same for specifying the correct format (encrypt.format=3Dluks here), and that specifying the wrong format (encrypt.format=3Daes) results in an error. While touching this test case, reduce the LUKS iteration time to 10 so the test stays reasonably fast. Signed-off-by: Max Reitz Reviewed-by: Daniel P. Berrang=C3=A9 Reviewed-by: Eric Blake --- tests/qemu-iotests/087 | 65 +++++++++++++++++++++++--------------- tests/qemu-iotests/087.out | 26 ++++++++++++++- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 index d6c8613419..0e52dec483 100755 --- a/tests/qemu-iotests/087 +++ b/tests/qemu-iotests/087 @@ -149,7 +149,6 @@ run_qemu < (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 156139918463783.58836362666614; Mon, 24 Jun 2019 10:59:44 -0700 (PDT) Received: from localhost ([::1]:53584 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfTFm-0000j5-RP for importer@patchew.org; Mon, 24 Jun 2019 13:59:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:49308) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfSxP-00021Q-IX for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfSxL-00067L-FH for qemu-devel@nongnu.org; Mon, 24 Jun 2019 13:40:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55552) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfSxB-0005fg-3q; Mon, 24 Jun 2019 13:40:31 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E88596696C; Mon, 24 Jun 2019 17:40:15 +0000 (UTC) Received: from localhost (ovpn-204-152.brq.redhat.com [10.40.204.152]) by smtp.corp.redhat.com (Postfix) with ESMTPS id EB37260BE2; Mon, 24 Jun 2019 17:40:14 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 24 Jun 2019 19:39:34 +0200 Message-Id: <20190624173935.25747-15-mreitz@redhat.com> In-Reply-To: <20190624173935.25747-1-mreitz@redhat.com> References: <20190624173935.25747-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 24 Jun 2019 17:40:21 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v4 14/14] block: Make use of QAPI defaults X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , qemu-devel@nongnu.org, Michael Roth , Markus Armbruster , Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This changes most of block-core.json to use QAPI defaults where possible. Notably omitted is everything around BlockdevOptions*, because that would change json:{} filenames (which is technically not an incompatible change, it would just break many iotests). Signed-off-by: Max Reitz --- qapi/block-core.json | 144 +++++++++++++++++++++------------- block/file-posix.c | 9 --- block/file-win32.c | 8 +- block/parallels.c | 6 +- block/qcow2.c | 36 +++------ block/qed.c | 3 - block/sheepdog.c | 3 - block/vdi.c | 3 - block/vhdx.c | 28 ++----- block/vpc.c | 3 - blockdev.c | 182 +++++++++---------------------------------- monitor/hmp-cmds.c | 27 ++++--- monitor/qmp-cmds.c | 3 +- 13 files changed, 165 insertions(+), 290 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index b30a19bf8e..5d5c0c4b81 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -1300,7 +1300,8 @@ { 'struct': 'BlockdevSnapshotSync', 'data': { '*device': 'str', '*node-name': 'str', 'snapshot-file': 'str', '*snapshot-node-name': 'str', - '*format': 'str', '*mode': 'NewImageMode' } } + '*format': { 'type': 'str', 'default': 'qcow2' }, + '*mode': { 'type': 'NewImageMode', 'default': 'absolute-paths'= } } } =20 ## # @BlockdevSnapshot: @@ -1378,11 +1379,16 @@ { 'struct': 'DriveBackup', 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', '*format': 'str', 'sync': 'MirrorSyncMode', - '*mode': 'NewImageMode', '*speed': 'int', - '*bitmap': 'str', '*compress': 'bool', - '*on-source-error': 'BlockdevOnError', - '*on-target-error': 'BlockdevOnError', - '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } + '*mode': { 'type': 'NewImageMode', 'default': 'absolute-paths'= }, + '*speed': { 'type': 'int', 'default': 0 }, + '*bitmap': 'str', + '*compress': { 'type': 'bool', 'default': false }, + '*on-source-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*on-target-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*auto-finalize': { 'type': 'bool', 'default': true }, + '*auto-dismiss': { 'type': 'bool', 'default': true } } } =20 ## # @BlockdevBackup: @@ -1437,11 +1443,16 @@ ## { 'struct': 'BlockdevBackup', 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', - 'sync': 'MirrorSyncMode', '*speed': 'int', - '*bitmap': 'str', '*compress': 'bool', - '*on-source-error': 'BlockdevOnError', - '*on-target-error': 'BlockdevOnError', - '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } + 'sync': 'MirrorSyncMode', + '*speed': { 'type': 'int', 'default': 0 }, + '*bitmap': 'str', + '*compress': { 'type': 'bool', 'default': false }, + '*on-source-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*on-target-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*auto-finalize': { 'type': 'bool', 'default': true }, + '*auto-dismiss': { 'type': 'bool', 'default': true } } } =20 ## # @blockdev-snapshot-sync: @@ -1631,9 +1642,11 @@ { 'command': 'block-commit', 'data': { '*job-id': 'str', 'device': 'str', '*base-node': 'str', '*base': 'str', '*top-node': 'str', '*top': 'str', - '*backing-file': 'str', '*speed': 'int', + '*backing-file': 'str', + '*speed': { 'type': 'int', 'default': 0 }, '*filter-node-name': 'str', - '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } + '*auto-finalize': { 'type': 'bool', 'default': true }, + '*auto-dismiss': { 'type': 'bool', 'default': true } } } =20 ## # @drive-backup: @@ -1958,12 +1971,19 @@ { 'struct': 'DriveMirror', 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', '*format': 'str', '*node-name': 'str', '*replaces': 'str', - 'sync': 'MirrorSyncMode', '*mode': 'NewImageMode', - '*speed': 'int', '*granularity': 'uint32', - '*buf-size': 'int', '*on-source-error': 'BlockdevOnError', - '*on-target-error': 'BlockdevOnError', - '*unmap': 'bool', '*copy-mode': 'MirrorCopyMode', - '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } + 'sync': 'MirrorSyncMode', + '*mode': { 'type': 'NewImageMode', 'default': 'absolute-paths'= }, + '*speed': { 'type': 'int', 'default': 0 }, + '*granularity': 'uint32', + '*buf-size': 'int', + '*on-source-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*on-target-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*unmap': { 'type': 'bool', 'default': true }, + '*copy-mode': { 'type': 'MirrorCopyMode', 'default': 'backgrou= nd' }, + '*auto-finalize': { 'type': 'bool', 'default': true }, + '*auto-dismiss': { 'type': 'bool', 'default': true } } } =20 ## # @BlockDirtyBitmap: @@ -1984,8 +2004,8 @@ # # @name: name of the dirty bitmap # -# @granularity: the bitmap granularity, default is 64k for -# block-dirty-bitmap-add +# @granularity: the bitmap granularity, default is the node's cluster size +# (clamped to [4k, 64k]), or 64k # # @persistent: the bitmap is persistent, i.e. it will be saved to the # corresponding block device image file on its close. For now= only @@ -2004,7 +2024,9 @@ ## { 'struct': 'BlockDirtyBitmapAdd', 'data': { 'node': 'str', 'name': 'str', '*granularity': 'uint32', - '*persistent': 'bool', '*autoload': 'bool', '*disabled': 'bool= ' } } + '*persistent': { 'type': 'bool', 'default': false }, + '*autoload': 'bool', + '*disabled': { 'type': 'bool', 'default': false } } } =20 ## # @BlockDirtyBitmapMergeSource: @@ -2282,12 +2304,17 @@ 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', '*replaces': 'str', 'sync': 'MirrorSyncMode', - '*speed': 'int', '*granularity': 'uint32', - '*buf-size': 'int', '*on-source-error': 'BlockdevOnError', - '*on-target-error': 'BlockdevOnError', + '*speed': { 'type': 'int', 'default': 0 }, + '*granularity': 'uint32', + '*buf-size': 'int', + '*on-source-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, + '*on-target-error': { 'type': 'BlockdevOnError', + 'default': 'report' }, '*filter-node-name': 'str', - '*copy-mode': 'MirrorCopyMode', - '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } + '*copy-mode': { 'type': 'MirrorCopyMode', 'default': 'backgrou= nd' }, + '*auto-finalize': { 'type': 'bool', 'default': true }, + '*auto-dismiss': { 'type': 'bool', 'default': true } } } =20 ## # @block_set_io_throttle: @@ -2580,9 +2607,11 @@ ## { 'command': 'block-stream', 'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', - '*base-node': 'str', '*backing-file': 'str', '*speed': 'int', - '*on-error': 'BlockdevOnError', - '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } + '*base-node': 'str', '*backing-file': 'str', + '*speed': { 'type': 'int', 'default': 0 }, + '*on-error': { 'type': 'BlockdevOnError', 'default': 'report' = }, + '*auto-finalize': { 'type': 'bool', 'default': true }, + '*auto-dismiss': { 'type': 'bool', 'default': true } } } =20 ## # @block-job-set-speed: @@ -4204,8 +4233,8 @@ { 'struct': 'BlockdevCreateOptionsFile', 'data': { 'filename': 'str', 'size': 'size', - '*preallocation': 'PreallocMode', - '*nocow': 'bool' } } + '*preallocation': { 'type': 'PreallocMode', 'default': 'off'= }, + '*nocow': { 'type': 'bool', 'default': false } } } =20 ## # @BlockdevCreateOptionsGluster: @@ -4224,7 +4253,7 @@ { 'struct': 'BlockdevCreateOptionsGluster', 'data': { 'location': 'BlockdevOptionsGluster', 'size': 'size', - '*preallocation': 'PreallocMode' } } + '*preallocation': { 'type': 'PreallocMode', 'default': 'off'= } } } =20 ## # @BlockdevCreateOptionsLUKS: @@ -4269,7 +4298,7 @@ { 'struct': 'BlockdevCreateOptionsParallels', 'data': { 'file': 'BlockdevRef', 'size': 'size', - '*cluster-size': 'size' } } + '*cluster-size': { 'type': 'size', 'default': 1048576 } } } =20 ## # @BlockdevCreateOptionsQcow: @@ -4331,16 +4360,16 @@ { 'struct': 'BlockdevCreateOptionsQcow2', 'data': { 'file': 'BlockdevRef', '*data-file': 'BlockdevRef', - '*data-file-raw': 'bool', + '*data-file-raw': { 'type': 'bool', 'default': false }, 'size': 'size', - '*version': 'BlockdevQcow2Version', + '*version': { 'type': 'BlockdevQcow2Version', 'default= ': 'v3' }, '*backing-file': 'str', '*backing-fmt': 'BlockdevDriver', '*encrypt': 'QCryptoBlockCreateOptions', - '*cluster-size': 'size', - '*preallocation': 'PreallocMode', - '*lazy-refcounts': 'bool', - '*refcount-bits': 'int' } } + '*cluster-size': { 'type': 'size', 'default': 65536 }, + '*preallocation': { 'type': 'PreallocMode', 'default': 'off'= }, + '*lazy-refcounts': { 'type': 'bool', 'default': false }, + '*refcount-bits': { 'type': 'int', 'default': 16 } } } =20 ## # @BlockdevCreateOptionsQed: @@ -4362,7 +4391,7 @@ 'size': 'size', '*backing-file': 'str', '*backing-fmt': 'BlockdevDriver', - '*cluster-size': 'size', + '*cluster-size': { 'type': 'size', 'default': 65536 }, '*table-size': 'int' } } =20 ## @@ -4445,11 +4474,13 @@ 'data': { 'file': 'BlockdevRef', 'size': 'size', '*extents': ['BlockdevRef'], - '*subformat': 'BlockdevVmdkSubformat', + '*subformat': { 'type': 'BlockdevVmdkSubformat', + 'default': 'monolithicSparse' }, '*backing-file': 'str', - '*adapter-type': 'BlockdevVmdkAdapterType', - '*hwversion': 'str', - '*zeroed-grain': 'bool' } } + '*adapter-type': { 'type': 'BlockdevVmdkAdapterType', + 'default': 'ide' }, + '*hwversion': { 'type': 'str', 'default': '4' }, + '*zeroed-grain': { 'type': 'bool', 'default': false } } } =20 =20 ## @@ -4516,7 +4547,7 @@ 'data': { 'location': 'BlockdevOptionsSheepdog', 'size': 'size', '*backing-file': 'str', - '*preallocation': 'PreallocMode', + '*preallocation': { 'type': 'PreallocMode', 'default': 'off'= }, '*redundancy': 'SheepdogRedundancy', '*object-size': 'size' } } =20 @@ -4549,7 +4580,7 @@ { 'struct': 'BlockdevCreateOptionsVdi', 'data': { 'file': 'BlockdevRef', 'size': 'size', - '*preallocation': 'PreallocMode' } } + '*preallocation': { 'type': 'PreallocMode', 'default': 'off'= } } } =20 ## # @BlockdevVhdxSubformat: @@ -4584,10 +4615,11 @@ { 'struct': 'BlockdevCreateOptionsVhdx', 'data': { 'file': 'BlockdevRef', 'size': 'size', - '*log-size': 'size', + '*log-size': { 'type': 'size', 'default': 1048576 }, '*block-size': 'size', - '*subformat': 'BlockdevVhdxSubformat', - '*block-state-zero': 'bool' } } + '*subformat': { 'type': 'BlockdevVhdxSubformat', + 'default': 'dynamic' }, + '*block-state-zero': { 'type': 'bool', 'default': true } } } =20 ## # @BlockdevVpcSubformat: @@ -4607,7 +4639,7 @@ # # @file Node to create the image format on # @size Size of the virtual disk in bytes -# @subformat vhdx subformat (default: dynamic) +# @subformat vpc subformat (default: dynamic) # @force-size Force use of the exact byte size instead of rounding t= o the # next size that can be represented in CHS geometry # (default: false) @@ -4617,8 +4649,9 @@ { 'struct': 'BlockdevCreateOptionsVpc', 'data': { 'file': 'BlockdevRef', 'size': 'size', - '*subformat': 'BlockdevVpcSubformat', - '*force-size': 'bool' } } + '*subformat': { 'type': 'BlockdevVpcSubformat', + 'default': 'dynamic' }, + '*force-size': { 'type': 'bool', 'default': false } }= } =20 ## # @BlockdevCreateOptions: @@ -4714,7 +4747,7 @@ { 'command': 'blockdev-open-tray', 'data': { '*device': 'str', '*id': 'str', - '*force': 'bool' } } + '*force': { 'type': 'bool', 'default': false } } } =20 ## # @blockdev-close-tray: @@ -4905,7 +4938,8 @@ '*id': 'str', 'filename': 'str', '*format': 'str', - '*read-only-mode': 'BlockdevChangeReadOnlyMode' } } + '*read-only-mode': { 'type': 'BlockdevChangeReadOnlyMode', + 'default': 'retain' } } } =20 =20 ## diff --git a/block/file-posix.c b/block/file-posix.c index ab05b51a66..88ac031e9f 100644 --- a/block/file-posix.c +++ b/block/file-posix.c @@ -2243,13 +2243,6 @@ raw_co_create(BlockdevCreateOptions *options, Error = **errp) assert(options->driver =3D=3D BLOCKDEV_DRIVER_FILE); file_opts =3D &options->u.file; =20 - if (!file_opts->has_nocow) { - file_opts->nocow =3D false; - } - if (!file_opts->has_preallocation) { - file_opts->preallocation =3D PREALLOC_MODE_OFF; - } - /* Create file */ fd =3D qemu_open(file_opts->filename, O_RDWR | O_CREAT | O_BINARY, 064= 4); if (fd < 0) { @@ -2365,9 +2358,7 @@ static int coroutine_fn raw_co_create_opts(const char= *filename, QemuOpts *opts, .u.file =3D { .filename =3D (char *) filename, .size =3D total_size, - .has_preallocation =3D true, .preallocation =3D prealloc, - .has_nocow =3D true, .nocow =3D nocow, }, }; diff --git a/block/file-win32.c b/block/file-win32.c index 6b2d67b239..9164b3d77c 100644 --- a/block/file-win32.c +++ b/block/file-win32.c @@ -565,11 +565,11 @@ static int raw_co_create(BlockdevCreateOptions *optio= ns, Error **errp) assert(options->driver =3D=3D BLOCKDEV_DRIVER_FILE); file_opts =3D &options->u.file; =20 - if (file_opts->has_preallocation) { + if (file_opts->preallocation) { error_setg(errp, "Preallocation is not supported on Windows"); return -EINVAL; } - if (file_opts->has_nocow) { + if (file_opts->nocow) { error_setg(errp, "nocow is not supported on Windows"); return -EINVAL; } @@ -604,8 +604,8 @@ static int coroutine_fn raw_co_create_opts(const char *= filename, QemuOpts *opts, .u.file =3D { .filename =3D (char *) filename, .size =3D total_size, - .has_preallocation =3D false, - .has_nocow =3D false, + .preallocation =3D false, + .nocow =3D false, }, }; return raw_co_create(&options, errp); diff --git a/block/parallels.c b/block/parallels.c index 00fae125d1..67de90bd51 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -522,11 +522,7 @@ static int coroutine_fn parallels_co_create(BlockdevCr= eateOptions* opts, /* Sanity checks */ total_size =3D parallels_opts->size; =20 - if (parallels_opts->has_cluster_size) { - cl_size =3D parallels_opts->cluster_size; - } else { - cl_size =3D DEFAULT_CLUSTER_SIZE; - } + cl_size =3D parallels_opts->cluster_size; =20 /* XXX What is the real limit here? This is an insanely large maximum.= */ if (cl_size >=3D INT64_MAX / MAX_PARALLELS_IMAGE_FACTOR) { diff --git a/block/qcow2.c b/block/qcow2.c index 95de19d906..0136be1a14 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3076,35 +3076,23 @@ qcow2_co_create(BlockdevCreateOptions *create_optio= ns, Error **errp) goto out; } =20 - if (qcow2_opts->has_version) { - switch (qcow2_opts->version) { - case BLOCKDEV_QCOW2_VERSION_V2: - version =3D 2; - break; - case BLOCKDEV_QCOW2_VERSION_V3: - version =3D 3; - break; - default: - g_assert_not_reached(); - } - } else { + switch (qcow2_opts->version) { + case BLOCKDEV_QCOW2_VERSION_V2: + version =3D 2; + break; + case BLOCKDEV_QCOW2_VERSION_V3: version =3D 3; + break; + default: + g_assert_not_reached(); } =20 - if (qcow2_opts->has_cluster_size) { - cluster_size =3D qcow2_opts->cluster_size; - } else { - cluster_size =3D DEFAULT_CLUSTER_SIZE; - } - + cluster_size =3D qcow2_opts->cluster_size; if (!validate_cluster_size(cluster_size, errp)) { ret =3D -EINVAL; goto out; } =20 - if (!qcow2_opts->has_preallocation) { - qcow2_opts->preallocation =3D PREALLOC_MODE_OFF; - } if (qcow2_opts->has_backing_file && qcow2_opts->preallocation !=3D PREALLOC_MODE_OFF) { @@ -3119,9 +3107,6 @@ qcow2_co_create(BlockdevCreateOptions *create_options= , Error **errp) goto out; } =20 - if (!qcow2_opts->has_lazy_refcounts) { - qcow2_opts->lazy_refcounts =3D false; - } if (version < 3 && qcow2_opts->lazy_refcounts) { error_setg(errp, "Lazy refcounts only supported with compatibility= " "level 1.1 and above (use version=3Dv3 or greater)"); @@ -3129,9 +3114,6 @@ qcow2_co_create(BlockdevCreateOptions *create_options= , Error **errp) goto out; } =20 - if (!qcow2_opts->has_refcount_bits) { - qcow2_opts->refcount_bits =3D 16; - } if (qcow2_opts->refcount_bits > 64 || !is_power_of_2(qcow2_opts->refcount_bits)) { diff --git a/block/qed.c b/block/qed.c index 77c7cef175..7046eb63ae 100644 --- a/block/qed.c +++ b/block/qed.c @@ -615,9 +615,6 @@ static int coroutine_fn bdrv_qed_co_create(BlockdevCrea= teOptions *opts, qed_opts =3D &opts->u.qed; =20 /* Validate options and set default values */ - if (!qed_opts->has_cluster_size) { - qed_opts->cluster_size =3D QED_DEFAULT_CLUSTER_SIZE; - } if (!qed_opts->has_table_size) { qed_opts->table_size =3D QED_DEFAULT_TABLE_SIZE; } diff --git a/block/sheepdog.c b/block/sheepdog.c index 6f402e5d4d..7d74e76c34 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -2034,9 +2034,6 @@ static int sd_co_create(BlockdevCreateOptions *option= s, Error **errp) s->inode.vdi_size =3D opts->size; backing_file =3D opts->backing_file; =20 - if (!opts->has_preallocation) { - opts->preallocation =3D PREALLOC_MODE_OFF; - } switch (opts->preallocation) { case PREALLOC_MODE_OFF: prealloc =3D false; diff --git a/block/vdi.c b/block/vdi.c index b9845a4cbd..9dd22ee1d0 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -756,9 +756,6 @@ static int coroutine_fn vdi_co_do_create(BlockdevCreate= Options *create_options, /* Validate options and set default values */ bytes =3D vdi_opts->size; =20 - if (!vdi_opts->has_preallocation) { - vdi_opts->preallocation =3D PREALLOC_MODE_OFF; - } switch (vdi_opts->preallocation) { case PREALLOC_MODE_OFF: image_type =3D VDI_TYPE_DYNAMIC; diff --git a/block/vhdx.c b/block/vhdx.c index d6070b6fa8..b238438c1d 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -1829,29 +1829,19 @@ static int coroutine_fn vhdx_co_create(BlockdevCrea= teOptions *opts, return -EINVAL; } =20 - if (!vhdx_opts->has_log_size) { - log_size =3D DEFAULT_LOG_SIZE; - } else { - if (vhdx_opts->log_size > UINT32_MAX) { - error_setg(errp, "Log size must be smaller than 4 GB"); - return -EINVAL; - } - log_size =3D vhdx_opts->log_size; + if (vhdx_opts->log_size > UINT32_MAX) { + error_setg(errp, "Log size must be smaller than 4 GB"); + return -EINVAL; } + log_size =3D vhdx_opts->log_size; if (log_size < MiB || (log_size % MiB) !=3D 0) { error_setg(errp, "Log size must be a multiple of 1 MB"); return -EINVAL; } =20 - if (!vhdx_opts->has_block_state_zero) { - use_zero_blocks =3D true; - } else { - use_zero_blocks =3D vhdx_opts->block_state_zero; - } + use_zero_blocks =3D vhdx_opts->block_state_zero; =20 - if (!vhdx_opts->has_subformat) { - vhdx_opts->subformat =3D BLOCKDEV_VHDX_SUBFORMAT_DYNAMIC; - } + vhdx_opts->subformat =3D BLOCKDEV_VHDX_SUBFORMAT_DYNAMIC; =20 switch (vhdx_opts->subformat) { case BLOCKDEV_VHDX_SUBFORMAT_DYNAMIC: @@ -2030,10 +2020,8 @@ static int coroutine_fn vhdx_co_create_opts(const ch= ar *filename, create_options->u.vhdx.size =3D ROUND_UP(create_options->u.vhdx.size, BDRV_SECTOR_SIZE); =20 - if (create_options->u.vhdx.has_log_size) { - create_options->u.vhdx.log_size =3D - ROUND_UP(create_options->u.vhdx.log_size, MiB); - } + create_options->u.vhdx.log_size =3D + ROUND_UP(create_options->u.vhdx.log_size, MiB); if (create_options->u.vhdx.has_block_size) { create_options->u.vhdx.block_size =3D ROUND_UP(create_options->u.vhdx.block_size, MiB); diff --git a/block/vpc.c b/block/vpc.c index d4776ee8a5..82cd8d4081 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -991,9 +991,6 @@ static int coroutine_fn vpc_co_create(BlockdevCreateOpt= ions *opts, /* Validate options and set default values */ total_size =3D vpc_opts->size; =20 - if (!vpc_opts->has_subformat) { - vpc_opts->subformat =3D BLOCKDEV_VPC_SUBFORMAT_DYNAMIC; - } switch (vpc_opts->subformat) { case BLOCKDEV_VPC_SUBFORMAT_DYNAMIC: disk_type =3D VHD_DYNAMIC; diff --git a/blockdev.c b/blockdev.c index 4d141e9a1f..f3828697a8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1122,8 +1122,8 @@ void qmp_blockdev_snapshot_sync(bool has_device, cons= t char *device, const char *snapshot_file, bool has_snapshot_node_name, const char *snapshot_node_name, - bool has_format, const char *format, - bool has_mode, NewImageMode mode, Error **= errp) + const char *format, NewImageMode mode, + Error **errp) { BlockdevSnapshotSync snapshot =3D { .has_device =3D has_device, @@ -1133,9 +1133,7 @@ void qmp_blockdev_snapshot_sync(bool has_device, cons= t char *device, .snapshot_file =3D (char *) snapshot_file, .has_snapshot_node_name =3D has_snapshot_node_name, .snapshot_node_name =3D (char *) snapshot_node_name, - .has_format =3D has_format, .format =3D (char *) format, - .has_mode =3D has_mode, .mode =3D mode, }; TransactionAction action =3D { @@ -1601,8 +1599,6 @@ static void external_snapshot_prepare(BlkActionState = *common, =20 if (action->type =3D=3D TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC= ) { BlockdevSnapshotSync *s =3D action->u.blockdev_snapshot_sync.data; - const char *format =3D s->has_format ? s->format : "qcow2"; - enum NewImageMode mode; const char *snapshot_node_name =3D s->has_snapshot_node_name ? s->snapshot_node_name : NULL; =20 @@ -1622,15 +1618,14 @@ static void external_snapshot_prepare(BlkActionStat= e *common, flags |=3D BDRV_O_NO_BACKING; =20 /* create new image w/backing file */ - mode =3D s->has_mode ? s->mode : NEW_IMAGE_MODE_ABSOLUTE_PATHS; - if (mode !=3D NEW_IMAGE_MODE_EXISTING) { + if (s->mode !=3D NEW_IMAGE_MODE_EXISTING) { int64_t size =3D bdrv_getlength(state->old_bs); if (size < 0) { error_setg_errno(errp, -size, "bdrv_getlength failed"); goto out; } bdrv_refresh_filename(state->old_bs); - bdrv_img_create(new_image_file, format, + bdrv_img_create(new_image_file, s->format, state->old_bs->filename, state->old_bs->drv->format_name, NULL, size, flags, false, &local_err); @@ -1644,7 +1639,7 @@ static void external_snapshot_prepare(BlkActionState = *common, if (snapshot_node_name) { qdict_put_str(options, "node-name", snapshot_node_name); } - qdict_put_str(options, "driver", format); + qdict_put_str(options, "driver", s->format); } =20 state->new_bs =3D bdrv_open(new_image_file, snapshot_ref, options, fla= gs, @@ -1963,9 +1958,9 @@ static void block_dirty_bitmap_add_prepare(BlkActionS= tate *common, /* AIO context taken and released within qmp_block_dirty_bitmap_add */ qmp_block_dirty_bitmap_add(action->node, action->name, action->has_granularity, action->granularit= y, - action->has_persistent, action->persistent, + action->persistent, action->has_autoload, action->autoload, - action->has_disabled, action->disabled, + action->disabled, &local_err); =20 if (!local_err) { @@ -2410,15 +2405,11 @@ static int do_open_tray(const char *blk_name, const= char *qdev_id, =20 void qmp_blockdev_open_tray(bool has_device, const char *device, bool has_id, const char *id, - bool has_force, bool force, - Error **errp) + bool force, Error **errp) { Error *local_err =3D NULL; int rc; =20 - if (!has_force) { - force =3D false; - } rc =3D do_open_tray(has_device ? device : NULL, has_id ? id : NULL, force, &local_err); @@ -2610,7 +2601,6 @@ void qmp_blockdev_change_medium(bool has_device, cons= t char *device, bool has_id, const char *id, const char *filename, bool has_format, const char *format, - bool has_read_only, BlockdevChangeReadOnlyMode read_only, Error **errp) { @@ -2637,10 +2627,6 @@ void qmp_blockdev_change_medium(bool has_device, con= st char *device, bdrv_flags &=3D ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKI= NG | BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY); =20 - if (!has_read_only) { - read_only =3D BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN; - } - switch (read_only) { case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN: break; @@ -2804,10 +2790,8 @@ out: =20 void qmp_block_dirty_bitmap_add(const char *node, const char *name, bool has_granularity, uint32_t granularity, - bool has_persistent, bool persistent, - bool has_autoload, bool autoload, - bool has_disabled, bool disabled, - Error **errp) + bool persistent, bool has_autoload, + bool autoload, bool disabled, Error **errp) { BlockDriverState *bs; BdrvDirtyBitmap *bitmap; @@ -2834,18 +2818,10 @@ void qmp_block_dirty_bitmap_add(const char *node, c= onst char *name, granularity =3D bdrv_get_default_bitmap_granularity(bs); } =20 - if (!has_persistent) { - persistent =3D false; - } - if (has_autoload) { warn_report("Autoload option is deprecated and its value is ignore= d"); } =20 - if (!has_disabled) { - disabled =3D false; - } - if (persistent) { aio_context =3D bdrv_get_aio_context(bs); aio_context_acquire(aio_context); @@ -3172,10 +3148,8 @@ void qmp_block_stream(bool has_job_id, const char *j= ob_id, const char *device, bool has_base, const char *base, bool has_base_node, const char *base_node, bool has_backing_file, const char *backing_file, - bool has_speed, int64_t speed, - bool has_on_error, BlockdevOnError on_error, - bool has_auto_finalize, bool auto_finalize, - bool has_auto_dismiss, bool auto_dismiss, + int64_t speed, BlockdevOnError on_error, + bool auto_finalize, bool auto_dismiss, Error **errp) { BlockDriverState *bs, *iter; @@ -3185,10 +3159,6 @@ void qmp_block_stream(bool has_job_id, const char *j= ob_id, const char *device, const char *base_name =3D NULL; int job_flags =3D JOB_DEFAULT; =20 - if (!has_on_error) { - on_error =3D BLOCKDEV_ON_ERROR_REPORT; - } - bs =3D bdrv_lookup_bs(device, device, errp); if (!bs) { return; @@ -3246,15 +3216,15 @@ void qmp_block_stream(bool has_job_id, const char *= job_id, const char *device, /* backing_file string overrides base bs filename */ base_name =3D has_backing_file ? backing_file : base_name; =20 - if (has_auto_finalize && !auto_finalize) { + if (!auto_finalize) { job_flags |=3D JOB_MANUAL_FINALIZE; } - if (has_auto_dismiss && !auto_dismiss) { + if (!auto_dismiss) { job_flags |=3D JOB_MANUAL_DISMISS; } =20 stream_start(has_job_id ? job_id : NULL, bs, base_bs, base_name, - job_flags, has_speed ? speed : 0, on_error, &local_err); + job_flags, speed, on_error, &local_err); if (local_err) { error_propagate(errp, local_err); goto out; @@ -3272,11 +3242,9 @@ void qmp_block_commit(bool has_job_id, const char *j= ob_id, const char *device, bool has_top_node, const char *top_node, bool has_top, const char *top, bool has_backing_file, const char *backing_file, - bool has_speed, int64_t speed, + int64_t speed, bool has_filter_node_name, const char *filter_node_n= ame, - bool has_auto_finalize, bool auto_finalize, - bool has_auto_dismiss, bool auto_dismiss, - Error **errp) + bool auto_finalize, bool auto_dismiss, Error **errp) { BlockDriverState *bs; BlockDriverState *iter; @@ -3289,16 +3257,13 @@ void qmp_block_commit(bool has_job_id, const char *= job_id, const char *device, BlockdevOnError on_error =3D BLOCKDEV_ON_ERROR_REPORT; int job_flags =3D JOB_DEFAULT; =20 - if (!has_speed) { - speed =3D 0; - } if (!has_filter_node_name) { filter_node_name =3D NULL; } - if (has_auto_finalize && !auto_finalize) { + if (!auto_finalize) { job_flags |=3D JOB_MANUAL_FINALIZE; } - if (has_auto_dismiss && !auto_dismiss) { + if (!auto_dismiss) { job_flags |=3D JOB_MANUAL_DISMISS; } =20 @@ -3441,30 +3406,9 @@ static BlockJob *do_drive_backup(DriveBackup *backup= , JobTxn *txn, bool set_backing_hd =3D false; int ret; =20 - if (!backup->has_speed) { - backup->speed =3D 0; - } - if (!backup->has_on_source_error) { - backup->on_source_error =3D BLOCKDEV_ON_ERROR_REPORT; - } - if (!backup->has_on_target_error) { - backup->on_target_error =3D BLOCKDEV_ON_ERROR_REPORT; - } - if (!backup->has_mode) { - backup->mode =3D NEW_IMAGE_MODE_ABSOLUTE_PATHS; - } if (!backup->has_job_id) { backup->job_id =3D NULL; } - if (!backup->has_auto_finalize) { - backup->auto_finalize =3D true; - } - if (!backup->has_auto_dismiss) { - backup->auto_dismiss =3D true; - } - if (!backup->has_compress) { - backup->compress =3D false; - } =20 bs =3D bdrv_lookup_bs(backup->device, backup->device, errp); if (!bs) { @@ -3619,27 +3563,9 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup,= JobTxn *txn, int job_flags =3D JOB_DEFAULT; int ret; =20 - if (!backup->has_speed) { - backup->speed =3D 0; - } - if (!backup->has_on_source_error) { - backup->on_source_error =3D BLOCKDEV_ON_ERROR_REPORT; - } - if (!backup->has_on_target_error) { - backup->on_target_error =3D BLOCKDEV_ON_ERROR_REPORT; - } if (!backup->has_job_id) { backup->job_id =3D NULL; } - if (!backup->has_auto_finalize) { - backup->auto_finalize =3D true; - } - if (!backup->has_auto_dismiss) { - backup->auto_dismiss =3D true; - } - if (!backup->has_compress) { - backup->compress =3D false; - } =20 bs =3D bdrv_lookup_bs(backup->device, backup->device, errp); if (!bs) { @@ -3705,51 +3631,33 @@ static void blockdev_mirror_common(const char *job_= id, BlockDriverState *bs, bool has_replaces, const char *replaces, enum MirrorSyncMode sync, BlockMirrorBackingMode backing_mode, - bool has_speed, int64_t speed, + int64_t speed, bool has_granularity, uint32_t granular= ity, bool has_buf_size, int64_t buf_size, - bool has_on_source_error, BlockdevOnError on_source_error, - bool has_on_target_error, BlockdevOnError on_target_error, - bool has_unmap, bool unmap, + bool unmap, bool has_filter_node_name, const char *filter_node_name, - bool has_copy_mode, MirrorCopyMode copy= _mode, - bool has_auto_finalize, bool auto_final= ize, - bool has_auto_dismiss, bool auto_dismis= s, + MirrorCopyMode copy_mode, + bool auto_finalize, bool auto_dismiss, Error **errp) { int job_flags =3D JOB_DEFAULT; =20 - if (!has_speed) { - speed =3D 0; - } - if (!has_on_source_error) { - on_source_error =3D BLOCKDEV_ON_ERROR_REPORT; - } - if (!has_on_target_error) { - on_target_error =3D BLOCKDEV_ON_ERROR_REPORT; - } if (!has_granularity) { granularity =3D 0; } if (!has_buf_size) { buf_size =3D 0; } - if (!has_unmap) { - unmap =3D true; - } if (!has_filter_node_name) { filter_node_name =3D NULL; } - if (!has_copy_mode) { - copy_mode =3D MIRROR_COPY_MODE_BACKGROUND; - } - if (has_auto_finalize && !auto_finalize) { + if (!auto_finalize) { job_flags |=3D JOB_MANUAL_FINALIZE; } - if (has_auto_dismiss && !auto_dismiss) { + if (!auto_dismiss) { job_flags |=3D JOB_MANUAL_DISMISS; } =20 @@ -3844,10 +3752,6 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) aio_context =3D bdrv_get_aio_context(bs); aio_context_acquire(aio_context); =20 - if (!arg->has_mode) { - arg->mode =3D NEW_IMAGE_MODE_ABSOLUTE_PATHS; - } - if (!arg->has_format) { format =3D (arg->mode =3D=3D NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name); @@ -3938,17 +3842,12 @@ void qmp_drive_mirror(DriveMirror *arg, Error **err= p) =20 blockdev_mirror_common(arg->has_job_id ? arg->job_id : NULL, bs, targe= t_bs, arg->has_replaces, arg->replaces, arg->sync, - backing_mode, arg->has_speed, arg->speed, + backing_mode, arg->speed, arg->has_granularity, arg->granularity, arg->has_buf_size, arg->buf_size, - arg->has_on_source_error, arg->on_source_error, - arg->has_on_target_error, arg->on_target_error, - arg->has_unmap, arg->unmap, - false, NULL, - arg->has_copy_mode, arg->copy_mode, - arg->has_auto_finalize, arg->auto_finalize, - arg->has_auto_dismiss, arg->auto_dismiss, - &local_err); + arg->on_source_error, arg->on_target_error, + arg->unmap, false, NULL, arg->copy_mode, + arg->auto_finalize, arg->auto_dismiss, &local_e= rr); bdrv_unref(target_bs); error_propagate(errp, local_err); out: @@ -3958,20 +3857,15 @@ out: void qmp_blockdev_mirror(bool has_job_id, const char *job_id, const char *device, const char *target, bool has_replaces, const char *replaces, - MirrorSyncMode sync, - bool has_speed, int64_t speed, + MirrorSyncMode sync, int64_t speed, bool has_granularity, uint32_t granularity, bool has_buf_size, int64_t buf_size, - bool has_on_source_error, BlockdevOnError on_source_error, - bool has_on_target_error, BlockdevOnError on_target_error, bool has_filter_node_name, const char *filter_node_name, - bool has_copy_mode, MirrorCopyMode copy_mode, - bool has_auto_finalize, bool auto_finalize, - bool has_auto_dismiss, bool auto_dismiss, - Error **errp) + MirrorCopyMode copy_mode, + bool auto_finalize, bool auto_dismiss, Error **er= rp) { BlockDriverState *bs; BlockDriverState *target_bs; @@ -4000,17 +3894,11 @@ void qmp_blockdev_mirror(bool has_job_id, const cha= r *job_id, =20 blockdev_mirror_common(has_job_id ? job_id : NULL, bs, target_bs, has_replaces, replaces, sync, backing_mode, - has_speed, speed, - has_granularity, granularity, + speed, has_granularity, granularity, has_buf_size, buf_size, - has_on_source_error, on_source_error, - has_on_target_error, on_target_error, - true, true, + on_source_error, on_target_error, true, has_filter_node_name, filter_node_name, - has_copy_mode, copy_mode, - has_auto_finalize, auto_finalize, - has_auto_dismiss, auto_dismiss, - &local_err); + copy_mode, auto_finalize, auto_dismiss, &local_= err); error_propagate(errp, local_err); out: aio_context_release(aio_context); diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index c283dde0e9..486feccdc5 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1359,9 +1359,14 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdi= ct) .has_format =3D !!format, .format =3D (char *)format, .sync =3D full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, - .has_mode =3D true, .mode =3D reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUT= E_PATHS, + .speed =3D 0, + .on_source_error =3D BLOCKDEV_ON_ERROR_REPORT, + .on_target_error =3D BLOCKDEV_ON_ERROR_REPORT, .unmap =3D true, + .copy_mode =3D MIRROR_COPY_MODE_BACKGROUND, + .auto_finalize =3D true, + .auto_dismiss =3D true, }; =20 if (!filename) { @@ -1388,10 +1393,13 @@ void hmp_drive_backup(Monitor *mon, const QDict *qd= ict) .has_format =3D !!format, .format =3D (char *)format, .sync =3D full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, - .has_mode =3D true, .mode =3D reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUT= E_PATHS, - .has_compress =3D !!compress, + .speed =3D 0, .compress =3D compress, + .on_source_error =3D BLOCKDEV_ON_ERROR_REPORT, + .on_target_error =3D BLOCKDEV_ON_ERROR_REPORT, + .auto_finalize =3D true, + .auto_dismiss =3D true, }; =20 if (!filename) { @@ -1408,7 +1416,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *q= dict) { const char *device =3D qdict_get_str(qdict, "device"); const char *filename =3D qdict_get_try_str(qdict, "snapshot-file"); - const char *format =3D qdict_get_try_str(qdict, "format"); + const char *format =3D qdict_get_try_str(qdict, "format") ?: "qcow2"; bool reuse =3D qdict_get_try_bool(qdict, "reuse", false); enum NewImageMode mode; Error *err =3D NULL; @@ -1424,8 +1432,7 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *q= dict) mode =3D reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PAT= HS; qmp_blockdev_snapshot_sync(true, device, false, NULL, filename, false, NULL, - !!format, format, - true, mode, &err); + format, mode, &err); hmp_handle_error(mon, &err); } =20 @@ -1978,11 +1985,12 @@ void hmp_change(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &err); return; } + } else { + read_only_mode =3D BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN; } =20 qmp_blockdev_change_medium(true, device, false, NULL, target, - !!arg, arg, !!read_only, read_only_mode, - &err); + !!arg, arg, read_only_mode, &err); } =20 hmp_handle_error(mon, &err); @@ -2024,8 +2032,7 @@ void hmp_block_stream(Monitor *mon, const QDict *qdic= t) int64_t speed =3D qdict_get_try_int(qdict, "speed", 0); =20 qmp_block_stream(true, device, device, base !=3D NULL, base, false, NU= LL, - false, NULL, qdict_haskey(qdict, "speed"), speed, tru= e, - BLOCKDEV_ON_ERROR_REPORT, false, false, false, false, + false, NULL, speed, BLOCKDEV_ON_ERROR_REPORT, true, t= rue, &error); =20 hmp_handle_error(mon, &error); diff --git a/monitor/qmp-cmds.c b/monitor/qmp-cmds.c index 01ce77e129..55eaf010b5 100644 --- a/monitor/qmp-cmds.c +++ b/monitor/qmp-cmds.c @@ -408,7 +408,8 @@ void qmp_change(const char *device, const char *target, #endif } else { qmp_blockdev_change_medium(true, device, false, NULL, target, - has_arg, arg, false, 0, errp); + has_arg, arg, + BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, = errp); } } =20 --=20 2.21.0