From nobody Tue Apr 30 01:06:31 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 1505470336338535.5616650852446; Fri, 15 Sep 2017 03:12:16 -0700 (PDT) Received: from localhost ([::1]:52344 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnba-0003Sd-Jt for importer@patchew.org; Fri, 15 Sep 2017 06:12:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37253) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnZo-00026L-Ib for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsnZn-0004I8-By for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38644) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsnZh-0004Au-KY; Fri, 15 Sep 2017 06:10:17 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AAB2281E02; Fri, 15 Sep 2017 10:10:16 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6EC4966D5F; Fri, 15 Sep 2017 10:10:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com AAB2281E02 Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx01.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 12:10:03 +0200 Message-Id: <20170915101008.16646-2-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 15 Sep 2017 10:10:16 +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] [PATCH 1/6] qemu-io: Reset qemuio_blk permissions before each command 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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" qemu-io provides a 'reopen' command that allows switching from writable to read-only access. We need to make sure that we don't try to keep write permissions to a BlockBackend that becomes read-only, otherwise things are going to fail. command() already makes sure to request any additional permissions that a qemu-io command requires, so just resetting the permissions to values that are safe for read-only images is enough to fix this. As a side effect, this makes the output of qemu-iotests case 187 more consistent. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake Reviewed-by: Fam Zheng --- qemu-io.c | 13 +++++++++++++ tests/qemu-iotests/187.out | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/qemu-io.c b/qemu-io.c index 265445ad89..9e031f0f8e 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -366,6 +366,12 @@ static void command_loop(void) char *input; =20 for (i =3D 0; !done && i < ncmdline; i++) { + /* Make sure that we start each command with clean permissions and= only + * add whatever the specific cmdinfo_t describes */ + if (qemuio_blk) { + blk_set_perm(qemuio_blk, BLK_PERM_CONSISTENT_READ, BLK_PERM_AL= L, + &error_abort); + } done =3D qemuio_command(qemuio_blk, cmdline[i]); } if (cmdline) { @@ -391,6 +397,13 @@ static void command_loop(void) if (input =3D=3D NULL) { break; } + + /* Make sure that we start each command with clean permissions and= only + * add whatever the specific cmdinfo_t describes */ + if (qemuio_blk) { + blk_set_perm(qemuio_blk, BLK_PERM_CONSISTENT_READ, BLK_PERM_AL= L, + &error_abort); + } done =3D qemuio_command(qemuio_blk, input); g_free(input); =20 diff --git a/tests/qemu-iotests/187.out b/tests/qemu-iotests/187.out index 68fb944cd5..30b987f71f 100644 --- a/tests/qemu-iotests/187.out +++ b/tests/qemu-iotests/187.out @@ -12,7 +12,7 @@ Start from read-write =20 wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -write failed: Operation not permitted +Block node is read-only wrote 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) *** done --=20 2.13.5 From nobody Tue Apr 30 01:06:31 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 1505470461896212.64144763934075; Fri, 15 Sep 2017 03:14:21 -0700 (PDT) Received: from localhost ([::1]:52354 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsndd-00067v-4A for importer@patchew.org; Fri, 15 Sep 2017 06:14:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37328) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnZw-0002Do-D2 for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsnZs-0004NV-2l for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42840) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsnZj-0004DB-Qo; Fri, 15 Sep 2017 06:10:20 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D91D8C0587F5; Fri, 15 Sep 2017 10:10:18 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0023466D5F; Fri, 15 Sep 2017 10:10:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com D91D8C0587F5 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 12:10:04 +0200 Message-Id: <20170915101008.16646-3-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 15 Sep 2017 10:10: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] [PATCH 2/6] block: Add reopen_queue to bdrv_child_perm() 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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" In the context of bdrv_reopen(), we'll have to look at the state of the graph as it will be after the reopen. This interface addition is in preparation for the change. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/block/block_int.h | 7 +++++++ block.c | 19 ++++++++++++------- block/commit.c | 1 + block/mirror.c | 1 + block/replication.c | 1 + block/vvfat.c | 1 + 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index ba4c383393..99abe2ce74 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -411,9 +411,14 @@ struct BlockDriver { * * If @c is NULL, return the permissions for attaching a new child for= the * given @role. + * + * If @reopen_queue is non-NULL, don't return the currently needed + * permissions, but those that will be needed after applying the + * @reopen_queue. */ void (*bdrv_child_perm)(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t parent_perm, uint64_t parent_shared, uint64_t *nperm, uint64_t *nshared); =20 @@ -983,6 +988,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm= , uint64_t shared, * all children */ void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared); =20 @@ -992,6 +998,7 @@ void bdrv_filter_default_perms(BlockDriverState *bs, Bd= rvChild *c, * CONSISTENT_READ and doesn't share WRITE. */ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared); =20 diff --git a/block.c b/block.c index 6dd47e414e..c7724c85e3 100644 --- a/block.c +++ b/block.c @@ -1537,16 +1537,17 @@ static void bdrv_child_abort_perm_update(BdrvChild = *c); static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shar= ed); =20 static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_= bs, - BdrvChild *c, - const BdrvChildRole *role, + BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t parent_perm, uint64_t parent_shared, uint64_t *nperm, uint64_t *nshared) { if (bs->drv && bs->drv->bdrv_child_perm) { - bs->drv->bdrv_child_perm(bs, c, role, + bs->drv->bdrv_child_perm(bs, c, role, reopen_queue, parent_perm, parent_shared, nperm, nshared); } + /* TODO Take force_share from reopen_queue */ if (child_bs && child_bs->force_share) { *nshared =3D BLK_PERM_ALL; } @@ -1596,7 +1597,7 @@ static int bdrv_check_perm(BlockDriverState *bs, uint= 64_t cumulative_perms, /* Check all children */ QLIST_FOREACH(c, &bs->children, next) { uint64_t cur_perm, cur_shared; - bdrv_child_perm(bs, c->bs, c, c->role, + bdrv_child_perm(bs, c->bs, c, c->role, NULL, cumulative_perms, cumulative_shared_perms, &cur_perm, &cur_shared); ret =3D bdrv_child_check_perm(c, cur_perm, cur_shared, ignore_chil= dren, @@ -1658,7 +1659,7 @@ static void bdrv_set_perm(BlockDriverState *bs, uint6= 4_t cumulative_perms, /* Update all children */ QLIST_FOREACH(c, &bs->children, next) { uint64_t cur_perm, cur_shared; - bdrv_child_perm(bs, c->bs, c, c->role, + bdrv_child_perm(bs, c->bs, c, c->role, NULL, cumulative_perms, cumulative_shared_perms, &cur_perm, &cur_shared); bdrv_child_set_perm(c, cur_perm, cur_shared); @@ -1827,6 +1828,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t pe= rm, uint64_t shared, =20 void bdrv_filter_default_perms(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { @@ -1844,6 +1846,7 @@ void bdrv_filter_default_perms(BlockDriverState *bs, = BdrvChild *c, =20 void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { @@ -1853,9 +1856,11 @@ void bdrv_format_default_perms(BlockDriverState *bs,= BdrvChild *c, if (!backing) { /* Apart from the modifications below, the same permissions are * forwarded and left alone as for filters */ - bdrv_filter_default_perms(bs, c, role, perm, shared, &perm, &share= d); + bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared, + &perm, &shared); =20 /* Format drivers may touch metadata even if the guest doesn't wri= te */ + /* TODO Take flags from reopen_queue */ if (bdrv_is_writable(bs)) { perm |=3D BLK_PERM_WRITE | BLK_PERM_RESIZE; } @@ -1999,7 +2004,7 @@ BdrvChild *bdrv_attach_child(BlockDriverState *parent= _bs, =20 assert(parent_bs->drv); assert(bdrv_get_aio_context(parent_bs) =3D=3D bdrv_get_aio_context(chi= ld_bs)); - bdrv_child_perm(parent_bs, child_bs, NULL, child_role, + bdrv_child_perm(parent_bs, child_bs, NULL, child_role, NULL, perm, shared_perm, &perm, &shared_perm); =20 child =3D bdrv_root_attach_child(child_bs, child_name, child_role, diff --git a/block/commit.c b/block/commit.c index 898d91f653..8f0e83578a 100644 --- a/block/commit.c +++ b/block/commit.c @@ -257,6 +257,7 @@ static void bdrv_commit_top_close(BlockDriverState *bs) =20 static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { diff --git a/block/mirror.c b/block/mirror.c index 6531652d73..6f5cb9f26c 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1084,6 +1084,7 @@ static void bdrv_mirror_top_close(BlockDriverState *b= s) =20 static void bdrv_mirror_top_child_perm(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { diff --git a/block/replication.c b/block/replication.c index bf4462c8e7..3a4e6822e4 100644 --- a/block/replication.c +++ b/block/replication.c @@ -157,6 +157,7 @@ static void replication_close(BlockDriverState *bs) =20 static void replication_child_perm(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { diff --git a/block/vvfat.c b/block/vvfat.c index c54fa94651..ee894bbe98 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -3210,6 +3210,7 @@ err: =20 static void vvfat_child_perm(BlockDriverState *bs, BdrvChild *c, const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { --=20 2.13.5 From nobody Tue Apr 30 01:06:31 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 1505470340559979.7626739694499; Fri, 15 Sep 2017 03:12:20 -0700 (PDT) Received: from localhost ([::1]:52345 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnbf-0003oH-PX for importer@patchew.org; Fri, 15 Sep 2017 06:12:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37276) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnZq-00027u-9Q for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsnZo-0004Jo-Nu for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43012) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsnZl-0004F4-GP; Fri, 15 Sep 2017 06:10:21 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9489AC058EA9; Fri, 15 Sep 2017 10:10:20 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 303D066D5F; Fri, 15 Sep 2017 10:10:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 9489AC058EA9 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 12:10:05 +0200 Message-Id: <20170915101008.16646-4-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 15 Sep 2017 10:10: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] [PATCH 3/6] block: Add reopen queue to bdrv_check_perm() 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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" In the context of bdrv_reopen(), we'll have to look at the state of the graph as it will be after the reopen. This interface addition is in preparation for the change. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/block.c b/block.c index c7724c85e3..0b499fda4c 100644 --- a/block.c +++ b/block.c @@ -1531,7 +1531,8 @@ static int bdrv_fill_options(QDict **options, const c= har *filename, return 0; } =20 -static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t sha= red, +static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q, + uint64_t perm, uint64_t shared, GSList *ignore_children, Error **errp); static void bdrv_child_abort_perm_update(BdrvChild *c); static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shar= ed); @@ -1562,7 +1563,8 @@ static void bdrv_child_perm(BlockDriverState *bs, Blo= ckDriverState *child_bs, * A call to this function must always be followed by a call to bdrv_set_p= erm() * or bdrv_abort_perm_update(). */ -static int bdrv_check_perm(BlockDriverState *bs, uint64_t cumulative_perms, +static int bdrv_check_perm(BlockDriverState *bs, BlockReopenQueue *q, + uint64_t cumulative_perms, uint64_t cumulative_shared_perms, GSList *ignore_children, Error **errp) { @@ -1597,11 +1599,11 @@ static int bdrv_check_perm(BlockDriverState *bs, ui= nt64_t cumulative_perms, /* Check all children */ QLIST_FOREACH(c, &bs->children, next) { uint64_t cur_perm, cur_shared; - bdrv_child_perm(bs, c->bs, c, c->role, NULL, + bdrv_child_perm(bs, c->bs, c, c->role, q, cumulative_perms, cumulative_shared_perms, &cur_perm, &cur_shared); - ret =3D bdrv_child_check_perm(c, cur_perm, cur_shared, ignore_chil= dren, - errp); + ret =3D bdrv_child_check_perm(c, q, cur_perm, cur_shared, + ignore_children, errp); if (ret < 0) { return ret; } @@ -1727,7 +1729,8 @@ char *bdrv_perm_names(uint64_t perm) * * Needs to be followed by a call to either bdrv_set_perm() or * bdrv_abort_perm_update(). */ -static int bdrv_check_update_perm(BlockDriverState *bs, uint64_t new_used_= perm, +static int bdrv_check_update_perm(BlockDriverState *bs, BlockReopenQueue *= q, + uint64_t new_used_perm, uint64_t new_shared_perm, GSList *ignore_children, Error **errp) { @@ -1769,19 +1772,20 @@ static int bdrv_check_update_perm(BlockDriverState = *bs, uint64_t new_used_perm, cumulative_shared_perms &=3D c->shared_perm; } =20 - return bdrv_check_perm(bs, cumulative_perms, cumulative_shared_perms, + return bdrv_check_perm(bs, q, cumulative_perms, cumulative_shared_perm= s, ignore_children, errp); } =20 /* Needs to be followed by a call to either bdrv_child_set_perm() or * bdrv_child_abort_perm_update(). */ -static int bdrv_child_check_perm(BdrvChild *c, uint64_t perm, uint64_t sha= red, +static int bdrv_child_check_perm(BdrvChild *c, BlockReopenQueue *q, + uint64_t perm, uint64_t shared, GSList *ignore_children, Error **errp) { int ret; =20 ignore_children =3D g_slist_prepend(g_slist_copy(ignore_children), c); - ret =3D bdrv_check_update_perm(c->bs, perm, shared, ignore_children, e= rrp); + ret =3D bdrv_check_update_perm(c->bs, q, perm, shared, ignore_children= , errp); g_slist_free(ignore_children); =20 return ret; @@ -1809,7 +1813,7 @@ int bdrv_child_try_set_perm(BdrvChild *c, uint64_t pe= rm, uint64_t shared, { int ret; =20 - ret =3D bdrv_child_check_perm(c, perm, shared, NULL, errp); + ret =3D bdrv_child_check_perm(c, NULL, perm, shared, NULL, errp); if (ret < 0) { bdrv_child_abort_perm_update(c); return ret; @@ -1950,7 +1954,7 @@ static void bdrv_replace_child(BdrvChild *child, Bloc= kDriverState *new_bs) * because we're just taking a parent away, so we're loosening * restrictions. */ bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm); - bdrv_check_perm(old_bs, perm, shared_perm, NULL, &error_abort); + bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL, &error_abor= t); bdrv_set_perm(old_bs, perm, shared_perm); } =20 @@ -1969,7 +1973,7 @@ BdrvChild *bdrv_root_attach_child(BlockDriverState *c= hild_bs, BdrvChild *child; int ret; =20 - ret =3D bdrv_check_update_perm(child_bs, perm, shared_perm, NULL, errp= ); + ret =3D bdrv_check_update_perm(child_bs, NULL, perm, shared_perm, NULL= , errp); if (ret < 0) { bdrv_abort_perm_update(child_bs); return NULL; @@ -3184,7 +3188,7 @@ void bdrv_replace_node(BlockDriverState *from, BlockD= riverState *to, =20 /* Check whether the required permissions can be granted on @to, ignor= ing * all BdrvChild in @list so that they can't block themselves. */ - ret =3D bdrv_check_update_perm(to, perm, shared, list, errp); + ret =3D bdrv_check_update_perm(to, NULL, perm, shared, list, errp); if (ret < 0) { bdrv_abort_perm_update(to); goto out; @@ -4054,7 +4058,7 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Erro= r **errp) =20 /* Update permissions, they may differ for inactive nodes */ bdrv_get_cumulative_perm(bs, &perm, &shared_perm); - ret =3D bdrv_check_perm(bs, perm, shared_perm, NULL, &local_err); + 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); @@ -4121,7 +4125,7 @@ static int bdrv_inactivate_recurse(BlockDriverState *= bs, =20 /* Update permissions, they may differ for inactive nodes */ bdrv_get_cumulative_perm(bs, &perm, &shared_perm); - bdrv_check_perm(bs, perm, shared_perm, NULL, &error_abort); + bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, &error_abort); bdrv_set_perm(bs, perm, shared_perm); } =20 --=20 2.13.5 From nobody Tue Apr 30 01:06:31 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 1505470453174630.4616459249102; Fri, 15 Sep 2017 03:14:13 -0700 (PDT) Received: from localhost ([::1]:52353 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsndU-00061o-G6 for importer@patchew.org; Fri, 15 Sep 2017 06:14:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37326) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnZw-0002Dm-Cv for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsnZr-0004N2-Ms for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46816) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsnZn-0004Gq-1d; Fri, 15 Sep 2017 06:10:23 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 274F880F79; Fri, 15 Sep 2017 10:10:22 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id DFDB971C4D; Fri, 15 Sep 2017 10:10:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 274F880F79 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 12:10:06 +0200 Message-Id: <20170915101008.16646-5-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 15 Sep 2017 10:10: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] [PATCH 4/6] block: Base permissions on rw state after reopen 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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" When new permissions are calculated during bdrv_reopen(), they need to be based on the state of the graph as it will be after the reopen has completed, not on the current state of the involved nodes. This patch makes bdrv_is_writable() optionally accept a BlockReopenQueue from which the new flags are taken. This is then used for determining the new bs->file permissions of format drivers as soon as we add the code to actually pass a non-NULL reopen queue to the .bdrv_child_perm callbacks. While moving bdrv_is_writable(), make it static. It isn't used outside block.c. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/block/block.h | 1 - block.c | 52 ++++++++++++++++++++++++++++++++++++-----------= ---- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 2ad18775af..082eb2cd9c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -435,7 +435,6 @@ int bdrv_is_allocated_above(BlockDriverState *top, Bloc= kDriverState *base, int64_t offset, int64_t bytes, int64_t *pnum); =20 bool bdrv_is_read_only(BlockDriverState *bs); -bool bdrv_is_writable(BlockDriverState *bs); int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, bool ignore_allow_rdw, Error **errp); int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp); diff --git a/block.c b/block.c index 0b499fda4c..ed8d51dd42 100644 --- a/block.c +++ b/block.c @@ -239,12 +239,6 @@ bool bdrv_is_read_only(BlockDriverState *bs) return bs->read_only; } =20 -/* Returns whether the image file can be written to right now */ -bool bdrv_is_writable(BlockDriverState *bs) -{ - return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE); -} - int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, bool ignore_allow_rdw, Error **errp) { @@ -1537,6 +1531,41 @@ static int bdrv_child_check_perm(BdrvChild *c, Block= ReopenQueue *q, static void bdrv_child_abort_perm_update(BdrvChild *c); static void bdrv_child_set_perm(BdrvChild *c, uint64_t perm, uint64_t shar= ed); =20 +typedef struct BlockReopenQueueEntry { + bool prepared; + BDRVReopenState state; + QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry; +} BlockReopenQueueEntry; + +/* + * Return the flags that @bs will have after the reopens in @q have + * successfully completed. If @q is NULL (or @bs is not contained in @q), + * return the current flags. + */ +static int bdrv_reopen_get_flags(BlockReopenQueue *q, BlockDriverState *bs) +{ + BlockReopenQueueEntry *entry; + + if (q !=3D NULL) { + QSIMPLEQ_FOREACH(entry, q, entry) { + if (entry->state.bs =3D=3D bs) { + return entry->state.flags; + } + } + } + + return bs->open_flags; +} + +/* Returns whether the image file can be written to after the reopen queue= @q + * has been successfully applied, or right now if @q is NULL. */ +static bool bdrv_is_writable(BlockDriverState *bs, BlockReopenQueue *q) +{ + int flags =3D bdrv_reopen_get_flags(q, bs); + + return (flags & (BDRV_O_RDWR | BDRV_O_INACTIVE)) =3D=3D BDRV_O_RDWR; +} + static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_= bs, BdrvChild *c, const BdrvChildRole *role, BlockReopenQueue *reopen_queue, @@ -1574,7 +1603,7 @@ static int bdrv_check_perm(BlockDriverState *bs, Bloc= kReopenQueue *q, =20 /* Write permissions never work with read-only images */ if ((cumulative_perms & (BLK_PERM_WRITE | BLK_PERM_WRITE_UNCHANGED)) && - !bdrv_is_writable(bs)) + !bdrv_is_writable(bs, q)) { error_setg(errp, "Block node is read-only"); return -EPERM; @@ -1864,8 +1893,7 @@ void bdrv_format_default_perms(BlockDriverState *bs, = BdrvChild *c, &perm, &shared); =20 /* Format drivers may touch metadata even if the guest doesn't wri= te */ - /* TODO Take flags from reopen_queue */ - if (bdrv_is_writable(bs)) { + if (bdrv_is_writable(bs, reopen_queue)) { perm |=3D BLK_PERM_WRITE | BLK_PERM_RESIZE; } =20 @@ -2642,12 +2670,6 @@ BlockDriverState *bdrv_open(const char *filename, co= nst char *reference, NULL, errp); } =20 -typedef struct BlockReopenQueueEntry { - bool prepared; - BDRVReopenState state; - QSIMPLEQ_ENTRY(BlockReopenQueueEntry) entry; -} BlockReopenQueueEntry; - /* * Adds a BlockDriverState to a simple queue for an atomic, transactional * reopen of multiple devices. --=20 2.13.5 From nobody Tue Apr 30 01:06:31 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 1505470559574728.619540083368; Fri, 15 Sep 2017 03:15:59 -0700 (PDT) Received: from localhost ([::1]:52365 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnfC-0007M0-RX for importer@patchew.org; Fri, 15 Sep 2017 06:15:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37388) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsna3-0002Iu-HC for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsnZz-0004Uj-Hq for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38504) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsnZr-0004M0-97; Fri, 15 Sep 2017 06:10:27 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 67306C04B318; Fri, 15 Sep 2017 10:10:26 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7066C69503; Fri, 15 Sep 2017 10:10:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 67306C04B318 Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 12:10:07 +0200 Message-Id: <20170915101008.16646-6-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 15 Sep 2017 10:10: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] [PATCH 5/6] block: reopen: Queue children after their parents 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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" We will calculate the required new permissions in the prepare stage of a reopen. Required permissions of children can be influenced by the changes made to their parents, but parents are independent from their children. This means that permissions need to be calculated top-down. In order to achieve this, queue parents before their children rather than queuing the children first. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/block.c b/block.c index ed8d51dd42..204cbb46c7 100644 --- a/block.c +++ b/block.c @@ -2768,6 +2768,19 @@ static BlockReopenQueue *bdrv_reopen_queue_child(Blo= ckReopenQueue *bs_queue, flags |=3D BDRV_O_ALLOW_RDWR; } =20 + if (!bs_entry) { + bs_entry =3D g_new0(BlockReopenQueueEntry, 1); + QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry); + } else { + QDECREF(bs_entry->state.options); + QDECREF(bs_entry->state.explicit_options); + } + + bs_entry->state.bs =3D bs; + bs_entry->state.options =3D options; + bs_entry->state.explicit_options =3D explicit_options; + bs_entry->state.flags =3D flags; + QLIST_FOREACH(child, &bs->children, next) { QDict *new_child_options; char *child_key_dot; @@ -2787,19 +2800,6 @@ static BlockReopenQueue *bdrv_reopen_queue_child(Blo= ckReopenQueue *bs_queue, child->role, options, flags); } =20 - if (!bs_entry) { - bs_entry =3D g_new0(BlockReopenQueueEntry, 1); - QSIMPLEQ_INSERT_TAIL(bs_queue, bs_entry, entry); - } else { - QDECREF(bs_entry->state.options); - QDECREF(bs_entry->state.explicit_options); - } - - bs_entry->state.bs =3D bs; - bs_entry->state.options =3D options; - bs_entry->state.explicit_options =3D explicit_options; - bs_entry->state.flags =3D flags; - return bs_queue; } =20 --=20 2.13.5 From nobody Tue Apr 30 01:06:31 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 1505470558284525.4872839543519; Fri, 15 Sep 2017 03:15:58 -0700 (PDT) Received: from localhost ([::1]:52364 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsnfB-0007LX-F7 for importer@patchew.org; Fri, 15 Sep 2017 06:15:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37377) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsna0-0002GE-UV for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsnZz-0004Uq-Ji for qemu-devel@nongnu.org; Fri, 15 Sep 2017 06:10:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38690) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsnZs-0004Nq-UD; Fri, 15 Sep 2017 06:10:29 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 11D3DC047B70; Fri, 15 Sep 2017 10:10:28 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id B472C66D5F; Fri, 15 Sep 2017 10:10:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 11D3DC047B70 Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx07.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 12:10:08 +0200 Message-Id: <20170915101008.16646-7-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Fri, 15 Sep 2017 10:10:28 +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] [PATCH 6/6] block: Fix permissions after bdrv_reopen() 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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" If we switch between read-only and read-write, the permissions that image format drivers need on bs->file change, too. Make sure to update the permissions during bdrv_reopen(). Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- include/block/block.h | 1 + block.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 65 insertions(+) diff --git a/include/block/block.h b/include/block/block.h index 082eb2cd9c..3c3af462e4 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -166,6 +166,7 @@ typedef QSIMPLEQ_HEAD(BlockReopenQueue, BlockReopenQueu= eEntry) BlockReopenQueue; typedef struct BDRVReopenState { BlockDriverState *bs; int flags; + uint64_t perm, shared_perm; QDict *options; QDict *explicit_options; void *opaque; diff --git a/block.c b/block.c index 204cbb46c7..5c65fac672 100644 --- a/block.c +++ b/block.c @@ -2781,6 +2781,10 @@ static BlockReopenQueue *bdrv_reopen_queue_child(Blo= ckReopenQueue *bs_queue, bs_entry->state.explicit_options =3D explicit_options; bs_entry->state.flags =3D flags; =20 + /* This needs to be overwritten in bdrv_reopen_prepare() */ + bs_entry->state.perm =3D UINT64_MAX; + bs_entry->state.shared_perm =3D 0; + QLIST_FOREACH(child, &bs->children, next) { QDict *new_child_options; char *child_key_dot; @@ -2887,6 +2891,52 @@ int bdrv_reopen(BlockDriverState *bs, int bdrv_flags= , Error **errp) return ret; } =20 +static BlockReopenQueueEntry *find_parent_in_reopen_queue(BlockReopenQueue= *q, + BdrvChild *c) +{ + BlockReopenQueueEntry *entry; + + QSIMPLEQ_FOREACH(entry, q, entry) { + BlockDriverState *bs =3D entry->state.bs; + BdrvChild *child; + + QLIST_FOREACH(child, &bs->children, next) { + if (child =3D=3D c) { + return entry; + } + } + } + + return NULL; +} + +static void bdrv_reopen_perm(BlockReopenQueue *q, BlockDriverState *bs, + uint64_t *perm, uint64_t *shared) +{ + BdrvChild *c; + BlockReopenQueueEntry *parent; + uint64_t cumulative_perms =3D 0; + uint64_t cumulative_shared_perms =3D BLK_PERM_ALL; + + QLIST_FOREACH(c, &bs->parents, next_parent) { + parent =3D find_parent_in_reopen_queue(q, c); + if (!parent) { + cumulative_perms |=3D c->perm; + cumulative_shared_perms &=3D c->shared_perm; + } else { + uint64_t nperm, nshared; + + bdrv_child_perm(parent->state.bs, bs, c, c->role, q, + parent->state.perm, parent->state.shared_perm, + &nperm, &nshared); + + cumulative_perms |=3D nperm; + cumulative_shared_perms &=3D nshared; + } + } + *perm =3D cumulative_perms; + *shared =3D cumulative_shared_perms; +} =20 /* * Prepares a BlockDriverState for reopen. All changes are staged in the @@ -2952,6 +3002,9 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state= , BlockReopenQueue *queue, goto error; } =20 + /* Calculate required permissions after reopening */ + bdrv_reopen_perm(queue, reopen_state->bs, + &reopen_state->perm, &reopen_state->shared_perm); =20 ret =3D bdrv_flush(reopen_state->bs); if (ret) { @@ -3007,6 +3060,12 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_stat= e, BlockReopenQueue *queue, } while ((entry =3D qdict_next(reopen_state->options, entry))); } =20 + ret =3D bdrv_check_perm(reopen_state->bs, queue, reopen_state->perm, + reopen_state->shared_perm, NULL, errp); + if (ret < 0) { + goto error; + } + ret =3D 0; =20 error: @@ -3047,6 +3106,9 @@ void bdrv_reopen_commit(BDRVReopenState *reopen_state) =20 bdrv_refresh_limits(bs, NULL); =20 + bdrv_set_perm(reopen_state->bs, reopen_state->perm, + reopen_state->shared_perm); + new_can_write =3D !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE); if (!old_can_write && new_can_write && drv->bdrv_reopen_bitmaps_rw) { @@ -3080,6 +3142,8 @@ void bdrv_reopen_abort(BDRVReopenState *reopen_state) } =20 QDECREF(reopen_state->explicit_options); + + bdrv_abort_perm_update(reopen_state->bs); } =20 =20 --=20 2.13.5 From nobody Tue Apr 30 01:06:31 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 1505495299515458.471492271595; Fri, 15 Sep 2017 10:08:19 -0700 (PDT) Received: from localhost ([::1]:54335 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsu6E-0005Nh-NN for importer@patchew.org; Fri, 15 Sep 2017 13:08:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51141) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dsu0Y-0000Sn-Ih for qemu-devel@nongnu.org; Fri, 15 Sep 2017 13:02:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dsu0V-0005yR-Ew for qemu-devel@nongnu.org; Fri, 15 Sep 2017 13:02:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56404) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dsu0L-0005oF-Pc; Fri, 15 Sep 2017 13:02:14 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A76BA52779; Fri, 15 Sep 2017 17:02:12 +0000 (UTC) Received: from localhost.localdomain.com (ovpn-117-157.ams2.redhat.com [10.36.117.157]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9E6B417CDD; Fri, 15 Sep 2017 17:02:08 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A76BA52779 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=kwolf@redhat.com From: Kevin Wolf To: qemu-block@nongnu.org Date: Fri, 15 Sep 2017 19:02:04 +0200 Message-Id: <20170915170204.14023-1-kwolf@redhat.com> In-Reply-To: <20170915101008.16646-1-kwolf@redhat.com> References: <20170915101008.16646-1-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 15 Sep 2017 17:02: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] [PATCH 7/6] qemu-iotests: Test change-backing-file command 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, famz@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com 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 involves a temporary read-write reopen if the backing file link in the middle of a backing file chain should be changed and is therefore a good test for the latest bdrv_reopen() vs. op blockers fixes. Signed-off-by: Kevin Wolf --- I actually managed to find a simple case that reproduces the bug that is fixed in this series, but outside of my commit job improvements that originally led me to this work. tests/qemu-iotests/195 | 92 ++++++++++++++++++++++++++++++++++++++++++= ++++ tests/qemu-iotests/195.out | 78 +++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/group | 1 + 3 files changed, 171 insertions(+) create mode 100755 tests/qemu-iotests/195 create mode 100644 tests/qemu-iotests/195.out diff --git a/tests/qemu-iotests/195 b/tests/qemu-iotests/195 new file mode 100755 index 0000000000..05a239cbf5 --- /dev/null +++ b/tests/qemu-iotests/195 @@ -0,0 +1,92 @@ +#!/bin/bash +# +# Test change-backing-file command +# +# 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=3Dkwolf@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 + rm -f "$TEST_IMG.mid" +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux + +function do_run_qemu() +{ + echo Testing: "$@" | _filter_imgfmt + $QEMU -nographic -qmp-pretty stdio -serial none "$@" + echo +} + +function run_qemu() +{ + do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp \ + | _filter_qemu_io | _filter_generated_node_ids +} + +size=3D64M +TEST_IMG=3D"$TEST_IMG.base" _make_test_img $size +TEST_IMG=3D"$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base" +_make_test_img -b "$TEST_IMG.mid" + +echo +echo "Change backing file of mid (opened read-only)" +echo + +run_qemu -drive if=3Dnone,file=3D"$TEST_IMG",backing.node-name=3Dmid <