From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942939493581.6547354771458; Fri, 17 Nov 2017 10:22:19 -0800 (PST) Received: from localhost ([::1]:47253 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlHD-00056s-Gn for importer@patchew.org; Fri, 17 Nov 2017 13:22:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42698) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCL-0000k1-N8 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCK-00029T-ND for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57706) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCF-00020n-8x; Fri, 17 Nov 2017 13:16:59 -0500 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 7E5E0356F6; Fri, 17 Nov 2017 18:16:58 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 983C38B11C; Fri, 17 Nov 2017 18:16:57 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:29 +0100 Message-Id: <20171117181653.20651-2-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.30]); Fri, 17 Nov 2017 18:16:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 01/25] replication: Fix replication open fail X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Wang Guang replication_child_perm request write permissions for all child which will lead bdrv_check_perm fail. replication_child_perm() should request write permissions only if it is writable itself. Signed-off-by: Wang Guang Signed-off-by: Wang Yong Reviewed-by: Xie Changlong Signed-off-by: Kevin Wolf --- block/replication.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/block/replication.c b/block/replication.c index 3a4e6822e4..1c95d673ff 100644 --- a/block/replication.c +++ b/block/replication.c @@ -161,10 +161,13 @@ static void replication_child_perm(BlockDriverState *= bs, BdrvChild *c, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { - *nperm =3D *nshared =3D BLK_PERM_CONSISTENT_READ \ - | BLK_PERM_WRITE \ - | BLK_PERM_WRITE_UNCHANGED; - + *nperm =3D BLK_PERM_CONSISTENT_READ; + if ((bs->open_flags & (BDRV_O_INACTIVE | BDRV_O_RDWR)) =3D=3D BDRV_O_R= DWR) { + *nperm |=3D BLK_PERM_WRITE; + } + *nshared =3D BLK_PERM_CONSISTENT_READ \ + | BLK_PERM_WRITE \ + | BLK_PERM_WRITE_UNCHANGED; return; } =20 --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942760009568.197440645409; Fri, 17 Nov 2017 10:19:20 -0800 (PST) Received: from localhost ([::1]:47229 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlEN-0002ld-2h for importer@patchew.org; Fri, 17 Nov 2017 13:19:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42700) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCL-0000k2-PY for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCK-00029a-PZ for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:05 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36916) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCG-000232-Fq; Fri, 17 Nov 2017 13:17:00 -0500 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 B25B0B5AC; Fri, 17 Nov 2017 18:16:59 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id CDA208B11C; Fri, 17 Nov 2017 18:16:58 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:30 +0100 Message-Id: <20171117181653.20651-3-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.38]); Fri, 17 Nov 2017 18:16:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 02/25] qemu-iotests: Use -nographic in 182 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This avoids that random UI frontend error messages end up in the output. In particular, we were seeing this line in CI error logs: +Unable to init server: Could not connect: Connection refused Signed-off-by: Kevin Wolf Reviewed-by: Kashyap Chamarthy Reviewed-by: Jeff Cody --- tests/qemu-iotests/182 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/182 b/tests/qemu-iotests/182 index 2e078ceed8..4b31592fb8 100755 --- a/tests/qemu-iotests/182 +++ b/tests/qemu-iotests/182 @@ -62,7 +62,7 @@ _launch_qemu -drive file=3D$TEST_IMG,if=3Dnone,id=3Ddrive= 0,file.locking=3Don \ =20 echo echo "Starting a second QEMU using the same image should fail" -echo 'quit' | $QEMU -monitor stdio \ +echo 'quit' | $QEMU -nographic -monitor stdio \ -drive file=3D$TEST_IMG,if=3Dnone,id=3Ddrive0,file.locking=3Don \ -device $virtioblk,drive=3Ddrive0 2>&1 | _filter_testdir 2>&1 | _filter_qemu | --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942820854252.35087472360703; Fri, 17 Nov 2017 10:20:20 -0800 (PST) Received: from localhost ([::1]:47232 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlFE-0003PZ-Qd for importer@patchew.org; Fri, 17 Nov 2017 13:20:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42728) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCM-0000kR-KH for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCL-0002As-Nr for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:06 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33962) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCH-00025C-Rd; Fri, 17 Nov 2017 13:17:01 -0500 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 038A9693CC; Fri, 17 Nov 2017 18:17:01 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0D0FE11E7E5; Fri, 17 Nov 2017 18:16:59 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:31 +0100 Message-Id: <20171117181653.20651-4-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.25]); Fri, 17 Nov 2017 18:17:01 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 03/25] block: Fix error path in bdrv_backing_update_filename() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" error_setg_errno() takes a positive errno code. Spotted by Coverity (CID 1381628). Signed-off-by: Kevin Wolf Reviewed-by: Alberto Garcia Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi --- block.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block.c b/block.c index 684cb018da..f6415547fe 100644 --- a/block.c +++ b/block.c @@ -998,7 +998,7 @@ static int bdrv_backing_update_filename(BdrvChild *c, B= lockDriverState *base, ret =3D bdrv_change_backing_file(parent, filename, base->drv ? base->drv->format_name : ""= ); if (ret < 0) { - error_setg_errno(errp, ret, "Could not update backing file link"); + error_setg_errno(errp, -ret, "Could not update backing file link"); } =20 if (!(orig_flags & BDRV_O_RDWR)) { --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942760012927.7973219607344; Fri, 17 Nov 2017 10:19:20 -0800 (PST) Received: from localhost ([::1]:47230 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlEP-0002mx-3p for importer@patchew.org; Fri, 17 Nov 2017 13:19:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42724) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCM-0000kI-AM for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCL-0002AQ-EP for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:06 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57768) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCJ-00026U-09; Fri, 17 Nov 2017 13:17:03 -0500 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 355F8356F7; Fri, 17 Nov 2017 18:17:02 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4F88F8B11C; Fri, 17 Nov 2017 18:17:01 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:32 +0100 Message-Id: <20171117181653.20651-5-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.30]); Fri, 17 Nov 2017 18:17:02 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 04/25] qcow2: don't permit changing encryption parameters X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" Currently if trying to change encryption parameters on a qcow2 image, qemu-= img will abort. We already explicitly check for attempt to change encrypt.format but missed other parameters like encrypt.key-secret. Rather than list each parameter, just blacklist changing of all parameters with a 'encrypt.' pref= ix. Signed-off-by: Daniel P. Berrange Reviewed-by: Alberto Garcia Reviewed-by: Eric Blake Signed-off-by: Kevin Wolf --- block/qcow2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c index b3d66a0e88..92e5d548e3 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -4069,6 +4069,9 @@ static int qcow2_amend_options(BlockDriverState *bs, = QemuOpts *opts, error_report("Changing the encryption format is not suppor= ted"); return -ENOTSUP; } + } else if (g_str_has_prefix(desc->name, "encrypt.")) { + error_report("Changing the encryption parameters is not suppor= ted"); + return -ENOTSUP; } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) { cluster_size =3D qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZ= E, cluster_size); --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943159524314.30087137564976; Fri, 17 Nov 2017 10:25:59 -0800 (PST) Received: from localhost ([::1]:47278 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlKr-0000Id-KA for importer@patchew.org; Fri, 17 Nov 2017 13:25:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42785) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCO-0000ow-OO for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCN-0002D0-Dm for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57792) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCK-00028H-6q; Fri, 17 Nov 2017 13:17:04 -0500 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 6C1CA267F3; Fri, 17 Nov 2017 18:17:03 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 83FC88B11C; Fri, 17 Nov 2017 18:17:02 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:33 +0100 Message-Id: <20171117181653.20651-6-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.30]); Fri, 17 Nov 2017 18:17:03 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 05/25] block: Deprecate bdrv_set_read_only() and users X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" bdrv_set_read_only() is used by some block drivers to override the read-only option given by the user. This is not how read-only images generally work in QEMU: Instead of second guessing what the user really meant (which currently includes making an image read-only even if the user didn't only use the default, but explicitly said read-only=3Doff), we should error out if we can't provide what the user requested. This adds deprecation warnings to all callers of bdrv_set_read_only() so that the behaviour can be corrected after the usual deprecation period. Signed-off-by: Kevin Wolf --- qapi/block-core.json | 7 +++++-- block.c | 5 +++++ block/bochs.c | 13 ++++++++++--- block/cloop.c | 13 ++++++++++--- block/dmg.c | 12 +++++++++--- block/rbd.c | 14 ++++++++++---- block/vvfat.c | 6 +++++- 7 files changed, 54 insertions(+), 16 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index ab96e348e6..76bf50f813 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -3134,8 +3134,11 @@ # This option is required on the top level of blockdev-add. # @discard: discard-related options (default: ignore) # @cache: cache-related options -# @read-only: whether the block device should be read-only -# (default: false) +# @read-only: whether the block device should be read-only (default: f= alse). +# Note that some block drivers support only read-only acce= ss, +# either generally or in certain configurations. In this c= ase, +# the default value does not work and the option must be +# specified explicitly. # @detect-zeroes: detect and optimize zero writes (Since 2.1) # (default: off) # @force-share: force share all permission on added nodes. diff --git a/block.c b/block.c index f6415547fe..0ed0c27140 100644 --- a/block.c +++ b/block.c @@ -261,6 +261,11 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool = read_only, return 0; } =20 +/* TODO Remove (deprecated since 2.11) + * Block drivers are not supposed to automatically change bs->read_only. + * Instead, they should just check whether they can provide what the user + * explicitly requested and error out if read-write is requested, but they= can + * only provide read-only access. */ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp) { int ret =3D 0; diff --git a/block/bochs.c b/block/bochs.c index a759b6eff0..50c630047b 100644 --- a/block/bochs.c +++ b/block/bochs.c @@ -28,6 +28,7 @@ #include "block/block_int.h" #include "qemu/module.h" #include "qemu/bswap.h" +#include "qemu/error-report.h" =20 /**************************************************************/ =20 @@ -110,9 +111,15 @@ static int bochs_open(BlockDriverState *bs, QDict *opt= ions, int flags, return -EINVAL; } =20 - ret =3D bdrv_set_read_only(bs, true, errp); /* no write support yet */ - if (ret < 0) { - return ret; + if (!bdrv_is_read_only(bs)) { + error_report("Opening bochs images without an explicit read-only= =3Don " + "option is deprecated. Future versions will refuse to= " + "open the image instead of automatically marking the " + "image read-only."); + ret =3D bdrv_set_read_only(bs, true, errp); /* no write support ye= t */ + if (ret < 0) { + return ret; + } } =20 ret =3D bdrv_pread(bs->file, 0, &bochs, sizeof(bochs)); diff --git a/block/cloop.c b/block/cloop.c index d6597fcf78..2be68987bd 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "qemu-common.h" #include "block/block_int.h" #include "qemu/module.h" @@ -72,9 +73,15 @@ static int cloop_open(BlockDriverState *bs, QDict *optio= ns, int flags, return -EINVAL; } =20 - ret =3D bdrv_set_read_only(bs, true, errp); - if (ret < 0) { - return ret; + if (!bdrv_is_read_only(bs)) { + error_report("Opening cloop images without an explicit read-only= =3Don " + "option is deprecated. Future versions will refuse to= " + "open the image instead of automatically marking the " + "image read-only."); + ret =3D bdrv_set_read_only(bs, true, errp); + if (ret < 0) { + return ret; + } } =20 /* read header */ diff --git a/block/dmg.c b/block/dmg.c index 6c0711f563..c9b3c519c4 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -419,9 +419,15 @@ static int dmg_open(BlockDriverState *bs, QDict *optio= ns, int flags, return -EINVAL; } =20 - ret =3D bdrv_set_read_only(bs, true, errp); - if (ret < 0) { - return ret; + if (!bdrv_is_read_only(bs)) { + error_report("Opening dmg images without an explicit read-only=3Do= n " + "option is deprecated. Future versions will refuse to= " + "open the image instead of automatically marking the " + "image read-only."); + ret =3D bdrv_set_read_only(bs, true, errp); + if (ret < 0) { + return ret; + } } =20 block_module_load_one("dmg-bz2"); diff --git a/block/rbd.c b/block/rbd.c index 144f350e1f..a76a5e8755 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -665,10 +665,16 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict = *options, int flags, /* If we are using an rbd snapshot, we must be r/o, otherwise * leave as-is */ if (s->snap !=3D NULL) { - r =3D bdrv_set_read_only(bs, true, &local_err); - if (r < 0) { - error_propagate(errp, local_err); - goto failed_open; + if (!bdrv_is_read_only(bs)) { + error_report("Opening rbd snapshots without an explicit " + "read-only=3Don option is deprecated. Future vers= ions " + "will refuse to open the image instead of " + "automatically marking the image read-only."); + r =3D bdrv_set_read_only(bs, true, &local_err); + if (r < 0) { + error_propagate(errp, local_err); + goto failed_open; + } } } =20 diff --git a/block/vvfat.c b/block/vvfat.c index a0f2335894..0841cc42fc 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -1259,7 +1259,11 @@ static int vvfat_open(BlockDriverState *bs, QDict *o= ptions, int flags, "Unable to set VVFAT to 'rw' when drive is read-onl= y"); goto fail; } - } else { + } else if (!bdrv_is_read_only(bs)) { + error_report("Opening non-rw vvfat images without an explicit " + "read-only=3Don option is deprecated. Future versions= " + "will refuse to open the image instead of " + "automatically marking the image read-only."); /* read only is the default for safety */ ret =3D bdrv_set_read_only(bs, true, &local_err); if (ret < 0) { --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942997203818.3144722240966; Fri, 17 Nov 2017 10:23:17 -0800 (PST) Received: from localhost ([::1]:47256 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlIF-00062R-7f for importer@patchew.org; Fri, 17 Nov 2017 13:23:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42856) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCU-0001Ad-2h for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCP-0002Fw-PV for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36992) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCL-00029g-Dw; Fri, 17 Nov 2017 13:17:05 -0500 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 A32B9FC7B2; Fri, 17 Nov 2017 18:17:04 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id BAB6F11E7E4; Fri, 17 Nov 2017 18:17:03 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:34 +0100 Message-Id: <20171117181653.20651-7-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.38]); Fri, 17 Nov 2017 18:17:04 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 06/25] qcow2: fix image corruption after committing qcow2 image into base X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: "Daniel P. Berrange" After committing the qcow2 image contents into the base image, qemu-img will call bdrv_make_empty to drop the payload in the layered image. When this is done for qcow2 images, it blows away the LUKS encryption header, making the resulting image unusable. There are two codepaths for emptying a qcow2 image, and the second (slower) codepath leaves the LUKS header intact, so force use of that codepath. Reviewed-by: Eric Blake Signed-off-by: Daniel P. Berrange Signed-off-by: Kevin Wolf --- block/qcow2.c | 6 +- tests/qemu-iotests/198 | 104 ++++++++++++++++++++++++++++++++ tests/qemu-iotests/198.out | 126 +++++++++++++++++++++++++++++++++++= ++++ tests/qemu-iotests/common.filter | 4 +- tests/qemu-iotests/group | 1 + 5 files changed, 238 insertions(+), 3 deletions(-) create mode 100755 tests/qemu-iotests/198 create mode 100644 tests/qemu-iotests/198.out diff --git a/block/qcow2.c b/block/qcow2.c index 92e5d548e3..e9a86b7443 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3601,12 +3601,14 @@ static int qcow2_make_empty(BlockDriverState *bs) l1_clusters =3D DIV_ROUND_UP(s->l1_size, s->cluster_size / sizeof(uint= 64_t)); =20 if (s->qcow_version >=3D 3 && !s->snapshots && - 3 + l1_clusters <=3D s->refcount_block_size) { + 3 + l1_clusters <=3D s->refcount_block_size && + s->crypt_method_header !=3D QCOW_CRYPT_LUKS) { /* The following function only works for qcow2 v3 images (it requi= res * the dirty flag) and only as long as there are no snapshots (bec= ause * it completely empties the image). Furthermore, the L1 table and= three * additional clusters (image header, refcount table, one refcount - * block) have to fit inside one refcount block. */ + * block) have to fit inside one refcount block. It cannot be used + * for LUKS (yet) as it throws away the LUKS header cluster(s) */ return make_completely_empty(bs); } =20 diff --git a/tests/qemu-iotests/198 b/tests/qemu-iotests/198 new file mode 100755 index 0000000000..34ef666381 --- /dev/null +++ b/tests/qemu-iotests/198 @@ -0,0 +1,104 @@ +#!/bin/bash +# +# Test commit of encrypted qcow2 files +# +# Copyright (C) 2017 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# creator +owner=3Dberrange@redhat.com + +seq=3D`basename $0` +echo "QA output created by $seq" + +here=3D`pwd` +status=3D1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto generic +_supported_os Linux + + +size=3D16M +TEST_IMG_BASE=3D$TEST_IMG.base +SECRET0=3D"secret,id=3Dsec0,data=3Dastrochicken" +SECRET1=3D"secret,id=3Dsec1,data=3Dfurby" + +TEST_IMG_SAVE=3D$TEST_IMG +TEST_IMG=3D$TEST_IMG_BASE +echo "=3D=3D create base =3D=3D" +_make_test_img --object $SECRET0 -o "encrypt.format=3Dluks,encrypt.key-sec= ret=3Dsec0,encrypt.iter-time=3D10" $size +TEST_IMG=3D$TEST_IMG_SAVE + +IMGSPECBASE=3D"driver=3D$IMGFMT,file.filename=3D$TEST_IMG_BASE,encrypt.key= -secret=3Dsec0" +IMGSPECLAYER=3D"driver=3D$IMGFMT,file.filename=3D$TEST_IMG,encrypt.key-sec= ret=3Dsec1" +IMGSPEC=3D"$IMGSPECLAYER,backing.driver=3D$IMGFMT,backing.file.filename=3D= $TEST_IMG_BASE,backing.encrypt.key-secret=3Dsec0" +QEMU_IO_OPTIONS=3D$QEMU_IO_OPTIONS_NO_FMT + +echo +echo "=3D=3D writing whole image base =3D=3D" +$QEMU_IO --object $SECRET0 -c "write -P 0xa 0 $size" --image-opts $IMGSPEC= BASE | _filter_qemu_io | _filter_testdir + +echo "=3D=3D create overlay =3D=3D" +_make_test_img --object $SECRET1 -o "encrypt.format=3Dluks,encrypt.key-sec= ret=3Dsec1,encrypt.iter-time=3D10" -u -b "$TEST_IMG_BASE" $size + +echo +echo "=3D=3D writing whole image layer =3D=3D" +$QEMU_IO --object $SECRET0 --object $SECRET1 -c "write -P 0x9 0 $size" --i= mage-opts $IMGSPEC | _filter_qemu_io | _filter_testdir + +echo +echo "=3D=3D verify pattern base =3D=3D" +$QEMU_IO --object $SECRET0 -c "read -P 0xa 0 $size" --image-opts $IMGSPECB= ASE | _filter_qemu_io | _filter_testdir + +echo +echo "=3D=3D verify pattern layer =3D=3D" +$QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0x9 0 $size" --im= age-opts $IMGSPEC | _filter_qemu_io | _filter_testdir + +echo +echo "=3D=3D committing layer into base =3D=3D" +$QEMU_IMG commit --object $SECRET0 --object $SECRET1 --image-opts $IMGSPEC= | _filter_testdir + +echo +echo "=3D=3D verify pattern base =3D=3D" +$QEMU_IO --object $SECRET0 -c "read -P 0x9 0 $size" --image-opts $IMGSPECB= ASE | _filter_qemu_io | _filter_testdir + +echo +echo "=3D=3D verify pattern layer =3D=3D" +$QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0x9 0 $size" --im= age-opts $IMGSPEC | _filter_qemu_io | _filter_testdir + +echo +echo "=3D=3D checking image base =3D=3D" +$QEMU_IMG info --image-opts $IMGSPECBASE | _filter_img_info | _filter_test= dir | sed -e "/^disk size:/ D" + +echo +echo "=3D=3D checking image layer =3D=3D" +$QEMU_IMG info --image-opts $IMGSPECLAYER | _filter_img_info | _filter_tes= tdir | sed -e "/^disk size:/ D" + + +# success, all done +echo "*** done" +rm -f $seq.full +status=3D0 diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out new file mode 100644 index 0000000000..2db565e16b --- /dev/null +++ b/tests/qemu-iotests/198.out @@ -0,0 +1,126 @@ +QA output created by 198 +=3D=3D create base =3D=3D +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=3DIMGFMT size=3D16777216 encrypt.= format=3Dluks encrypt.key-secret=3Dsec0 encrypt.iter-time=3D10 + +=3D=3D writing whole image base =3D=3D +wrote 16777216/16777216 bytes at offset 0 +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +=3D=3D create overlay =3D=3D +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D16777216 backing_file= =3DTEST_DIR/t.IMGFMT.base encrypt.format=3Dluks encrypt.key-secret=3Dsec1 e= ncrypt.iter-time=3D10 + +=3D=3D writing whole image layer =3D=3D +wrote 16777216/16777216 bytes at offset 0 +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D verify pattern base =3D=3D +read 16777216/16777216 bytes at offset 0 +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D verify pattern layer =3D=3D +read 16777216/16777216 bytes at offset 0 +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D committing layer into base =3D=3D +Image committed. + +=3D=3D verify pattern base =3D=3D +read 16777216/16777216 bytes at offset 0 +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D verify pattern layer =3D=3D +read 16777216/16777216 bytes at offset 0 +16 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=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"}} +file format: IMGFMT +virtual size: 16M (16777216 bytes) +Format specific information: + compat: 1.1 + lazy refcounts: false + refcount bits: 16 + encrypt: + ivgen alg: plain64 + hash alg: sha256 + cipher alg: aes-256 + uuid: 00000000-0000-0000-0000-000000000000 + format: luks + cipher mode: xts + slots: + [0]: + active: true + iters: 1024 + key offset: 4096 + stripes: 4000 + [1]: + active: false + key offset: 262144 + [2]: + active: false + key offset: 520192 + [3]: + active: false + key offset: 778240 + [4]: + active: false + key offset: 1036288 + [5]: + active: false + key offset: 1294336 + [6]: + active: false + key offset: 1552384 + [7]: + active: false + key offset: 1810432 + payload offset: 2068480 + master key iters: 1024 + corrupt: false + +=3D=3D checking image layer =3D=3D +image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"d= river": "file", "filename": "TEST_DIR/t.IMGFMT"}} +file format: IMGFMT +virtual size: 16M (16777216 bytes) +backing file: TEST_DIR/t.IMGFMT.base +Format specific information: + compat: 1.1 + lazy refcounts: false + refcount bits: 16 + encrypt: + ivgen alg: plain64 + hash alg: sha256 + cipher alg: aes-256 + uuid: 00000000-0000-0000-0000-000000000000 + format: luks + cipher mode: xts + slots: + [0]: + active: true + iters: 1024 + key offset: 4096 + stripes: 4000 + [1]: + active: false + key offset: 262144 + [2]: + active: false + key offset: 520192 + [3]: + active: false + key offset: 778240 + [4]: + active: false + key offset: 1036288 + [5]: + active: false + key offset: 1294336 + [6]: + active: false + key offset: 1552384 + [7]: + active: false + key offset: 1810432 + payload offset: 2068480 + master key iters: 1024 + corrupt: false +*** done diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.f= ilter index 873ca6b104..d9237799e9 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -157,7 +157,9 @@ _filter_img_info() -e "/lazy_refcounts: \\(on\\|off\\)/d" \ -e "/block_size: [0-9]\\+/d" \ -e "/block_state_zero: \\(on\\|off\\)/d" \ - -e "/log_size: [0-9]\\+/d" + -e "/log_size: [0-9]\\+/d" \ + -e "s/iters: [0-9]\\+/iters: 1024/" \ + -e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-00000000000= 0/" } =20 # filter out offsets and file names from qemu-img map; good for both diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 24e5ad1b79..83b839bbe3 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -194,3 +194,4 @@ 194 rw auto migration quick 195 rw auto quick 197 rw auto quick +198 rw auto --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943186097567.2873762300853; Fri, 17 Nov 2017 10:26:26 -0800 (PST) Received: from localhost ([::1]:47279 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlKy-0000O6-7j for importer@patchew.org; Fri, 17 Nov 2017 13:26:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42852) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCU-0001AX-1b for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCP-0002F4-1c for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52402) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCM-0002BN-OZ; Fri, 17 Nov 2017 13:17:06 -0500 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 ED8A2C04DBF3; Fri, 17 Nov 2017 18:17:05 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id F36FA116D8D; Fri, 17 Nov 2017 18:17:04 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:35 +0100 Message-Id: <20171117181653.20651-8-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.32]); Fri, 17 Nov 2017 18:17:05 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 07/25] block: Fix permissions in image activation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Inactive images generally request less permissions for their image files than they would if they were active (in particular, write permissions). Activating the image involves extending the permissions, therefore. drv->bdrv_invalidate_cache() can already require write access to the image file, so we have to update the permissions earlier than that. The current code does it only later, so we have to move up this part. Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz --- block.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/block.c b/block.c index 0ed0c27140..752fe6192b 100644 --- a/block.c +++ b/block.c @@ -4174,7 +4174,29 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Err= or **errp) } } =20 + /* + * Update permissions, they may differ for inactive nodes. + * + * Note that the required permissions of inactive images are always a + * subset of the permissions required after activating the image. This + * allows us to just get the permissions upfront without restricting + * drv->bdrv_invalidate_cache(). + * + * It also means that in error cases, we don't have to try and revert = to + * the old permissions (which is an operation that could fail, too). W= e can + * just keep the extended permissions for the next time that an activa= tion + * of the image is tried. + */ bs->open_flags &=3D ~BDRV_O_INACTIVE; + bdrv_get_cumulative_perm(bs, &perm, &shared_perm); + ret =3D bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &local_err); + if (ret < 0) { + bs->open_flags |=3D BDRV_O_INACTIVE; + error_propagate(errp, local_err); + return; + } + bdrv_set_perm(bs, perm, shared_perm); + if (bs->drv->bdrv_invalidate_cache) { bs->drv->bdrv_invalidate_cache(bs, &local_err); if (local_err) { @@ -4191,16 +4213,6 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Err= or **errp) return; } =20 - /* Update permissions, they may differ for inactive nodes */ - bdrv_get_cumulative_perm(bs, &perm, &shared_perm); - ret =3D bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &local_err); - if (ret < 0) { - bs->open_flags |=3D BDRV_O_INACTIVE; - error_propagate(errp, local_err); - return; - } - bdrv_set_perm(bs, perm, shared_perm); - QLIST_FOREACH(parent, &bs->parents, next_parent) { if (parent->role->activate) { parent->role->activate(parent, &local_err); --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943350105634.2878482791883; Fri, 17 Nov 2017 10:29:10 -0800 (PST) Received: from localhost ([::1]:47297 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlNi-000363-WC for importer@patchew.org; Fri, 17 Nov 2017 13:28:51 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42891) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCV-0001ES-HO for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCT-0002KV-V7 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:15 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37704) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCN-0002Cv-UO; Fri, 17 Nov 2017 13:17:08 -0500 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 2F6026A7E2; Fri, 17 Nov 2017 18:17:07 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 482138B11C; Fri, 17 Nov 2017 18:17:06 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:36 +0100 Message-Id: <20171117181653.20651-9-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.27]); Fri, 17 Nov 2017 18:17:07 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 08/25] iotests: test clearing unknown autoclear_features by qcow2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy Test clearing unknown autoclear_features by qcow2 on incoming migration. [ kwolf: Fixed wait for destination VM startup ] Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz --- tests/qemu-iotests/196 | 66 ++++++++++++++++++++++++++++++++++++++++++= ++++ tests/qemu-iotests/196.out | 5 ++++ tests/qemu-iotests/group | 1 + 3 files changed, 72 insertions(+) create mode 100755 tests/qemu-iotests/196 create mode 100644 tests/qemu-iotests/196.out diff --git a/tests/qemu-iotests/196 b/tests/qemu-iotests/196 new file mode 100755 index 0000000000..4116ebc92b --- /dev/null +++ b/tests/qemu-iotests/196 @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# +# Test clearing unknown autoclear_features flag by qcow2 after +# migration. This test mimics migration to older qemu. +# +# Copyright (c) 2017 Parallels International GmbH +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +import iotests +from iotests import qemu_img + +disk =3D os.path.join(iotests.test_dir, 'disk') +migfile =3D os.path.join(iotests.test_dir, 'migfile') + +class TestInvalidateAutoclear(iotests.QMPTestCase): + + def tearDown(self): + self.vm_a.shutdown() + self.vm_b.shutdown() + os.remove(disk) + os.remove(migfile) + + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, disk, '1M') + + self.vm_a =3D iotests.VM(path_suffix=3D'a').add_drive(disk) + self.vm_a.launch() + + self.vm_b =3D iotests.VM(path_suffix=3D'b').add_drive(disk) + self.vm_b.add_incoming("exec: cat '" + migfile + "'") + + def test_migration(self): + result =3D self.vm_a.qmp('migrate', uri=3D'exec:cat>' + migfile) + self.assert_qmp(result, 'return', {}); + self.assertNotEqual(self.vm_a.event_wait("STOP"), None) + + with open(disk, 'r+b') as f: + f.seek(88) # first byte of autoclear_features field + f.write(b'\xff') + + self.vm_b.launch() + while True: + result =3D self.vm_b.qmp('query-status') + if result['return']['status'] =3D=3D 'running': + break + + with open(disk, 'rb') as f: + f.seek(88) + self.assertEqual(f.read(1), b'\x00') + +if __name__ =3D=3D '__main__': + iotests.main(supported_fmts=3D['qcow2']) diff --git a/tests/qemu-iotests/196.out b/tests/qemu-iotests/196.out new file mode 100644 index 0000000000..ae1213e6f8 --- /dev/null +++ b/tests/qemu-iotests/196.out @@ -0,0 +1,5 @@ +. +---------------------------------------------------------------------- +Ran 1 tests + +OK diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 83b839bbe3..1fad602152 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -193,5 +193,6 @@ 192 rw auto quick 194 rw auto migration quick 195 rw auto quick +196 rw auto quick 197 rw auto quick 198 rw auto --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943350086321.72318388376345; Fri, 17 Nov 2017 10:29:10 -0800 (PST) Received: from localhost ([::1]:47298 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlNr-0003Dd-PG for importer@patchew.org; Fri, 17 Nov 2017 13:28:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43043) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCZ-0001Jk-SA for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCX-0002PT-CO for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34050) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCP-0002EW-CC; Fri, 17 Nov 2017 13:17:09 -0500 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 8C4C17652C; Fri, 17 Nov 2017 18:17:08 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7CD598B11C; Fri, 17 Nov 2017 18:17:07 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:37 +0100 Message-Id: <20171117181653.20651-10-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.26]); Fri, 17 Nov 2017 18:17:08 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 09/25] qcow2: fix image corruption on commit with persistent bitmap X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Eric Blake If an image contains persistent bitmaps, we cannot use the fast path of bdrv_make_empty() to clear the image during qemu-img commit, because that will lose the clusters related to the bitmaps. Also leave a comment in qcow2_read_extensions to remind future feature additions to think about fast-path removal, since we just barely fixed the same bug for LUKS encryption. It's a pain that qemu-img has not yet been taught to manipulate, or even at a very minimum display, information about persistent bitmaps; instead, we have to use QMP commands. It's also a pain that only qeury-block and x-debug-block-dirty-bitmap-sha256 will allow bitmap introspection; but the former requires the node to be hooked to a block device, and the latter is experimental. Signed-off-by: Eric Blake Signed-off-by: Kevin Wolf --- block/qcow2.c | 17 ++-- tests/qemu-iotests/176 | 55 ++++++++++-- tests/qemu-iotests/176.out | 216 +++++++++++++++++++++++++++++++++++++++++= +++- 3 files changed, 270 insertions(+), 18 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index e9a86b7443..f2731a7cb5 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -376,6 +376,8 @@ static int qcow2_read_extensions(BlockDriverState *bs, = uint64_t start_offset, =20 default: /* unknown magic - save it in case we need to rewrite the head= er */ + /* If you add a new feature, make sure to also update the fast + * path of qcow2_make_empty() to deal with it. */ { Qcow2UnknownHeaderExtension *uext; =20 @@ -3600,15 +3602,16 @@ static int qcow2_make_empty(BlockDriverState *bs) =20 l1_clusters =3D DIV_ROUND_UP(s->l1_size, s->cluster_size / sizeof(uint= 64_t)); =20 - if (s->qcow_version >=3D 3 && !s->snapshots && + if (s->qcow_version >=3D 3 && !s->snapshots && !s->nb_bitmaps && 3 + l1_clusters <=3D s->refcount_block_size && s->crypt_method_header !=3D QCOW_CRYPT_LUKS) { - /* The following function only works for qcow2 v3 images (it requi= res - * the dirty flag) and only as long as there are no snapshots (bec= ause - * it completely empties the image). Furthermore, the L1 table and= three - * additional clusters (image header, refcount table, one refcount - * block) have to fit inside one refcount block. It cannot be used - * for LUKS (yet) as it throws away the LUKS header cluster(s) */ + /* The following function only works for qcow2 v3 images (it + * requires the dirty flag) and only as long as there are no + * features that reserve extra clusters (such as snapshots, + * LUKS header, or persistent bitmaps), because it completely + * empties the image. Furthermore, the L1 table and three + * additional clusters (image header, refcount table, one + * refcount block) have to fit inside one refcount block. */ return make_completely_empty(bs); } =20 diff --git a/tests/qemu-iotests/176 b/tests/qemu-iotests/176 index 950b28720e..0f31a20294 100755 --- a/tests/qemu-iotests/176 +++ b/tests/qemu-iotests/176 @@ -3,10 +3,11 @@ # Commit changes into backing chains and empty the top image if the # backing image is not explicitly specified. # -# Variant of 097, which includes snapshots to test different codepath -# in qcow2 +# Variant of 097, which includes snapshots and persistent bitmaps, to +# tickle the slow codepath in qcow2. See also 198, for another feature +# that tickles the slow codepath. # -# Copyright (C) 2014 Red Hat, Inc. +# Copyright (C) 2014, 2017 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -43,11 +44,18 @@ trap "_cleanup; exit \$status" 0 1 2 3 15 . ./common.filter . ./common.pattern =20 -# Any format supporting backing files and bdrv_make_empty +# This test is specific to qcow2 _supported_fmt qcow2 _supported_proto file _supported_os Linux =20 +function run_qemu() +{ + $QEMU -nographic -qmp stdio -serial none "$@" 2>&1 \ + | _filter_testdir | _filter_qmp | _filter_qemu +} + +for reason in snapshot bitmap; do =20 # Four passes: # 0: Two-layer backing chain, commit to upper backing file (implicitly) @@ -66,14 +74,29 @@ _supported_os Linux for i in 0 1 2 3; do =20 echo -echo "=3D=3D=3D Test pass $i =3D=3D=3D" +echo "=3D=3D=3D Test pass $reason.$i =3D=3D=3D" echo =20 len=3D$((2100 * 1024 * 1024 + 512)) # larger than 2G, and not cluster alig= ned TEST_IMG=3D"$TEST_IMG.base" _make_test_img $len TEST_IMG=3D"$TEST_IMG.itmd" _make_test_img -b "$TEST_IMG.base" $len _make_test_img -b "$TEST_IMG.itmd" $len -$QEMU_IMG snapshot -c snap "$TEST_IMG" +# Update the top image to use a feature that is incompatible with fast path +case $reason in + snapshot) $QEMU_IMG snapshot -c snap "$TEST_IMG" ;; + bitmap) + run_qemu < Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942781264903.2988369628117; Fri, 17 Nov 2017 10:19:41 -0800 (PST) Received: from localhost ([::1]:47231 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlEl-00035g-G3 for importer@patchew.org; Fri, 17 Nov 2017 13:19:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42943) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCX-0001GE-16 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCV-0002NH-Mh for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:30513) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCQ-0002G8-J0; Fri, 17 Nov 2017 13:17:10 -0500 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 C474D267F3; Fri, 17 Nov 2017 18:17:09 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id DC42C8B11C; Fri, 17 Nov 2017 18:17:08 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:38 +0100 Message-Id: <20171117181653.20651-11-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.30]); Fri, 17 Nov 2017 18:17:09 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 10/25] qapi/qnull: Add own header X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Reviewed-by: Markus Armbruster Message-id: 20171114180128.17076-2-mreitz@redhat.com Signed-off-by: Max Reitz --- include/qapi/qmp/qdict.h | 1 + include/qapi/qmp/qnull.h | 30 ++++++++++++++++++++++++++++++ include/qapi/qmp/qobject.h | 12 ------------ include/qapi/qmp/types.h | 1 + qapi/qapi-clone-visitor.c | 1 + qapi/string-input-visitor.c | 1 + qobject/qnull.c | 2 +- tests/check-qnull.c | 2 +- 8 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 include/qapi/qmp/qnull.h diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 6588c7f0c8..7ea5120c4a 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -15,6 +15,7 @@ =20 #include "qapi/qmp/qobject.h" #include "qapi/qmp/qlist.h" +#include "qapi/qmp/qnull.h" #include "qapi/qmp/qnum.h" #include "qemu/queue.h" =20 diff --git a/include/qapi/qmp/qnull.h b/include/qapi/qmp/qnull.h new file mode 100644 index 0000000000..d075549283 --- /dev/null +++ b/include/qapi/qmp/qnull.h @@ -0,0 +1,30 @@ +/* + * QNull + * + * Copyright (C) 2015 Red Hat, Inc. + * + * Authors: + * Markus Armbruster + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 + * or later. See the COPYING.LIB file in the top-level directory. + */ + +#ifndef QNULL_H +#define QNULL_H + +#include "qapi/qmp/qobject.h" + +struct QNull { + QObject base; +}; + +extern QNull qnull_; + +static inline QNull *qnull(void) +{ + QINCREF(&qnull_); + return &qnull_; +} + +#endif /* QNULL_H */ diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index eab29edd12..ef1d1a9237 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -93,16 +93,4 @@ static inline QType qobject_type(const QObject *obj) return obj->type; } =20 -struct QNull { - QObject base; -}; - -extern QNull qnull_; - -static inline QNull *qnull(void) -{ - QINCREF(&qnull_); - return &qnull_; -} - #endif /* QOBJECT_H */ diff --git a/include/qapi/qmp/types.h b/include/qapi/qmp/types.h index a4bc662bfb..749ac44dcb 100644 --- a/include/qapi/qmp/types.h +++ b/include/qapi/qmp/types.h @@ -19,5 +19,6 @@ #include "qapi/qmp/qstring.h" #include "qapi/qmp/qdict.h" #include "qapi/qmp/qlist.h" +#include "qapi/qmp/qnull.h" =20 #endif /* QAPI_QMP_TYPES_H */ diff --git a/qapi/qapi-clone-visitor.c b/qapi/qapi-clone-visitor.c index d8b62792bc..daab6819b4 100644 --- a/qapi/qapi-clone-visitor.c +++ b/qapi/qapi-clone-visitor.c @@ -12,6 +12,7 @@ #include "qapi/clone-visitor.h" #include "qapi/visitor-impl.h" #include "qapi/error.h" +#include "qapi/qmp/qnull.h" =20 struct QapiCloneVisitor { Visitor visitor; diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c index 67a0a4a58b..b3fdd0827d 100644 --- a/qapi/string-input-visitor.c +++ b/qapi/string-input-visitor.c @@ -16,6 +16,7 @@ #include "qapi/string-input-visitor.h" #include "qapi/visitor-impl.h" #include "qapi/qmp/qerror.h" +#include "qapi/qmp/qnull.h" #include "qemu/option.h" #include "qemu/queue.h" #include "qemu/range.h" diff --git a/qobject/qnull.c b/qobject/qnull.c index 69a21d1059..bc9fd31626 100644 --- a/qobject/qnull.c +++ b/qobject/qnull.c @@ -12,7 +12,7 @@ =20 #include "qemu/osdep.h" #include "qemu-common.h" -#include "qapi/qmp/qobject.h" +#include "qapi/qmp/qnull.h" =20 QNull qnull_ =3D { .base =3D { diff --git a/tests/check-qnull.c b/tests/check-qnull.c index 5c6eb0adc8..afa4400da1 100644 --- a/tests/check-qnull.c +++ b/tests/check-qnull.c @@ -8,7 +8,7 @@ */ #include "qemu/osdep.h" =20 -#include "qapi/qmp/qobject.h" +#include "qapi/qmp/qnull.h" #include "qemu-common.h" #include "qapi/qobject-input-visitor.h" #include "qapi/qobject-output-visitor.h" --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943182086657.4678758291013; Fri, 17 Nov 2017 10:26:22 -0800 (PST) Received: from localhost ([::1]:47280 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlLE-0000c2-6x for importer@patchew.org; Fri, 17 Nov 2017 13:26:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42922) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCW-0001Fd-HS for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCV-0002Mr-Ep for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37758) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCR-0002Hb-Pt; Fri, 17 Nov 2017 13:17:11 -0500 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 037B780F79; Fri, 17 Nov 2017 18:17:11 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F6598B11C; Fri, 17 Nov 2017 18:17:09 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:39 +0100 Message-Id: <20171117181653.20651-12-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.27]); Fri, 17 Nov 2017 18:17:11 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 11/25] qapi/qlist: Add qlist_append_null() macro X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Besides the macro itself, this patch also adds a corresponding Coccinelle rule. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Message-id: 20171114180128.17076-3-mreitz@redhat.com Signed-off-by: Max Reitz --- include/qapi/qmp/qlist.h | 3 +++ scripts/coccinelle/qobject.cocci | 3 +++ 2 files changed, 6 insertions(+) diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h index c4b5fdad9b..59d209bbae 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qapi/qmp/qlist.h @@ -15,6 +15,7 @@ =20 #include "qapi/qmp/qobject.h" #include "qapi/qmp/qnum.h" +#include "qapi/qmp/qnull.h" #include "qemu/queue.h" =20 typedef struct QListEntry { @@ -37,6 +38,8 @@ typedef struct QList { qlist_append(qlist, qbool_from_bool(value)) #define qlist_append_str(qlist, value) \ qlist_append(qlist, qstring_from_str(value)) +#define qlist_append_null(qlist) \ + qlist_append(qlist, qnull()) =20 #define QLIST_FOREACH_ENTRY(qlist, var) \ for ((var) =3D ((qlist)->head.tqh_first); \ diff --git a/scripts/coccinelle/qobject.cocci b/scripts/coccinelle/qobject.= cocci index 1120eb1a42..47bcafe9a9 100644 --- a/scripts/coccinelle/qobject.cocci +++ b/scripts/coccinelle/qobject.cocci @@ -41,4 +41,7 @@ expression Obj, E; | - qlist_append(Obj, qstring_from_str(E)); + qlist_append_str(Obj, E); +| +- qlist_append(Obj, qnull()); ++ qlist_append_null(Obj); ) --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943515098150.2728794320086; Fri, 17 Nov 2017 10:31:55 -0800 (PST) Received: from localhost ([::1]:47321 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlQU-0005m7-Nh for importer@patchew.org; Fri, 17 Nov 2017 13:31:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43040) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCZ-0001Jb-Qo for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCX-0002Pj-Fr for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37768) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCS-0002Ig-WD; Fri, 17 Nov 2017 13:17:13 -0500 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 38F40780D0; Fri, 17 Nov 2017 18:17:12 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 52A7C8B11C; Fri, 17 Nov 2017 18:17:11 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:40 +0100 Message-Id: <20171117181653.20651-13-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.27]); Fri, 17 Nov 2017 18:17:12 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 12/25] qapi: Add qobject_is_equal() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz This generic function (along with its implementations for different types) determines whether two QObjects are equal. Signed-off-by: Max Reitz Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Reviewed-by: Markus Armbruster Message-id: 20171114180128.17076-4-mreitz@redhat.com Signed-off-by: Max Reitz --- include/qapi/qmp/qbool.h | 1 + include/qapi/qmp/qdict.h | 1 + include/qapi/qmp/qlist.h | 1 + include/qapi/qmp/qnull.h | 2 ++ include/qapi/qmp/qnum.h | 1 + include/qapi/qmp/qobject.h | 9 ++++++++ include/qapi/qmp/qstring.h | 1 + qobject/qbool.c | 8 +++++++ qobject/qdict.c | 29 +++++++++++++++++++++++++ qobject/qlist.c | 32 +++++++++++++++++++++++++++ qobject/qnull.c | 9 ++++++++ qobject/qnum.c | 54 ++++++++++++++++++++++++++++++++++++++++++= ++++ qobject/qobject.c | 29 +++++++++++++++++++++++++ qobject/qstring.c | 9 ++++++++ 14 files changed, 186 insertions(+) diff --git a/include/qapi/qmp/qbool.h b/include/qapi/qmp/qbool.h index a41111c309..f77ea86c4e 100644 --- a/include/qapi/qmp/qbool.h +++ b/include/qapi/qmp/qbool.h @@ -24,6 +24,7 @@ typedef struct QBool { QBool *qbool_from_bool(bool value); bool qbool_get_bool(const QBool *qb); QBool *qobject_to_qbool(const QObject *obj); +bool qbool_is_equal(const QObject *x, const QObject *y); void qbool_destroy_obj(QObject *obj); =20 #endif /* QBOOL_H */ diff --git a/include/qapi/qmp/qdict.h b/include/qapi/qmp/qdict.h index 7ea5120c4a..fc218e7be6 100644 --- a/include/qapi/qmp/qdict.h +++ b/include/qapi/qmp/qdict.h @@ -43,6 +43,7 @@ void qdict_del(QDict *qdict, const char *key); int qdict_haskey(const QDict *qdict, const char *key); QObject *qdict_get(const QDict *qdict, const char *key); QDict *qobject_to_qdict(const QObject *obj); +bool qdict_is_equal(const QObject *x, const QObject *y); void qdict_iter(const QDict *qdict, void (*iter)(const char *key, QObject *obj, void *opaque), void *opaque); diff --git a/include/qapi/qmp/qlist.h b/include/qapi/qmp/qlist.h index 59d209bbae..ec3fcc1a4c 100644 --- a/include/qapi/qmp/qlist.h +++ b/include/qapi/qmp/qlist.h @@ -61,6 +61,7 @@ QObject *qlist_peek(QList *qlist); int qlist_empty(const QList *qlist); size_t qlist_size(const QList *qlist); QList *qobject_to_qlist(const QObject *obj); +bool qlist_is_equal(const QObject *x, const QObject *y); void qlist_destroy_obj(QObject *obj); =20 static inline const QListEntry *qlist_first(const QList *qlist) diff --git a/include/qapi/qmp/qnull.h b/include/qapi/qmp/qnull.h index d075549283..c992ee2ae1 100644 --- a/include/qapi/qmp/qnull.h +++ b/include/qapi/qmp/qnull.h @@ -27,4 +27,6 @@ static inline QNull *qnull(void) return &qnull_; } =20 +bool qnull_is_equal(const QObject *x, const QObject *y); + #endif /* QNULL_H */ diff --git a/include/qapi/qmp/qnum.h b/include/qapi/qmp/qnum.h index d6b0791139..c3d86794bb 100644 --- a/include/qapi/qmp/qnum.h +++ b/include/qapi/qmp/qnum.h @@ -69,6 +69,7 @@ double qnum_get_double(QNum *qn); char *qnum_to_string(QNum *qn); =20 QNum *qobject_to_qnum(const QObject *obj); +bool qnum_is_equal(const QObject *x, const QObject *y); void qnum_destroy_obj(QObject *obj); =20 #endif /* QNUM_H */ diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h index ef1d1a9237..38ac68845c 100644 --- a/include/qapi/qmp/qobject.h +++ b/include/qapi/qmp/qobject.h @@ -68,6 +68,15 @@ static inline void qobject_incref(QObject *obj) } =20 /** + * qobject_is_equal(): Return whether the two objects are equal. + * + * Any of the pointers may be NULL; return true if both are. Always + * return false if only one is (therefore a QNull object is not + * considered equal to a NULL pointer). + */ +bool qobject_is_equal(const QObject *x, const QObject *y); + +/** * qobject_destroy(): Free resources used by the object */ void qobject_destroy(QObject *obj); diff --git a/include/qapi/qmp/qstring.h b/include/qapi/qmp/qstring.h index 10076b7c8c..65c05a9be5 100644 --- a/include/qapi/qmp/qstring.h +++ b/include/qapi/qmp/qstring.h @@ -31,6 +31,7 @@ void qstring_append_int(QString *qstring, int64_t value); void qstring_append(QString *qstring, const char *str); void qstring_append_chr(QString *qstring, int c); QString *qobject_to_qstring(const QObject *obj); +bool qstring_is_equal(const QObject *x, const QObject *y); void qstring_destroy_obj(QObject *obj); =20 #endif /* QSTRING_H */ diff --git a/qobject/qbool.c b/qobject/qbool.c index 0606bbd2a3..ac825fc5a2 100644 --- a/qobject/qbool.c +++ b/qobject/qbool.c @@ -52,6 +52,14 @@ QBool *qobject_to_qbool(const QObject *obj) } =20 /** + * qbool_is_equal(): Test whether the two QBools are equal + */ +bool qbool_is_equal(const QObject *x, const QObject *y) +{ + return qobject_to_qbool(x)->value =3D=3D qobject_to_qbool(y)->value; +} + +/** * qbool_destroy_obj(): Free all memory allocated by a * QBool object */ diff --git a/qobject/qdict.c b/qobject/qdict.c index 576018e531..e8f15f1132 100644 --- a/qobject/qdict.c +++ b/qobject/qdict.c @@ -403,6 +403,35 @@ void qdict_del(QDict *qdict, const char *key) } =20 /** + * qdict_is_equal(): Test whether the two QDicts are equal + * + * Here, equality means whether they contain the same keys and whether + * the respective values are in turn equal (i.e. invoking + * qobject_is_equal() on them yields true). + */ +bool qdict_is_equal(const QObject *x, const QObject *y) +{ + const QDict *dict_x =3D qobject_to_qdict(x); + const QDict *dict_y =3D qobject_to_qdict(y); + const QDictEntry *e; + + if (qdict_size(dict_x) !=3D qdict_size(dict_y)) { + return false; + } + + for (e =3D qdict_first(dict_x); e; e =3D qdict_next(dict_x, e)) { + const QObject *obj_x =3D qdict_entry_value(e); + const QObject *obj_y =3D qdict_get(dict_y, qdict_entry_key(e)); + + if (!qobject_is_equal(obj_x, obj_y)) { + return false; + } + } + + return true; +} + +/** * qdict_destroy_obj(): Free all the memory allocated by a QDict */ void qdict_destroy_obj(QObject *obj) diff --git a/qobject/qlist.c b/qobject/qlist.c index 86b60cb88c..3ef57d31d1 100644 --- a/qobject/qlist.c +++ b/qobject/qlist.c @@ -140,6 +140,38 @@ QList *qobject_to_qlist(const QObject *obj) } =20 /** + * qlist_is_equal(): Test whether the two QLists are equal + * + * In order to be considered equal, the respective two objects at each + * index of the two lists have to compare equal (regarding + * qobject_is_equal()), and both lists have to have the same number of + * elements. + * That means both lists have to contain equal objects in equal order. + */ +bool qlist_is_equal(const QObject *x, const QObject *y) +{ + const QList *list_x =3D qobject_to_qlist(x); + const QList *list_y =3D qobject_to_qlist(y); + const QListEntry *entry_x, *entry_y; + + entry_x =3D qlist_first(list_x); + entry_y =3D qlist_first(list_y); + + while (entry_x && entry_y) { + if (!qobject_is_equal(qlist_entry_obj(entry_x), + qlist_entry_obj(entry_y))) + { + return false; + } + + entry_x =3D qlist_next(entry_x); + entry_y =3D qlist_next(entry_y); + } + + return !entry_x && !entry_y; +} + +/** * qlist_destroy_obj(): Free all the memory allocated by a QList */ void qlist_destroy_obj(QObject *obj) diff --git a/qobject/qnull.c b/qobject/qnull.c index bc9fd31626..f6f55f11ea 100644 --- a/qobject/qnull.c +++ b/qobject/qnull.c @@ -20,3 +20,12 @@ QNull qnull_ =3D { .refcnt =3D 1, }, }; + +/** + * qnull_is_equal(): Always return true because any two QNull objects + * are equal. + */ +bool qnull_is_equal(const QObject *x, const QObject *y) +{ + return true; +} diff --git a/qobject/qnum.c b/qobject/qnum.c index 476e81c93b..410686a611 100644 --- a/qobject/qnum.c +++ b/qobject/qnum.c @@ -213,6 +213,60 @@ QNum *qobject_to_qnum(const QObject *obj) } =20 /** + * qnum_is_equal(): Test whether the two QNums are equal + * + * Negative integers are never considered equal to unsigned integers, + * but positive integers in the range [0, INT64_MAX] are considered + * equal independently of whether the QNum's kind is i64 or u64. + * + * Doubles are never considered equal to integers. + */ +bool qnum_is_equal(const QObject *x, const QObject *y) +{ + QNum *num_x =3D qobject_to_qnum(x); + QNum *num_y =3D qobject_to_qnum(y); + + switch (num_x->kind) { + case QNUM_I64: + switch (num_y->kind) { + case QNUM_I64: + /* Comparison in native int64_t type */ + return num_x->u.i64 =3D=3D num_y->u.i64; + case QNUM_U64: + /* Implicit conversion of x to uin64_t, so we have to + * check its sign before */ + return num_x->u.i64 >=3D 0 && num_x->u.i64 =3D=3D num_y->u.u64; + case QNUM_DOUBLE: + return false; + } + abort(); + case QNUM_U64: + switch (num_y->kind) { + case QNUM_I64: + return qnum_is_equal(y, x); + case QNUM_U64: + /* Comparison in native uint64_t type */ + return num_x->u.u64 =3D=3D num_y->u.u64; + case QNUM_DOUBLE: + return false; + } + abort(); + case QNUM_DOUBLE: + switch (num_y->kind) { + case QNUM_I64: + case QNUM_U64: + return false; + case QNUM_DOUBLE: + /* Comparison in native double type */ + return num_x->u.dbl =3D=3D num_y->u.dbl; + } + abort(); + } + + abort(); +} + +/** * qnum_destroy_obj(): Free all memory allocated by a * QNum object */ diff --git a/qobject/qobject.c b/qobject/qobject.c index b0cafb66f1..b2a536041d 100644 --- a/qobject/qobject.c +++ b/qobject/qobject.c @@ -27,3 +27,32 @@ void qobject_destroy(QObject *obj) assert(QTYPE_QNULL < obj->type && obj->type < QTYPE__MAX); qdestroy[obj->type](obj); } + + +static bool (*qis_equal[QTYPE__MAX])(const QObject *, const QObject *) =3D= { + [QTYPE_NONE] =3D NULL, /* No such object exists */ + [QTYPE_QNULL] =3D qnull_is_equal, + [QTYPE_QNUM] =3D qnum_is_equal, + [QTYPE_QSTRING] =3D qstring_is_equal, + [QTYPE_QDICT] =3D qdict_is_equal, + [QTYPE_QLIST] =3D qlist_is_equal, + [QTYPE_QBOOL] =3D qbool_is_equal, +}; + +bool qobject_is_equal(const QObject *x, const QObject *y) +{ + /* We cannot test x =3D=3D y because an object does not need to be + * equal to itself (e.g. NaN floats are not). */ + + if (!x && !y) { + return true; + } + + if (!x || !y || x->type !=3D y->type) { + return false; + } + + assert(QTYPE_NONE < x->type && x->type < QTYPE__MAX); + + return qis_equal[x->type](x, y); +} diff --git a/qobject/qstring.c b/qobject/qstring.c index 5da7b5f37c..74182a1c02 100644 --- a/qobject/qstring.c +++ b/qobject/qstring.c @@ -129,6 +129,15 @@ const char *qstring_get_str(const QString *qstring) } =20 /** + * qstring_is_equal(): Test whether the two QStrings are equal + */ +bool qstring_is_equal(const QObject *x, const QObject *y) +{ + return !strcmp(qobject_to_qstring(x)->string, + qobject_to_qstring(y)->string); +} + +/** * qstring_destroy_obj(): Free all memory allocated by a QString * object */ --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510942955736801.6999578717137; Fri, 17 Nov 2017 10:22:35 -0800 (PST) Received: from localhost ([::1]:47254 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlHZ-0005Wp-Qt for importer@patchew.org; Fri, 17 Nov 2017 13:22:29 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42980) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCY-0001Ht-86 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCW-0002Ow-Rt for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:18 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34320) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCU-0002KJ-6v; Fri, 17 Nov 2017 13:17:14 -0500 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 6D993690A; Fri, 17 Nov 2017 18:17:13 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 883F58B11C; Fri, 17 Nov 2017 18:17:12 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:41 +0100 Message-Id: <20171117181653.20651-14-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.39]); Fri, 17 Nov 2017 18:17:13 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 13/25] block: qobject_is_equal() in bdrv_reopen_prepare() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Currently, bdrv_reopen_prepare() assumes that all BDS options are strings. However, this is not the case if the BDS has been created through the json: pseudo-protocol or blockdev-add. Note that the user-invokable reopen command is an HMP command, so you can only specify strings there. Therefore, specifying a non-string option with the "same" value as it was when originally created will now return an error because the values are supposedly similar (and there is no way for the user to circumvent this but to just not specify the option again -- however, this is still strictly better than just crashing). Signed-off-by: Max Reitz Reviewed-by: Eric Blake Message-id: 20171114180128.17076-5-mreitz@redhat.com Signed-off-by: Max Reitz --- block.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/block.c b/block.c index 752fe6192b..70c6d7cf94 100644 --- a/block.c +++ b/block.c @@ -3074,19 +3074,26 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_sta= te, BlockReopenQueue *queue, const QDictEntry *entry =3D qdict_first(reopen_state->options); =20 do { - QString *new_obj =3D qobject_to_qstring(entry->value); - const char *new =3D qstring_get_str(new_obj); + QObject *new =3D entry->value; + QObject *old =3D qdict_get(reopen_state->bs->options, entry->k= ey); + /* - * Caution: while qdict_get_try_str() is fine, getting - * non-string types would require more care. When - * bs->options come from -blockdev or blockdev_add, its - * members are typed according to the QAPI schema, but - * when they come from -drive, they're all QString. + * TODO: When using -drive to specify blockdev options, all va= lues + * will be strings; however, when using -blockdev, blockdev-ad= d or + * filenames using the json:{} pseudo-protocol, they will be + * correctly typed. + * In contrast, reopening options are (currently) always strin= gs + * (because you can only specify them through qemu-io; all oth= er + * callers do not specify any options). + * Therefore, when using anything other than -drive to create = a BDS, + * this cannot detect non-string options as unchanged, because + * qobject_is_equal() always returns false for objects of diff= erent + * type. In the future, this should be remedied by correctly = typing + * all options. For now, this is not too big of an issue beca= use + * the user can simply omit options which cannot be changed an= yway, + * so they will stay unchanged. */ - const char *old =3D qdict_get_try_str(reopen_state->bs->option= s, - entry->key); - - if (!old || strcmp(new, old)) { + if (!qobject_is_equal(new, old)) { error_setg(errp, "Cannot change the option '%s'", entry->k= ey); ret =3D -EINVAL; goto error; --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943139555848.9763388196747; Fri, 17 Nov 2017 10:25:39 -0800 (PST) Received: from localhost ([::1]:47272 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlKS-0008Ld-Uf for importer@patchew.org; Fri, 17 Nov 2017 13:25:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43010) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCZ-0001Il-1T for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCY-0002Qh-6Z for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:19 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34074) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCV-0002M6-Dk; Fri, 17 Nov 2017 13:17:15 -0500 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 A44824C380; Fri, 17 Nov 2017 18:17:14 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id BBD528B11C; Fri, 17 Nov 2017 18:17:13 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:42 +0100 Message-Id: <20171117181653.20651-15-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.25]); Fri, 17 Nov 2017 18:17:14 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 14/25] iotests: Add test for non-string option reopening X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Signed-off-by: Max Reitz Reviewed-by: Kevin Wolf Reviewed-by: Eric Blake Message-id: 20171114180128.17076-6-mreitz@redhat.com Signed-off-by: Max Reitz --- tests/qemu-iotests/133 | 9 +++++++++ tests/qemu-iotests/133.out | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/tests/qemu-iotests/133 b/tests/qemu-iotests/133 index 9d35a6a1ca..af6b3e1dd4 100755 --- a/tests/qemu-iotests/133 +++ b/tests/qemu-iotests/133 @@ -83,6 +83,15 @@ $QEMU_IO -c 'reopen -o driver=3Dqcow2' $TEST_IMG $QEMU_IO -c 'reopen -o file.driver=3Dfile' $TEST_IMG $QEMU_IO -c 'reopen -o backing.driver=3Dqcow2' $TEST_IMG =20 +echo +echo "=3D=3D=3D Check that reopening works with non-string options =3D=3D= =3D" +echo + +# Using the json: pseudo-protocol we can create non-string options +# (Invoke 'info' just so we get some output afterwards) +IMGOPTSSYNTAX=3Dfalse $QEMU_IO -f null-co -c 'reopen' -c 'info' \ + "json:{'driver': 'null-co', 'size': 65536}" + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/133.out b/tests/qemu-iotests/133.out index cc86b94880..f4a85aeb63 100644 --- a/tests/qemu-iotests/133.out +++ b/tests/qemu-iotests/133.out @@ -19,4 +19,9 @@ Cannot change the option 'driver' =20 =3D=3D=3D Check that unchanged driver is okay =3D=3D=3D =20 + +=3D=3D=3D Check that reopening works with non-string options =3D=3D=3D + +format name: null-co +format name: null-co *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943696206687.5631497636871; Fri, 17 Nov 2017 10:34:56 -0800 (PST) Received: from localhost ([::1]:47339 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlTR-0008KB-07 for importer@patchew.org; Fri, 17 Nov 2017 13:34:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43175) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCg-0001Qs-9C for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCe-0002Wk-9y for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52530) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCW-0002Ny-Mk; Fri, 17 Nov 2017 13:17:16 -0500 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 EBD16C05679B; Fri, 17 Nov 2017 18:17:15 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id EFCB311E76F; Fri, 17 Nov 2017 18:17:14 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:43 +0100 Message-Id: <20171117181653.20651-16-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.32]); Fri, 17 Nov 2017 18:17:15 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 15/25] tests: Add check-qobject for equality tests X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Add a new test file (check-qobject.c) for unit tests that concern QObjects as a whole. Its only purpose for now is to test the qobject_is_equal() function. Signed-off-by: Max Reitz Message-id: 20171114180128.17076-7-mreitz@redhat.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- tests/check-qobject.c | 328 +++++++++++++++++++++++++++++++++++++++++++++= ++++ tests/.gitignore | 1 + tests/Makefile.include | 4 +- 3 files changed, 332 insertions(+), 1 deletion(-) create mode 100644 tests/check-qobject.c diff --git a/tests/check-qobject.c b/tests/check-qobject.c new file mode 100644 index 0000000000..03e9175113 --- /dev/null +++ b/tests/check-qobject.c @@ -0,0 +1,328 @@ +/* + * Generic QObject unit-tests. + * + * Copyright (C) 2017 Red Hat Inc. + * + * This work is licensed under the terms of the GNU LGPL, version 2.1 or l= ater. + * See the COPYING.LIB file in the top-level directory. + */ +#include "qemu/osdep.h" + +#include "qapi/qmp/types.h" +#include "qemu-common.h" + +#include + +/* Marks the end of the test_equality() argument list. + * We cannot use NULL there because that is a valid argument. */ +static QObject test_equality_end_of_arguments; + +/** + * Test whether all variadic QObject *arguments are equal (@expected + * is true) or whether they are all not equal (@expected is false). + * Every QObject is tested to be equal to itself (to test + * reflexivity), all tests are done both ways (to test symmetry), and + * transitivity is not assumed but checked (each object is compared to + * every other one). + * + * Note that qobject_is_equal() is not really an equivalence relation, + * so this function may not be used for all objects (reflexivity is + * not guaranteed, e.g. in the case of a QNum containing NaN). + * + * The @_ argument is required because a boolean may not be the last + * argument before a variadic argument list (C11 7.16.1.4 para. 4). + */ +static void do_test_equality(bool expected, int _, ...) +{ + va_list ap_count, ap_extract; + QObject **args; + int arg_count =3D 0; + int i, j; + + va_start(ap_count, _); + va_copy(ap_extract, ap_count); + while (va_arg(ap_count, QObject *) !=3D &test_equality_end_of_argument= s) { + arg_count++; + } + va_end(ap_count); + + args =3D g_new(QObject *, arg_count); + for (i =3D 0; i < arg_count; i++) { + args[i] =3D va_arg(ap_extract, QObject *); + } + va_end(ap_extract); + + for (i =3D 0; i < arg_count; i++) { + g_assert(qobject_is_equal(args[i], args[i]) =3D=3D true); + + for (j =3D i + 1; j < arg_count; j++) { + g_assert(qobject_is_equal(args[i], args[j]) =3D=3D expected); + } + } +} + +#define check_equal(...) \ + do_test_equality(true, 0, __VA_ARGS__, &test_equality_end_of_arguments) +#define check_unequal(...) \ + do_test_equality(false, 0, __VA_ARGS__, &test_equality_end_of_argument= s) + +static void do_free_all(int _, ...) +{ + va_list ap; + QObject *obj; + + va_start(ap, _); + while ((obj =3D va_arg(ap, QObject *)) !=3D NULL) { + qobject_decref(obj); + } + va_end(ap); +} + +#define free_all(...) \ + do_free_all(0, __VA_ARGS__, NULL) + +static void qobject_is_equal_null_test(void) +{ + check_unequal(qnull(), NULL); +} + +static void qobject_is_equal_num_test(void) +{ + QNum *u0, *i0, *d0, *dnan, *um42, *im42, *dm42; + + u0 =3D qnum_from_uint(0u); + i0 =3D qnum_from_int(0); + d0 =3D qnum_from_double(0.0); + dnan =3D qnum_from_double(NAN); + um42 =3D qnum_from_uint((uint64_t)-42); + im42 =3D qnum_from_int(-42); + dm42 =3D qnum_from_double(-42.0); + + /* Integers representing a mathematically equal number should + * compare equal */ + check_equal(u0, i0); + /* Doubles, however, are always unequal to integers */ + check_unequal(u0, d0); + check_unequal(i0, d0); + + /* Do not assume any object is equal to itself -- note however + * that NaN cannot occur in a JSON object anyway. */ + g_assert(qobject_is_equal(QOBJECT(dnan), QOBJECT(dnan)) =3D=3D false); + + /* No unsigned overflow */ + check_unequal(um42, im42); + check_unequal(um42, dm42); + check_unequal(im42, dm42); + + free_all(u0, i0, d0, dnan, um42, im42, dm42); +} + +static void qobject_is_equal_bool_test(void) +{ + QBool *btrue_0, *btrue_1, *bfalse_0, *bfalse_1; + + btrue_0 =3D qbool_from_bool(true); + btrue_1 =3D qbool_from_bool(true); + bfalse_0 =3D qbool_from_bool(false); + bfalse_1 =3D qbool_from_bool(false); + + check_equal(btrue_0, btrue_1); + check_equal(bfalse_0, bfalse_1); + check_unequal(btrue_0, bfalse_0); + + free_all(btrue_0, btrue_1, bfalse_0, bfalse_1); +} + +static void qobject_is_equal_string_test(void) +{ + QString *str_base, *str_whitespace_0, *str_whitespace_1, *str_whitespa= ce_2; + QString *str_whitespace_3, *str_case, *str_built; + + str_base =3D qstring_from_str("foo"); + str_whitespace_0 =3D qstring_from_str(" foo"); + str_whitespace_1 =3D qstring_from_str("foo "); + str_whitespace_2 =3D qstring_from_str("foo\b"); + str_whitespace_3 =3D qstring_from_str("fooo\b"); + str_case =3D qstring_from_str("Foo"); + + /* Should yield "foo" */ + str_built =3D qstring_from_substr("form", 0, 1); + qstring_append_chr(str_built, 'o'); + + check_unequal(str_base, str_whitespace_0, str_whitespace_1, + str_whitespace_2, str_whitespace_3, str_case); + + check_equal(str_base, str_built); + + free_all(str_base, str_whitespace_0, str_whitespace_1, str_whitespace_= 2, + str_whitespace_3, str_case, str_built); +} + +static void qobject_is_equal_list_test(void) +{ + QList *list_0, *list_1, *list_cloned; + QList *list_reordered, *list_longer, *list_shorter; + + list_0 =3D qlist_new(); + list_1 =3D qlist_new(); + list_reordered =3D qlist_new(); + list_longer =3D qlist_new(); + list_shorter =3D qlist_new(); + + qlist_append_int(list_0, 1); + qlist_append_int(list_0, 2); + qlist_append_int(list_0, 3); + + qlist_append_int(list_1, 1); + qlist_append_int(list_1, 2); + qlist_append_int(list_1, 3); + + qlist_append_int(list_reordered, 1); + qlist_append_int(list_reordered, 3); + qlist_append_int(list_reordered, 2); + + qlist_append_int(list_longer, 1); + qlist_append_int(list_longer, 2); + qlist_append_int(list_longer, 3); + qlist_append_null(list_longer); + + qlist_append_int(list_shorter, 1); + qlist_append_int(list_shorter, 2); + + list_cloned =3D qlist_copy(list_0); + + check_equal(list_0, list_1, list_cloned); + check_unequal(list_0, list_reordered, list_longer, list_shorter); + + /* With a NaN in it, the list should no longer compare equal to + * itself */ + qlist_append(list_0, qnum_from_double(NAN)); + g_assert(qobject_is_equal(QOBJECT(list_0), QOBJECT(list_0)) =3D=3D fal= se); + + free_all(list_0, list_1, list_cloned, list_reordered, list_longer, + list_shorter); +} + +static void qobject_is_equal_dict_test(void) +{ + Error *local_err =3D NULL; + QDict *dict_0, *dict_1, *dict_cloned; + QDict *dict_different_key, *dict_different_value, *dict_different_null= _key; + QDict *dict_longer, *dict_shorter, *dict_nested; + QDict *dict_crumpled; + + dict_0 =3D qdict_new(); + dict_1 =3D qdict_new(); + dict_different_key =3D qdict_new(); + dict_different_value =3D qdict_new(); + dict_different_null_key =3D qdict_new(); + dict_longer =3D qdict_new(); + dict_shorter =3D qdict_new(); + dict_nested =3D qdict_new(); + + qdict_put_int(dict_0, "f.o", 1); + qdict_put_int(dict_0, "bar", 2); + qdict_put_int(dict_0, "baz", 3); + qdict_put_null(dict_0, "null"); + + qdict_put_int(dict_1, "f.o", 1); + qdict_put_int(dict_1, "bar", 2); + qdict_put_int(dict_1, "baz", 3); + qdict_put_null(dict_1, "null"); + + qdict_put_int(dict_different_key, "F.o", 1); + qdict_put_int(dict_different_key, "bar", 2); + qdict_put_int(dict_different_key, "baz", 3); + qdict_put_null(dict_different_key, "null"); + + qdict_put_int(dict_different_value, "f.o", 42); + qdict_put_int(dict_different_value, "bar", 2); + qdict_put_int(dict_different_value, "baz", 3); + qdict_put_null(dict_different_value, "null"); + + qdict_put_int(dict_different_null_key, "f.o", 1); + qdict_put_int(dict_different_null_key, "bar", 2); + qdict_put_int(dict_different_null_key, "baz", 3); + qdict_put_null(dict_different_null_key, "none"); + + qdict_put_int(dict_longer, "f.o", 1); + qdict_put_int(dict_longer, "bar", 2); + qdict_put_int(dict_longer, "baz", 3); + qdict_put_int(dict_longer, "xyz", 4); + qdict_put_null(dict_longer, "null"); + + qdict_put_int(dict_shorter, "f.o", 1); + qdict_put_int(dict_shorter, "bar", 2); + qdict_put_int(dict_shorter, "baz", 3); + + qdict_put(dict_nested, "f", qdict_new()); + qdict_put_int(qdict_get_qdict(dict_nested, "f"), "o", 1); + qdict_put_int(dict_nested, "bar", 2); + qdict_put_int(dict_nested, "baz", 3); + qdict_put_null(dict_nested, "null"); + + dict_cloned =3D qdict_clone_shallow(dict_0); + + check_equal(dict_0, dict_1, dict_cloned); + check_unequal(dict_0, dict_different_key, dict_different_value, + dict_different_null_key, dict_longer, dict_shorter, + dict_nested); + + dict_crumpled =3D qobject_to_qdict(qdict_crumple(dict_1, &local_err)); + g_assert(!local_err); + check_equal(dict_crumpled, dict_nested); + + qdict_flatten(dict_nested); + check_equal(dict_0, dict_nested); + + /* Containing an NaN value will make this dict compare unequal to + * itself */ + qdict_put(dict_0, "NaN", qnum_from_double(NAN)); + g_assert(qobject_is_equal(QOBJECT(dict_0), QOBJECT(dict_0)) =3D=3D fal= se); + + free_all(dict_0, dict_1, dict_cloned, dict_different_key, + dict_different_value, dict_different_null_key, dict_longer, + dict_shorter, dict_nested, dict_crumpled); +} + +static void qobject_is_equal_conversion_test(void) +{ + QNum *u0, *i0, *d0; + QString *s0, *s_empty; + QBool *bfalse; + + u0 =3D qnum_from_uint(0u); + i0 =3D qnum_from_int(0); + d0 =3D qnum_from_double(0.0); + s0 =3D qstring_from_str("0"); + s_empty =3D qstring_new(); + bfalse =3D qbool_from_bool(false); + + /* No automatic type conversion */ + check_unequal(u0, s0, s_empty, bfalse, qnull(), NULL); + check_unequal(i0, s0, s_empty, bfalse, qnull(), NULL); + check_unequal(d0, s0, s_empty, bfalse, qnull(), NULL); + + free_all(u0, i0, d0, s0, s_empty, bfalse); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/public/qobject_is_equal_null", + qobject_is_equal_null_test); + g_test_add_func("/public/qobject_is_equal_num", qobject_is_equal_num_t= est); + g_test_add_func("/public/qobject_is_equal_bool", + qobject_is_equal_bool_test); + g_test_add_func("/public/qobject_is_equal_string", + qobject_is_equal_string_test); + g_test_add_func("/public/qobject_is_equal_list", + qobject_is_equal_list_test); + g_test_add_func("/public/qobject_is_equal_dict", + qobject_is_equal_dict_test); + g_test_add_func("/public/qobject_is_equal_conversion", + qobject_is_equal_conversion_test); + + return g_test_run(); +} diff --git a/tests/.gitignore b/tests/.gitignore index 53cb2efaee..74e55d7264 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -8,6 +8,7 @@ check-qjson check-qlist check-qlit check-qnull +check-qobject check-qstring check-qom-interface check-qom-proplist diff --git a/tests/Makefile.include b/tests/Makefile.include index 434a2ce868..c002352134 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -41,6 +41,7 @@ check-unit-y +=3D tests/check-qlist$(EXESUF) gcov-files-check-qlist-y =3D qobject/qlist.c check-unit-y +=3D tests/check-qnull$(EXESUF) gcov-files-check-qnull-y =3D qobject/qnull.c +check-unit-y +=3D tests/check-qobject$(EXESUF) check-unit-y +=3D tests/check-qjson$(EXESUF) gcov-files-check-qjson-y =3D qobject/qjson.c check-unit-y +=3D tests/check-qlit$(EXESUF) @@ -546,7 +547,7 @@ GENERATED_FILES +=3D tests/test-qapi-types.h tests/test= -qapi-visit.h \ tests/test-qmp-introspect.h =20 test-obj-y =3D tests/check-qnum.o tests/check-qstring.o tests/check-qdict.= o \ - tests/check-qlist.o tests/check-qnull.o \ + tests/check-qlist.o tests/check-qnull.o tests/check-qobject.o \ tests/check-qjson.o tests/check-qlit.o \ tests/test-coroutine.o tests/test-string-output-visitor.o \ tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \ @@ -580,6 +581,7 @@ tests/check-qstring$(EXESUF): tests/check-qstring.o $(t= est-util-obj-y) tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y) tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y) tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y) +tests/check-qobject$(EXESUF): tests/check-qobject.o $(test-util-obj-y) tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y) tests/check-qlit$(EXESUF): tests/check-qlit.o $(test-util-obj-y) tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom= -obj-y) --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 151094336449792.04788142866164; Fri, 17 Nov 2017 10:29:24 -0800 (PST) Received: from localhost ([::1]:47299 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlO5-0003Ps-IL for importer@patchew.org; Fri, 17 Nov 2017 13:29:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43140) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCf-0001Pa-8d for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCe-0002Wa-7y for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:25 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52560) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCX-0002PX-VQ; Fri, 17 Nov 2017 13:17:18 -0500 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 2BB45C045753; Fri, 17 Nov 2017 18:17:17 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 421AD8B11C; Fri, 17 Nov 2017 18:17:16 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:44 +0100 Message-Id: <20171117181653.20651-17-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.32]); Fri, 17 Nov 2017 18:17:17 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 16/25] iotests: Add test for failing qemu-img commit X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Signed-off-by: Max Reitz Message-id: 20170616135847.17726-1-mreitz@redhat.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- tests/qemu-iotests/020 | 27 +++++++++++++++++++++++++++ tests/qemu-iotests/020.out | 17 +++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020 index 7a111100ec..cefe3a830e 100755 --- a/tests/qemu-iotests/020 +++ b/tests/qemu-iotests/020 @@ -110,6 +110,33 @@ for offset in $TEST_OFFSETS; do io_zero readv $(( offset + 64 * 1024 + 65536 * 4 )) 65536 65536 1 done _check_test_img +_cleanup +TEST_IMG=3D$TEST_IMG_SAVE + +echo +echo 'Testing failing commit' +echo + +# Create an image with a null backing file to which committing will fail (= with +# ENOSPC so we can distinguish the result from some generic EIO which may = be +# generated anywhere in the block layer) +_make_test_img -b "json:{'driver': 'raw', + 'file': { + 'driver': 'blkdebug', + 'inject-error': [{ + 'event': 'write_aio', + 'errno': 28, + 'once': true + }], + 'image': { + 'driver': 'null-co' + }}}" + +# Just write anything so committing will not be a no-op +$QEMU_IO -c 'writev 0 64k' "$TEST_IMG" | _filter_qemu_io + +$QEMU_IMG commit "$TEST_IMG" +_cleanup_test_img =20 # success, all done echo "*** done" diff --git a/tests/qemu-iotests/020.out b/tests/qemu-iotests/020.out index 42f6c1b151..165b70aa49 100644 --- a/tests/qemu-iotests/020.out +++ b/tests/qemu-iotests/020.out @@ -1075,4 +1075,21 @@ read 65536/65536 bytes at offset 4295098368 read 65536/65536 bytes at offset 4295294976 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) No errors were found on the image. + +Testing failing commit + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D1073741824 backing_fil= e=3Djson:{'driver': 'raw',, + 'file': { + 'driver': 'blkdebug',, + 'inject-error': [{ + 'event': 'write_aio',, + 'errno': 28,, + 'once': true + }],, + 'image': { + 'driver': 'null-co' + }}} +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qemu-img: Block job failed: No space left on device *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943296498337.4596418200093; Fri, 17 Nov 2017 10:28:16 -0800 (PST) Received: from localhost ([::1]:47296 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlN4-0002XM-6y for importer@patchew.org; Fri, 17 Nov 2017 13:28:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43168) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCg-0001QW-22 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCf-0002XP-7l for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37174) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCZ-0002RP-6F; Fri, 17 Nov 2017 13:17:19 -0500 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 5D14C4900A; Fri, 17 Nov 2017 18:17:18 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 772C38B11C; Fri, 17 Nov 2017 18:17:17 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:45 +0100 Message-Id: <20171117181653.20651-18-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.38]); Fri, 17 Nov 2017 18:17:18 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 17/25] qcow2: reject unaligned offsets in write compressed X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Anton Nefedov Misaligned compressed write is not supported. Signed-off-by: Anton Nefedov Message-id: 1510654613-47868-2-git-send-email-anton.nefedov@virtuozzo.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- block/qcow2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/block/qcow2.c b/block/qcow2.c index f2731a7cb5..811b913233 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3358,6 +3358,10 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, ui= nt64_t offset, return bdrv_truncate(bs->file, cluster_offset, PREALLOC_MODE_OFF, = NULL); } =20 + if (offset_into_cluster(s, offset)) { + return -EINVAL; + } + buf =3D qemu_blockalign(bs, s->cluster_size); if (bytes !=3D s->cluster_size) { if (bytes > s->cluster_size || --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 151094387279857.87076813066801; Fri, 17 Nov 2017 10:37:52 -0800 (PST) Received: from localhost ([::1]:47364 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlWA-0002HW-Jt for importer@patchew.org; Fri, 17 Nov 2017 13:37:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43204) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCg-0001S5-UY for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCf-0002Xw-Jg for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41708) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCa-0002Ss-BK; Fri, 17 Nov 2017 13:17:20 -0500 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 92D007EAAA; Fri, 17 Nov 2017 18:17:19 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id AE3C611E7EC; Fri, 17 Nov 2017 18:17:18 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:46 +0100 Message-Id: <20171117181653.20651-19-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.28]); Fri, 17 Nov 2017 18:17:19 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 18/25] qcow2: check_errors are fatal X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz When trying to repair a dirty image, qcow2_check() may apparently succeed (no really fatal error occurred that would prevent the check from continuing), but if check_errors in the result object is non-zero, we cannot trust the image to be usable. Reported-by: R. Nageswara Sastry Buglink: https://bugs.launchpad.net/qemu/+bug/1728639 Signed-off-by: Max Reitz Message-id: 20171110203111.7666-2-mreitz@redhat.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- block/qcow2.c | 5 ++++- tests/qemu-iotests/060 | 20 ++++++++++++++++++++ tests/qemu-iotests/060.out | 23 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/block/qcow2.c b/block/qcow2.c index 811b913233..1914a940e5 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1477,7 +1477,10 @@ static int qcow2_do_open(BlockDriverState *bs, QDict= *options, int flags, BdrvCheckResult result =3D {0}; =20 ret =3D qcow2_check(bs, &result, BDRV_FIX_ERRORS | BDRV_FIX_LEAKS); - if (ret < 0) { + if (ret < 0 || result.check_errors) { + if (ret >=3D 0) { + ret =3D -EIO; + } error_setg_errno(errp, -ret, "Could not repair dirty image"); goto fail; } diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index fae08b03bf..56bdf1ee2e 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -301,6 +301,26 @@ _make_test_img 64M poke_file "$TEST_IMG" "48" "\x00\x00\x00\x00\x00\x00\x00\x0= 0" $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io =20 +echo +echo "=3D=3D=3D Testing dirty corrupt image =3D=3D=3D" +echo + +_make_test_img 64M + +# Let the refblock appear unaligned +poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\xff\xff\x2a\x0= 0" +# Mark the image dirty, thus forcing an automatic check when opening it +poke_file "$TEST_IMG" 72 "\x00\x00\x00\x00\x00\x00\x00\x01" +# Open the image (qemu should refuse to do so) +$QEMU_IO -c close "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt + +echo '--- Repairing ---' + +# The actual repair should have happened (because of the dirty bit), +# but some cleanup may have failed (like freeing the old reftable) +# because the image was already marked corrupt by that point +_check_test_img -r all + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index 62c22701b8..f013fe73c0 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -284,4 +284,27 @@ No errors were found on the image. Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 qcow2: Marking image as corrupt: Preventing invalid allocation of L2 table= at offset 0; further corruption events will be suppressed write failed: Input/output error + +=3D=3D=3D Testing dirty corrupt image =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +ERROR refcount block 0 is not cluster aligned; refcount table entry corrup= ted +IMGFMT: Marking image as corrupt: Refblock offset 0xffff2a00 unaligned (re= ftable index: 0); further corruption events will be suppressed +Can't get refcount for cluster 0: Input/output error +Can't get refcount for cluster 1: Input/output error +Can't get refcount for cluster 2: Input/output error +Can't get refcount for cluster 3: Input/output error +Rebuilding refcount structure +Repairing cluster 1 refcount=3D1 reference=3D0 +can't open device TEST_DIR/t.IMGFMT: Could not repair dirty image: Input/o= utput error +--- Repairing --- +Leaked cluster 1 refcount=3D1 reference=3D0 +Repairing cluster 1 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 1 leaked clusters + 0 corruptions + +Double checking the fixed image now... +No errors were found on the image. *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15109435203431.3598189052402176; Fri, 17 Nov 2017 10:32:00 -0800 (PST) Received: from localhost ([::1]:47322 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlQf-0005wW-FN for importer@patchew.org; Fri, 17 Nov 2017 13:31:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43195) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCg-0001Rp-Mn for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCf-0002Xj-FJ for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52674) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCb-0002Ty-LR; Fri, 17 Nov 2017 13:17:21 -0500 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 C8587C05679B; Fri, 17 Nov 2017 18:17:20 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id E22F111E76F; Fri, 17 Nov 2017 18:17:19 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:47 +0100 Message-Id: <20171117181653.20651-20-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.32]); Fri, 17 Nov 2017 18:17:20 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 19/25] qcow2: Unaligned zero cluster in handle_alloc() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz We should check whether the cluster offset we are about to use is actually valid; that is, whether it is aligned to cluster boundaries. Reported-by: R. Nageswara Sastry Buglink: https://bugs.launchpad.net/qemu/+bug/1728643 Buglink: https://bugs.launchpad.net/qemu/+bug/1728657 Signed-off-by: Max Reitz Message-id: 20171110203111.7666-3-mreitz@redhat.com Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Signed-off-by: Max Reitz --- block/qcow2-cluster.c | 13 ++++++++++++- tests/qemu-iotests/060 | 16 ++++++++++++++++ tests/qemu-iotests/060.out | 10 ++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 2e072ed155..a3fec27bf9 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1308,10 +1308,21 @@ static int handle_alloc(BlockDriverState *bs, uint6= 4_t guest_offset, (!*host_offset || start_of_cluster(s, *host_offset) =3D=3D (entry & L2E_OFFSET_MASK= ))) { + int preallocated_nb_clusters; + + if (offset_into_cluster(s, entry & L2E_OFFSET_MASK)) { + qcow2_signal_corruption(bs, true, -1, -1, "Preallocated zero " + "cluster offset %#llx unaligned (guest= " + "offset: %#" PRIx64 ")", + entry & L2E_OFFSET_MASK, guest_offset); + ret =3D -EIO; + goto fail; + } + /* Try to reuse preallocated zero clusters; contiguous normal clus= ters * would be fine, too, but count_cow_clusters() above has limited * nb_clusters already to a range of COW clusters */ - int preallocated_nb_clusters =3D + preallocated_nb_clusters =3D count_contiguous_clusters(nb_clusters, s->cluster_size, &l2_table[l2_index], QCOW_OFLAG_COPI= ED); assert(preallocated_nb_clusters > 0); diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index 56bdf1ee2e..49bc89df38 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -321,6 +321,22 @@ echo '--- Repairing ---' # because the image was already marked corrupt by that point _check_test_img -r all =20 +echo +echo "=3D=3D=3D Writing to an unaligned preallocated zero cluster =3D=3D= =3D" +echo + +_make_test_img 64M + +# Allocate the L2 table +$QEMU_IO -c "write 0 64k" -c "discard 0 64k" "$TEST_IMG" | _filter_qemu_io +# Pretend there is a preallocated zero cluster somewhere inside the +# image header +poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x00\x2a\x01" +# Let's write to it! +$QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io + +# Can't repair this yet (TODO: We can just deallocate the cluster) + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index f013fe73c0..c583076808 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -307,4 +307,14 @@ The following inconsistencies were found and repaired: =20 Double checking the fixed image now... No errors were found on the image. + +=3D=3D=3D Writing to an unaligned preallocated zero cluster =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +discard 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 u= naligned (guest offset: 0); further corruption events will be suppressed +write failed: Input/output error *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943540080716.5897218606747; Fri, 17 Nov 2017 10:32:20 -0800 (PST) Received: from localhost ([::1]:47323 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlQq-000658-3e for importer@patchew.org; Fri, 17 Nov 2017 13:32:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43265) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCj-0001UY-K8 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCh-0002Zc-By for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41746) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCc-0002VB-U7; Fri, 17 Nov 2017 13:17:23 -0500 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 2440B7EAB7; Fri, 17 Nov 2017 18:17:22 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 23F2A11E76F; Fri, 17 Nov 2017 18:17:20 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:48 +0100 Message-Id: <20171117181653.20651-21-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.28]); Fri, 17 Nov 2017 18:17:22 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 20/25] block: Guard against NULL bs->drv X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz We currently do not guard everywhere against a NULL bs->drv where we should be doing so. Most of the places fixed here just do not care about that case at all. Some care implicitly, e.g. through a prior function call to bdrv_getlength() which would always fail for an ejected BDS. Add an assert there to make it more obvious. Other places seem to care, but do so insufficiently: Freeing clusters in a qcow2 image is an error-free operation, but it may leave the image in an unusable state anyway. Giving qcow2_free_clusters() an error code is not really viable, it is much easier to note that bs->drv may be NULL even after a successful driver call. This concerns bdrv_co_flush(), and the way the check is added to bdrv_co_pdiscard() (in every iteration instead of only once). Finally, some places employ at least an assert(bs->drv); somewhere, that may be reasonable (such as in the reopen code), but in bdrv_has_zero_init(), it is definitely not. Returning 0 there in case of an ejected BDS saves us much headache instead. Reported-by: R. Nageswara Sastry Buglink: https://bugs.launchpad.net/qemu/+bug/1728660 Signed-off-by: Max Reitz Message-id: 20171110203111.7666-4-mreitz@redhat.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- block.c | 19 ++++++++++++++++++- block/io.c | 36 ++++++++++++++++++++++++++++++++++++ block/qapi.c | 8 +++++++- block/replication.c | 15 +++++++++++++++ block/vvfat.c | 2 +- tests/qemu-iotests/060 | 22 ++++++++++++++++++++++ tests/qemu-iotests/060.out | 31 +++++++++++++++++++++++++++++++ 7 files changed, 130 insertions(+), 3 deletions(-) diff --git a/block.c b/block.c index 70c6d7cf94..996778cfa0 100644 --- a/block.c +++ b/block.c @@ -720,6 +720,10 @@ static int refresh_total_sectors(BlockDriverState *bs,= int64_t hint) { BlockDriver *drv =3D bs->drv; =20 + if (!drv) { + return -ENOMEDIUM; + } + /* Do not attempt drv->bdrv_getlength() on scsi-generic devices */ if (bdrv_is_sg(bs)) return 0; @@ -3431,6 +3435,10 @@ int bdrv_change_backing_file(BlockDriverState *bs, BlockDriver *drv =3D bs->drv; int ret; =20 + if (!drv) { + return -ENOMEDIUM; + } + /* Backing file format doesn't make sense without a backing file */ if (backing_fmt && !backing_file) { return -EINVAL; @@ -3916,7 +3924,9 @@ int bdrv_has_zero_init_1(BlockDriverState *bs) =20 int bdrv_has_zero_init(BlockDriverState *bs) { - assert(bs->drv); + if (!bs->drv) { + return 0; + } =20 /* If BS is a copy on write image, it is initialized to the contents of the base image, which may not be zeroes. */ @@ -4256,6 +4266,10 @@ static int bdrv_inactivate_recurse(BlockDriverState = *bs, BdrvChild *child, *parent; int ret; =20 + if (!bs->drv) { + return -ENOMEDIUM; + } + if (!setting_flag && bs->drv->bdrv_inactivate) { ret =3D bs->drv->bdrv_inactivate(bs); if (ret < 0) { @@ -4790,6 +4804,9 @@ void bdrv_remove_aio_context_notifier(BlockDriverStat= e *bs, int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts, BlockDriverAmendStatusCB *status_cb, void *cb_opaqu= e) { + if (!bs->drv) { + return -ENOMEDIUM; + } if (!bs->drv->bdrv_amend_options) { return -ENOTSUP; } diff --git a/block/io.c b/block/io.c index 3d5ef2cabe..4fdf93a014 100644 --- a/block/io.c +++ b/block/io.c @@ -853,6 +853,10 @@ static int coroutine_fn bdrv_driver_preadv(BlockDriver= State *bs, =20 assert(!(flags & ~BDRV_REQ_MASK)); =20 + if (!drv) { + return -ENOMEDIUM; + } + if (drv->bdrv_co_preadv) { return drv->bdrv_co_preadv(bs, offset, bytes, qiov, flags); } @@ -894,6 +898,10 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDrive= rState *bs, =20 assert(!(flags & ~BDRV_REQ_MASK)); =20 + if (!drv) { + return -ENOMEDIUM; + } + if (drv->bdrv_co_pwritev) { ret =3D drv->bdrv_co_pwritev(bs, offset, bytes, qiov, flags & bs->supported_write_flags); @@ -945,6 +953,10 @@ bdrv_driver_pwritev_compressed(BlockDriverState *bs, u= int64_t offset, { BlockDriver *drv =3D bs->drv; =20 + if (!drv) { + return -ENOMEDIUM; + } + if (!drv->bdrv_co_pwritev_compressed) { return -ENOTSUP; } @@ -975,6 +987,10 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvC= hild *child, BDRV_REQUEST_MAX_BYTES); unsigned int progress =3D 0; =20 + if (!drv) { + return -ENOMEDIUM; + } + /* FIXME We cannot require callers to have write permissions when all = they * are doing is a read request. If we did things right, write permissi= ons * would be obtained anyway, but internally by the copy-on-read code. = As @@ -1291,6 +1307,10 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(Blo= ckDriverState *bs, bs->bl.request_alignment); int max_transfer =3D MIN_NON_ZERO(bs->bl.max_transfer, MAX_BOUNCE_BUFF= ER); =20 + if (!drv) { + return -ENOMEDIUM; + } + assert(alignment % bs->bl.request_alignment =3D=3D 0); head =3D offset % alignment; tail =3D (offset + bytes) % alignment; @@ -1397,6 +1417,10 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChi= ld *child, uint64_t bytes_remaining =3D bytes; int max_transfer; =20 + if (!drv) { + return -ENOMEDIUM; + } + if (bdrv_has_readonly_bitmaps(bs)) { return -EPERM; } @@ -1863,6 +1887,8 @@ static int coroutine_fn bdrv_co_block_status(BlockDri= verState *bs, bytes =3D n; } =20 + /* Must be non-NULL or bdrv_getlength() would have failed */ + assert(bs->drv); if (!bs->drv->bdrv_co_get_block_status) { *pnum =3D bytes; ret =3D BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED; @@ -2373,6 +2399,12 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs) } =20 BLKDBG_EVENT(bs->file, BLKDBG_FLUSH_TO_DISK); + if (!bs->drv) { + /* bs->drv->bdrv_co_flush() might have ejected the BDS + * (even in case of apparent success) */ + ret =3D -ENOMEDIUM; + goto out; + } if (bs->drv->bdrv_co_flush_to_disk) { ret =3D bs->drv->bdrv_co_flush_to_disk(bs); } else if (bs->drv->bdrv_aio_flush) { @@ -2542,6 +2574,10 @@ int coroutine_fn bdrv_co_pdiscard(BlockDriverState *= bs, int64_t offset, num =3D max_pdiscard; } =20 + if (!bs->drv) { + ret =3D -ENOMEDIUM; + goto out; + } if (bs->drv->bdrv_co_pdiscard) { ret =3D bs->drv->bdrv_co_pdiscard(bs, offset, num); } else { diff --git a/block/qapi.c b/block/qapi.c index 7fa2437923..fc10f0a565 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -39,8 +39,14 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *bl= k, { ImageInfo **p_image_info; BlockDriverState *bs0; - BlockDeviceInfo *info =3D g_malloc0(sizeof(*info)); + BlockDeviceInfo *info; =20 + if (!bs->drv) { + error_setg(errp, "Block device %s is ejected", bs->node_name); + return NULL; + } + + info =3D g_malloc0(sizeof(*info)); info->file =3D g_strdup(bs->filename); info->ro =3D bs->read_only; info->drv =3D g_strdup(bs->drv->format_name); diff --git a/block/replication.c b/block/replication.c index 1c95d673ff..e41e293d2b 100644 --- a/block/replication.c +++ b/block/replication.c @@ -342,12 +342,24 @@ static void secondary_do_checkpoint(BDRVReplicationSt= ate *s, Error **errp) return; } =20 + if (!s->active_disk->bs->drv) { + error_setg(errp, "Active disk %s is ejected", + s->active_disk->bs->node_name); + return; + } + ret =3D s->active_disk->bs->drv->bdrv_make_empty(s->active_disk->bs); if (ret < 0) { error_setg(errp, "Cannot make active disk empty"); return; } =20 + if (!s->hidden_disk->bs->drv) { + error_setg(errp, "Hidden disk %s is ejected", + s->hidden_disk->bs->node_name); + return; + } + ret =3D s->hidden_disk->bs->drv->bdrv_make_empty(s->hidden_disk->bs); if (ret < 0) { error_setg(errp, "Cannot make hidden disk empty"); @@ -511,6 +523,9 @@ static void replication_start(ReplicationState *rs, Rep= licationMode mode, return; } =20 + /* Must be true, or the bdrv_getlength() calls would have failed */ + assert(s->active_disk->bs->drv && s->hidden_disk->bs->drv); + if (!s->active_disk->bs->drv->bdrv_make_empty || !s->hidden_disk->bs->drv->bdrv_make_empty) { error_setg(errp, diff --git a/block/vvfat.c b/block/vvfat.c index 0841cc42fc..a690595f2c 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2947,7 +2947,7 @@ static int do_commit(BDRVVVFATState* s) return ret; } =20 - if (s->qcow->bs->drv->bdrv_make_empty) { + if (s->qcow->bs->drv && s->qcow->bs->drv->bdrv_make_empty) { s->qcow->bs->drv->bdrv_make_empty(s->qcow->bs); } =20 diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index 49bc89df38..44141f6243 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -337,6 +337,28 @@ $QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io =20 # Can't repair this yet (TODO: We can just deallocate the cluster) =20 +echo +echo '=3D=3D=3D Discarding with an unaligned refblock =3D=3D=3D' +echo + +_make_test_img 64M + +$QEMU_IO -c "write 0 128k" "$TEST_IMG" | _filter_qemu_io +# Make our refblock unaligned +poke_file "$TEST_IMG" "$(($rt_offset))" "\x00\x00\x00\x00\x00\x00\x2a\x00" +# Now try to discard something that will be submitted as two requests +# (main part + tail) +$QEMU_IO -c "discard 0 65537" "$TEST_IMG" + +echo '--- Repairing ---' +# Fails the first repair because the corruption prevents the check +# function from double-checking +# (Using -q for the first invocation, because otherwise the +# double-check error message appears above the summary for some +# reason -- so let's just hide the summary) +_check_test_img -q -r all +_check_test_img -r all + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index c583076808..07dfdcac99 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -317,4 +317,35 @@ discard 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 u= naligned (guest offset: 0); further corruption events will be suppressed write failed: Input/output error + +=3D=3D=3D Discarding with an unaligned refblock =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +wrote 131072/131072 bytes at offset 0 +128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qcow2: Marking image as corrupt: Refblock offset 0x2a00 unaligned (reftabl= e index: 0); further corruption events will be suppressed +qcow2_free_clusters failed: Input/output error +discard failed: No medium found +--- Repairing --- +ERROR refcount block 0 is not cluster aligned; refcount table entry corrup= ted +qcow2: Marking image as corrupt: Refblock offset 0x2a00 unaligned (reftabl= e index: 0); further corruption events will be suppressed +Can't get refcount for cluster 0: Input/output error +Can't get refcount for cluster 1: Input/output error +Can't get refcount for cluster 2: Input/output error +Can't get refcount for cluster 3: Input/output error +Can't get refcount for cluster 4: Input/output error +Can't get refcount for cluster 5: Input/output error +Can't get refcount for cluster 6: Input/output error +Rebuilding refcount structure +Repairing cluster 1 refcount=3D1 reference=3D0 +qemu-img: Check failed: No medium found +Leaked cluster 1 refcount=3D1 reference=3D0 +Repairing cluster 1 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 1 leaked clusters + 0 corruptions + +Double checking the fixed image now... +No errors were found on the image. *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943486575467.03955555653397; Fri, 17 Nov 2017 10:31:26 -0800 (PST) Received: from localhost ([::1]:47319 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlPw-0005Jn-Ks for importer@patchew.org; Fri, 17 Nov 2017 13:31:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43257) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCj-0001Tq-3x for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCh-0002Zp-G9 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:58114) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCe-0002Vu-5y; Fri, 17 Nov 2017 13:17:24 -0500 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 568D5267D8; Fri, 17 Nov 2017 18:17:23 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id 722678B11C; Fri, 17 Nov 2017 18:17:22 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:49 +0100 Message-Id: <20171117181653.20651-22-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.30]); Fri, 17 Nov 2017 18:17:23 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 21/25] qcow2: Add bounds check to get_refblock_offset() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Reported-by: R. Nageswara Sastry Buglink: https://bugs.launchpad.net/qemu/+bug/1728661 Signed-off-by: Max Reitz Message-id: 20171110203111.7666-5-mreitz@redhat.com Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Signed-off-by: Max Reitz --- block/qcow2.h | 6 ------ block/qcow2-refcount.c | 26 +++++++++++++++++++++++++- tests/qemu-iotests/060 | 46 ++++++++++++++++++++++++++++++++++++++++++= ++++ tests/qemu-iotests/060.out | 22 ++++++++++++++++++++++ 4 files changed, 93 insertions(+), 7 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 782a206ecb..6f0ff15dd0 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -527,12 +527,6 @@ uint32_t offset_to_reftable_index(BDRVQcow2State *s, u= int64_t offset) return offset >> (s->refcount_block_bits + s->cluster_bits); } =20 -static inline uint64_t get_refblock_offset(BDRVQcow2State *s, uint64_t off= set) -{ - uint32_t index =3D offset_to_reftable_index(s, offset); - return s->refcount_table[index] & REFT_OFFSET_MASK; -} - /* qcow2.c functions */ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, int64_t sector_num, int nb_sectors); diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 60b8eef3e8..3de1ab51ba 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -3077,16 +3077,40 @@ done: return ret; } =20 +static int64_t get_refblock_offset(BlockDriverState *bs, uint64_t offset) +{ + BDRVQcow2State *s =3D bs->opaque; + uint32_t index =3D offset_to_reftable_index(s, offset); + int64_t covering_refblock_offset =3D 0; + + if (index < s->refcount_table_size) { + covering_refblock_offset =3D s->refcount_table[index] & REFT_OFFSE= T_MASK; + } + if (!covering_refblock_offset) { + qcow2_signal_corruption(bs, true, -1, -1, "Refblock at %#" PRIx64 = " is " + "not covered by the refcount structures", + offset); + return -EIO; + } + + return covering_refblock_offset; +} + static int qcow2_discard_refcount_block(BlockDriverState *bs, uint64_t discard_block_offs) { BDRVQcow2State *s =3D bs->opaque; - uint64_t refblock_offs =3D get_refblock_offset(s, discard_block_offs); + int64_t refblock_offs; uint64_t cluster_index =3D discard_block_offs >> s->cluster_bits; uint32_t block_index =3D cluster_index & (s->refcount_block_size - 1); void *refblock; int ret; =20 + refblock_offs =3D get_refblock_offset(bs, discard_block_offs); + if (refblock_offs < 0) { + return refblock_offs; + } + assert(discard_block_offs !=3D 0); =20 ret =3D qcow2_cache_get(bs, s->refcount_block_cache, refblock_offs, diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index 44141f6243..c230696b3a 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -359,6 +359,52 @@ echo '--- Repairing ---' _check_test_img -q -r all _check_test_img -r all =20 +echo +echo "=3D=3D=3D Discarding an out-of-bounds refblock =3D=3D=3D" +echo + +_make_test_img 64M + +# Pretend there's a refblock really up high +poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\xff\xff\xff\x00\x00\x00\x0= 0" +# Let's try to shrink the qcow2 image so that the block driver tries +# to discard that refblock (and see what happens!) +$QEMU_IMG resize --shrink "$TEST_IMG" 32M + +echo '--- Checking and retrying ---' +# Image should not be resized +_img_info | grep 'virtual size' +# But it should pass this check, because the "partial" resize has +# already overwritten refblocks past the end +_check_test_img -r all +# So let's try again +$QEMU_IMG resize --shrink "$TEST_IMG" 32M +_img_info | grep 'virtual size' + +echo +echo "=3D=3D=3D Discarding a non-covered in-bounds refblock =3D=3D=3D" +echo + +IMGOPTS=3D'refcount_bits=3D1' _make_test_img 64M + +# Pretend there's a refblock somewhere where there is no refblock to +# cover it (but the covering refblock has a valid index in the +# reftable) +# Every refblock covers 65536 * 8 * 65536 =3D 32 GB, so we have to point +# to 0x10_0000_0000 (64G) to point to the third refblock +poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\x00\x00\x10\x00\x00\x00\x0= 0" +$QEMU_IMG resize --shrink "$TEST_IMG" 32M + +echo '--- Checking and retrying ---' +# Image should not be resized +_img_info | grep 'virtual size' +# But it should pass this check, because the "partial" resize has +# already overwritten refblocks past the end +_check_test_img -r all +# So let's try again +$QEMU_IMG resize --shrink "$TEST_IMG" 32M +_img_info | grep 'virtual size' + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index 07dfdcac99..358e54cdc9 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -348,4 +348,26 @@ The following inconsistencies were found and repaired: =20 Double checking the fixed image now... No errors were found on the image. + +=3D=3D=3D Discarding an out-of-bounds refblock =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +qcow2: Marking image as corrupt: Refblock at 0xffffff00000000 is not cover= ed by the refcount structures; further corruption events will be suppressed +qemu-img: Failed to discard unused refblocks: Input/output error +--- Checking and retrying --- +virtual size: 64M (67108864 bytes) +No errors were found on the image. +Image resized. +virtual size: 32M (33554432 bytes) + +=3D=3D=3D Discarding a non-covered in-bounds refblock =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +qcow2: Marking image as corrupt: Refblock at 0x1000000000 is not covered b= y the refcount structures; further corruption events will be suppressed +qemu-img: Failed to discard unused refblocks: Input/output error +--- Checking and retrying --- +virtual size: 64M (67108864 bytes) +No errors were found on the image. +Image resized. +virtual size: 32M (33554432 bytes) *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943710253428.35012793164015; Fri, 17 Nov 2017 10:35:10 -0800 (PST) Received: from localhost ([::1]:47342 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlTk-00008c-AP for importer@patchew.org; Fri, 17 Nov 2017 13:35:04 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43349) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCo-0001Z3-2L for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:35 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCj-0002b9-2C for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:34 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34356) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCf-0002X6-BD; Fri, 17 Nov 2017 13:17:25 -0500 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 8E078820ED; Fri, 17 Nov 2017 18:17:24 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id A65E08B11C; Fri, 17 Nov 2017 18:17:23 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:50 +0100 Message-Id: <20171117181653.20651-23-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.26]); Fri, 17 Nov 2017 18:17:24 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 22/25] qcow2: Refuse to get unaligned offsets from cache X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz Instead of using an assertion, it is better to emit a corruption event here. Checking all offsets for correct alignment can be tedious and it is easily possible to forget to do so. qcow2_cache_do_get() is a function every L2 and refblock access has to go through, so this is a good central point to add such a check. And for good measure, let us also add an assertion that the offset is non-zero. Making this a corruption event is not feasible, because a zero offset usually means something special (such as the cluster is unused), so all callers should be checking this anyway. If they do not, it is their fault, hence the assertion here. Signed-off-by: Max Reitz Message-id: 20171110203111.7666-6-mreitz@redhat.com Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Signed-off-by: Max Reitz --- block/qcow2-cache.c | 21 +++++++++++++++++++++ tests/qemu-iotests/060 | 21 +++++++++++++++++++++ tests/qemu-iotests/060.out | 29 +++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index 75746a7f43..a5baaba0ff 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -62,6 +62,18 @@ static inline int qcow2_cache_get_table_idx(BlockDriverS= tate *bs, return idx; } =20 +static inline const char *qcow2_cache_get_name(BDRVQcow2State *s, Qcow2Cac= he *c) +{ + if (c =3D=3D s->refcount_block_cache) { + return "refcount block"; + } else if (c =3D=3D s->l2_table_cache) { + return "L2 table"; + } else { + /* Do not abort, because this is not critical */ + return "unknown"; + } +} + static void qcow2_cache_table_release(BlockDriverState *bs, Qcow2Cache *c, int i, int num_tables) { @@ -314,9 +326,18 @@ static int qcow2_cache_do_get(BlockDriverState *bs, Qc= ow2Cache *c, uint64_t min_lru_counter =3D UINT64_MAX; int min_lru_index =3D -1; =20 + assert(offset !=3D 0); + trace_qcow2_cache_get(qemu_coroutine_self(), c =3D=3D s->l2_table_cach= e, offset, read_from_disk); =20 + if (offset_into_cluster(s, offset)) { + qcow2_signal_corruption(bs, true, -1, -1, "Cannot get entry from %= s " + "cache: Offset %#" PRIx64 " is unaligned", + qcow2_cache_get_name(s, c), offset); + return -EIO; + } + /* Check if the table is already cached */ i =3D lookup_index =3D (offset / s->cluster_size * 4) % c->size; do { diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index c230696b3a..1eca09417b 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -405,6 +405,27 @@ _check_test_img -r all $QEMU_IMG resize --shrink "$TEST_IMG" 32M _img_info | grep 'virtual size' =20 +echo +echo "=3D=3D=3D Discarding a refblock covered by an unaligned refblock =3D= =3D=3D" +echo + +IMGOPTS=3D'refcount_bits=3D1' _make_test_img 64M + +# Same as above +poke_file "$TEST_IMG" "$(($rt_offset+8))" "\x00\x00\x00\x10\x00\x00\x00\x0= 0" +# But now we actually "create" an unaligned third refblock +poke_file "$TEST_IMG" "$(($rt_offset+16))" "\x00\x00\x00\x00\x00\x00\x02\x= 00" +$QEMU_IMG resize --shrink "$TEST_IMG" 32M + +echo '--- Repairing ---' +# Fails the first repair because the corruption prevents the check +# function from double-checking +# (Using -q for the first invocation, because otherwise the +# double-check error message appears above the summary for some +# reason -- so let's just hide the summary) +_check_test_img -q -r all +_check_test_img -r all + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index 358e54cdc9..56f5eb15d8 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -370,4 +370,33 @@ virtual size: 64M (67108864 bytes) No errors were found on the image. Image resized. virtual size: 32M (33554432 bytes) + +=3D=3D=3D Discarding a refblock covered by an unaligned refblock =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +qcow2: Marking image as corrupt: Cannot get entry from refcount block cach= e: Offset 0x200 is unaligned; further corruption events will be suppressed +qemu-img: Failed to discard unused refblocks: Input/output error +--- Repairing --- +Repairing refcount block 1 is outside image +ERROR refcount block 2 is not cluster aligned; refcount table entry corrup= ted +qcow2: Marking image as corrupt: Refblock offset 0x200 unaligned (reftable= index: 0x2); further corruption events will be suppressed +Can't get refcount for cluster 1048576: Input/output error +Rebuilding refcount structure +Repairing cluster 1 refcount=3D1 reference=3D0 +Repairing cluster 2 refcount=3D1 reference=3D0 +Repairing cluster 1048576 refcount=3D1 reference=3D0 +qemu-img: Check failed: No medium found +Leaked cluster 1 refcount=3D1 reference=3D0 +Leaked cluster 2 refcount=3D1 reference=3D0 +Leaked cluster 1048576 refcount=3D1 reference=3D0 +Repairing cluster 1 refcount=3D1 reference=3D0 +Repairing cluster 2 refcount=3D1 reference=3D0 +Repairing cluster 1048576 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 3 leaked clusters + 0 corruptions + +Double checking the fixed image now... +No errors were found on the image. *** done --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943866368397.7502505022343; Fri, 17 Nov 2017 10:37:46 -0800 (PST) Received: from localhost ([::1]:47365 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlWG-0002L5-Gy for importer@patchew.org; Fri, 17 Nov 2017 13:37:40 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43345) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCn-0001Yu-T7 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:34 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCj-0002bc-Jw for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:33 -0500 Received: from mx1.redhat.com ([209.132.183.28]:50270) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCh-0002Yp-5n; Fri, 17 Nov 2017 13:17:27 -0500 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 636892C9767; Fri, 17 Nov 2017 18:17:26 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id DB24711E7DB; Fri, 17 Nov 2017 18:17:24 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:51 +0100 Message-Id: <20171117181653.20651-24-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.29]); Fri, 17 Nov 2017 18:17:26 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 23/25] qcow2: Fix overly broad madvise() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz @mem_size and @offset are both size_t, thus subtracting them from one another will just return a big size_t if mem_size < offset -- even more obvious here because the result is stored in another size_t. Checking that result to be positive is therefore not sufficient to exclude the case that offset > mem_size. Thus, we currently sometimes issue an madvise() over a very large address range. This is triggered by iotest 163, but with -m64, this does not result in tangible problems. But with -m32, this test produces three segfaults, all of which are fixed by this patch. Signed-off-by: Max Reitz Message-id: 20171114184127.24238-1-mreitz@redhat.com Reviewed-by: Eric Blake Reviewed-by: Alberto Garcia Reviewed-by: Darren Kenny Signed-off-by: Max Reitz --- block/qcow2-cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c index a5baaba0ff..c48ffebd8f 100644 --- a/block/qcow2-cache.c +++ b/block/qcow2-cache.c @@ -85,7 +85,7 @@ static void qcow2_cache_table_release(BlockDriverState *b= s, Qcow2Cache *c, size_t mem_size =3D (size_t) s->cluster_size * num_tables; size_t offset =3D QEMU_ALIGN_UP((uintptr_t) t, align) - (uintptr_t) t; size_t length =3D QEMU_ALIGN_DOWN(mem_size - offset, align); - if (length > 0) { + if (mem_size > offset && length > 0) { madvise((uint8_t *) t + offset, length, MADV_DONTNEED); } #endif --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510944036689279.33734522649104; Fri, 17 Nov 2017 10:40:36 -0800 (PST) Received: from localhost ([::1]:47386 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlYx-0004xm-8a for importer@patchew.org; Fri, 17 Nov 2017 13:40:27 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43384) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCp-0001aa-Sa for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCo-0002fy-Ht for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:35 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41836) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCi-0002a1-Hc; Fri, 17 Nov 2017 13:17:28 -0500 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 9B4A57EA8B; Fri, 17 Nov 2017 18:17:27 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id ACA638B11C; Fri, 17 Nov 2017 18:17:26 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:52 +0100 Message-Id: <20171117181653.20651-25-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.28]); Fri, 17 Nov 2017 18:17:27 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 24/25] block: Make bdrv_next() keep strong references X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz On one hand, it is a good idea for bdrv_next() to return a strong reference because ideally nearly every pointer should be refcounted. This fixes intermittent failure of iotest 194. On the other, it is absolutely necessary for bdrv_next() itself to keep a strong reference to both the BB (in its first phase) and the BDS (at least in the second phase) because when called the next time, it will dereference those objects to get a link to the next one. Therefore, it needs these objects to stay around until then. Just storing the pointer to the next in the iterator is not really viable because that pointer might become invalid as well. Both arguments taken together means we should probably just invoke bdrv_ref() and blk_ref() in bdrv_next(). This means we have to assert that bdrv_next() is always called from the main loop, but that was probably necessary already before this patch and judging from the callers, it also looks to actually be the case. Keeping these strong references means however that callers need to give them up if they decide to abort the iteration early. They can do so through the new bdrv_next_cleanup() function. Suggested-by: Kevin Wolf Signed-off-by: Max Reitz Message-id: 20171110172545.32609-1-mreitz@redhat.com Reviewed-by: Stefan Hajnoczi Signed-off-by: Max Reitz --- include/block/block.h | 1 + block.c | 3 +++ block/block-backend.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- block/snapshot.c | 6 ++++++ migration/block.c | 1 + 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index fbc21daf62..c05cac57e5 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -461,6 +461,7 @@ typedef struct BdrvNextIterator { =20 BlockDriverState *bdrv_first(BdrvNextIterator *it); BlockDriverState *bdrv_next(BdrvNextIterator *it); +void bdrv_next_cleanup(BdrvNextIterator *it); =20 BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs); bool bdrv_is_encrypted(BlockDriverState *bs); diff --git a/block.c b/block.c index 996778cfa0..6c8ef98dfa 100644 --- a/block.c +++ b/block.c @@ -4255,6 +4255,7 @@ void bdrv_invalidate_cache_all(Error **errp) aio_context_release(aio_context); if (local_err) { error_propagate(errp, local_err); + bdrv_next_cleanup(&it); return; } } @@ -4330,6 +4331,7 @@ int bdrv_inactivate_all(void) for (bs =3D bdrv_first(&it); bs; bs =3D bdrv_next(&it)) { ret =3D bdrv_inactivate_recurse(bs, pass); if (ret < 0) { + bdrv_next_cleanup(&it); goto out; } } @@ -4864,6 +4866,7 @@ bool bdrv_is_first_non_filter(BlockDriverState *candi= date) =20 /* candidate is the first non filter */ if (perm) { + bdrv_next_cleanup(&it); return true; } } diff --git a/block/block-backend.c b/block/block-backend.c index f10b1db612..5836cb3087 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -442,21 +442,37 @@ BlockBackend *blk_next(BlockBackend *blk) * the monitor or attached to a BlockBackend */ BlockDriverState *bdrv_next(BdrvNextIterator *it) { - BlockDriverState *bs; + BlockDriverState *bs, *old_bs; + + /* Must be called from the main loop */ + assert(qemu_get_current_aio_context() =3D=3D qemu_get_aio_context()); =20 /* First, return all root nodes of BlockBackends. In order to avoid * returning a BDS twice when multiple BBs refer to it, we only return= it * if the BB is the first one in the parent list of the BDS. */ if (it->phase =3D=3D BDRV_NEXT_BACKEND_ROOTS) { + BlockBackend *old_blk =3D it->blk; + + old_bs =3D old_blk ? blk_bs(old_blk) : NULL; + do { it->blk =3D blk_all_next(it->blk); bs =3D it->blk ? blk_bs(it->blk) : NULL; } while (it->blk && (bs =3D=3D NULL || bdrv_first_blk(bs) !=3D it-= >blk)); =20 + if (it->blk) { + blk_ref(it->blk); + } + blk_unref(old_blk); + if (bs) { + bdrv_ref(bs); + bdrv_unref(old_bs); return bs; } it->phase =3D BDRV_NEXT_MONITOR_OWNED; + } else { + old_bs =3D it->bs; } =20 /* Then return the monitor-owned BDSes without a BB attached. Ignore a= ll @@ -467,18 +483,46 @@ BlockDriverState *bdrv_next(BdrvNextIterator *it) bs =3D it->bs; } while (bs && bdrv_has_blk(bs)); =20 + if (bs) { + bdrv_ref(bs); + } + bdrv_unref(old_bs); + return bs; } =20 -BlockDriverState *bdrv_first(BdrvNextIterator *it) +static void bdrv_next_reset(BdrvNextIterator *it) { *it =3D (BdrvNextIterator) { .phase =3D BDRV_NEXT_BACKEND_ROOTS, }; +} =20 +BlockDriverState *bdrv_first(BdrvNextIterator *it) +{ + bdrv_next_reset(it); return bdrv_next(it); } =20 +/* Must be called when aborting a bdrv_next() iteration before + * bdrv_next() returns NULL */ +void bdrv_next_cleanup(BdrvNextIterator *it) +{ + /* Must be called from the main loop */ + assert(qemu_get_current_aio_context() =3D=3D qemu_get_aio_context()); + + if (it->phase =3D=3D BDRV_NEXT_BACKEND_ROOTS) { + if (it->blk) { + bdrv_unref(blk_bs(it->blk)); + blk_unref(it->blk); + } + } else { + bdrv_unref(it->bs); + } + + bdrv_next_reset(it); +} + /* * Add a BlockBackend into the list of backends referenced by the monitor,= with * the given @name acting as the handle for the monitor. diff --git a/block/snapshot.c b/block/snapshot.c index 1d5ab5f90f..be0743abac 100644 --- a/block/snapshot.c +++ b/block/snapshot.c @@ -417,6 +417,7 @@ bool bdrv_all_can_snapshot(BlockDriverState **first_bad= _bs) } aio_context_release(ctx); if (!ok) { + bdrv_next_cleanup(&it); goto fail; } } @@ -444,6 +445,7 @@ int bdrv_all_delete_snapshot(const char *name, BlockDri= verState **first_bad_bs, } aio_context_release(ctx); if (ret < 0) { + bdrv_next_cleanup(&it); goto fail; } } @@ -469,6 +471,7 @@ int bdrv_all_goto_snapshot(const char *name, BlockDrive= rState **first_bad_bs) } aio_context_release(ctx); if (err < 0) { + bdrv_next_cleanup(&it); goto fail; } } @@ -494,6 +497,7 @@ int bdrv_all_find_snapshot(const char *name, BlockDrive= rState **first_bad_bs) } aio_context_release(ctx); if (err < 0) { + bdrv_next_cleanup(&it); goto fail; } } @@ -525,6 +529,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn, } aio_context_release(ctx); if (err < 0) { + bdrv_next_cleanup(&it); goto fail; } } @@ -548,6 +553,7 @@ BlockDriverState *bdrv_all_find_vmstate_bs(void) aio_context_release(ctx); =20 if (found) { + bdrv_next_cleanup(&it); break; } } diff --git a/migration/block.c b/migration/block.c index 3282809583..7147171bb7 100644 --- a/migration/block.c +++ b/migration/block.c @@ -415,6 +415,7 @@ static int init_blk_migration(QEMUFile *f) sectors =3D bdrv_nb_sectors(bs); if (sectors <=3D 0) { ret =3D sectors; + bdrv_next_cleanup(&it); goto out; } =20 --=20 2.13.6 From nobody Mon May 6 19:01:54 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510943876513136.06826483890336; Fri, 17 Nov 2017 10:37:56 -0800 (PST) Received: from localhost ([::1]:47367 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlWQ-0002VM-MF for importer@patchew.org; Fri, 17 Nov 2017 13:37:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43390) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eFlCq-0001ar-5l for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eFlCp-0002gF-99 for qemu-devel@nongnu.org; Fri, 17 Nov 2017 13:17:36 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37328) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eFlCk-0002bo-Aq; Fri, 17 Nov 2017 13:17:30 -0500 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 40E0E4E4C5; Fri, 17 Nov 2017 18:17:29 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-103.ams2.redhat.com [10.36.117.103]) by smtp.corp.redhat.com (Postfix) with ESMTP id EA8E68B11C; Fri, 17 Nov 2017 18:17:27 +0000 (UTC) From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 17 Nov 2017 19:16:53 +0100 Message-Id: <20171117181653.20651-26-kwolf@redhat.com> In-Reply-To: <20171117181653.20651-1-kwolf@redhat.com> References: <20171117181653.20651-1-kwolf@redhat.com> 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.38]); Fri, 17 Nov 2017 18:17:29 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 25/25] iotests: Make 087 pass without AIO enabled X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Max Reitz If AIO has not been enabled in the qemu build that is to be tested, we should skip the "aio=3Dnative without O_DIRECT" test instead of failing. Signed-off-by: Max Reitz Message-id: 20171115180732.31753-1-mreitz@redhat.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- tests/qemu-iotests/087 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/qemu-iotests/087 b/tests/qemu-iotests/087 index 27ab6c5151..2561a14456 100755 --- a/tests/qemu-iotests/087 +++ b/tests/qemu-iotests/087 @@ -102,7 +102,14 @@ echo echo =3D=3D=3D aio=3Dnative without O_DIRECT =3D=3D=3D echo =20 -run_qemu <