From patchwork Fri Sep 20 15:27:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154595 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0286616B1 for ; Fri, 20 Sep 2019 15:43:49 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D797F20882 for ; Fri, 20 Sep 2019 15:43:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D797F20882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32776 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL4V-0006Ci-31 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:43:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43742) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpU-0000a7-40 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpQ-0004Hb-7s for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:7871) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpN-0004Ct-Nq; Fri, 20 Sep 2019 11:28:09 -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 103DD30615C1; Fri, 20 Sep 2019 15:28:09 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9B2505C1B5; Fri, 20 Sep 2019 15:28:08 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 01/22] blockdev: Allow external snapshots everywhere Date: Fri, 20 Sep 2019 17:27:43 +0200 Message-Id: <20190920152804.12875-2-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 20 Sep 2019 15:28:09 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" There is no good reason why we would allow external snapshots only on the first non-filter node in a chain. Parent BDSs should not care whether their child is replaced by a snapshot. (If they do care, they should announce that via freezing the chain, which is checked in bdrv_append() through bdrv_set_backing_hd().) Before we had bdrv_is_first_non_filter() here (since 212a5a8f095), there was a special function bdrv_check_ext_snapshot() that allowed snapshots by default, but block drivers could override this. Only blkverify did so, however. It is not clear to me why blkverify would do so; maybe just so that the testee block driver would not be replaced. The introducing commit f6186f49e2c does not explain why. Maybe because 08b24cfe376 would have been the correct solution? (Which adds a .supports_backing check.) Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/blockdev.c b/blockdev.c index f89e48fc79..b62b33dc03 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1596,11 +1596,6 @@ static void external_snapshot_prepare(BlkActionState *common, } } - if (!bdrv_is_first_non_filter(state->old_bs)) { - error_setg(errp, QERR_FEATURE_DISABLED, "snapshot"); - goto out; - } - if (action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_SNAPSHOT_SYNC) { BlockdevSnapshotSync *s = action->u.blockdev_snapshot_sync.data; const char *format = s->has_format ? s->format : "qcow2"; From patchwork Fri Sep 20 15:27:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154575 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DFA491745 for ; Fri, 20 Sep 2019 15:36:10 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C0737207FC for ; Fri, 20 Sep 2019 15:36:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C0737207FC Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60954 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKx6-0006WR-Fi for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:36:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43813) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpa-0000dF-N5 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpY-0004My-Fn for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48660) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpS-0004Ft-1q; Fri, 20 Sep 2019 11:28:15 -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 58CA918C890D; Fri, 20 Sep 2019 15:28:11 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E691D60606; Fri, 20 Sep 2019 15:28:10 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 02/22] blockdev: Allow resizing everywhere Date: Fri, 20 Sep 2019 17:27:44 +0200 Message-Id: <20190920152804.12875-3-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 20 Sep 2019 15:28:11 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Block nodes that do not allow resizing should not share BLK_PERM_RESIZE. It does not matter whether they are the first non-filter in their chain or not. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/blockdev.c b/blockdev.c index b62b33dc03..0420bc29be 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3198,11 +3198,6 @@ void qmp_block_resize(bool has_device, const char *device, aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); - if (!bdrv_is_first_non_filter(bs)) { - error_setg(errp, QERR_FEATURE_DISABLED, "resize"); - goto out; - } - if (size < 0) { error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "size", "a >0 size"); goto out; From patchwork Fri Sep 20 15:27:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154573 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 246DB912 for ; Fri, 20 Sep 2019 15:32:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0583820882 for ; Fri, 20 Sep 2019 15:32:21 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0583820882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60922 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKtO-0003vD-Vb for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:32:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43815) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpa-0000dK-O9 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpY-0004N3-GC for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:22 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33090) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpU-0004KG-0Q; Fri, 20 Sep 2019 11:28:16 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A4D4C8665D; Fri, 20 Sep 2019 15:28:13 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3F66060167; Fri, 20 Sep 2019 15:28:13 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 03/22] block: Drop bdrv_is_first_non_filter() Date: Fri, 20 Sep 2019 17:27:45 +0200 Message-Id: <20190920152804.12875-4-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 20 Sep 2019 15:28:13 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" It is unused now. (And it was ugly because it needed to explore all BDS chains from the top.) Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block.h | 1 - block.c | 26 -------------------------- 2 files changed, 27 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 37c9de7446..d3ccab4722 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -403,7 +403,6 @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts, /* external snapshots */ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, BlockDriverState *candidate); -bool bdrv_is_first_non_filter(BlockDriverState *candidate); /* check if a named node can be replaced when doing drive-mirror */ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, diff --git a/block.c b/block.c index 1c7c199849..7d99ca692c 100644 --- a/block.c +++ b/block.c @@ -6206,32 +6206,6 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, return false; } -/* This function checks if the candidate is the first non filter bs down it's - * bs chain. Since we don't have pointers to parents it explore all bs chains - * from the top. Some filters can choose not to pass down the recursion. - */ -bool bdrv_is_first_non_filter(BlockDriverState *candidate) -{ - BlockDriverState *bs; - BdrvNextIterator it; - - /* walk down the bs forest recursively */ - for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { - bool perm; - - /* try to recurse in this top level bs */ - perm = bdrv_recurse_is_first_non_filter(bs, candidate); - - /* candidate is the first non filter */ - if (perm) { - bdrv_next_cleanup(&it); - return true; - } - } - - return false; -} - BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, const char *node_name, Error **errp) { From patchwork Fri Sep 20 15:27:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154605 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1CBA716B1 for ; Fri, 20 Sep 2019 15:51:43 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F1B04208C3 for ; Fri, 20 Sep 2019 15:51:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F1B04208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32826 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLC9-0003CD-BE for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:51:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43843) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpc-0000eG-Pk for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpa-0004Oy-Mx for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48686) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpW-0004Kx-4T; Fri, 20 Sep 2019 11:28:18 -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 EE72C18C8919; Fri, 20 Sep 2019 15:28:15 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 89BDE60606; Fri, 20 Sep 2019 15:28:15 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 04/22] iotests: Let 041 use -blockdev for quorum children Date: Fri, 20 Sep 2019 17:27:46 +0200 Message-Id: <20190920152804.12875-5-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 20 Sep 2019 15:28:16 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Using -drive with default options means that a virtio-blk drive will be created that has write access to the to-be quorum children. Quorum should have exclusive write access to them, so we should use -blockdev instead. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/041 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 84bc6d6581..d91f538276 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -884,7 +884,10 @@ class TestRepairQuorum(iotests.QMPTestCase): # Assign a node name to each quorum image in order to manipulate # them opts = "node-name=img%i" % self.IMAGES.index(i) - self.vm = self.vm.add_drive(i, opts) + opts += ',driver=%s' % iotests.imgfmt + opts += ',file.driver=file' + opts += ',file.filename=%s' % i + self.vm = self.vm.add_blockdev(opts) self.vm.launch() From patchwork Fri Sep 20 15:27:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154581 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 66A151745 for ; Fri, 20 Sep 2019 15:38:06 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4682520882 for ; Fri, 20 Sep 2019 15:38:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4682520882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60960 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKyy-0008AF-CV for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:38:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43861) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpe-0000gB-Re for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpc-0004Pt-OG for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41990) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpY-0004M5-D5; Fri, 20 Sep 2019 11:28:20 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 47D68C058CBD; Fri, 20 Sep 2019 15:28:18 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D444B60167; Fri, 20 Sep 2019 15:28:17 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 05/22] quorum: Fix child permissions Date: Fri, 20 Sep 2019 17:27:47 +0200 Message-Id: <20190920152804.12875-6-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 20 Sep 2019 15:28:18 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Quorum is not actually a filter. It cannot share WRITE or RESIZE on its children. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/quorum.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/block/quorum.c b/block/quorum.c index df68adcfaa..17b439056f 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -1114,6 +1114,23 @@ static char *quorum_dirname(BlockDriverState *bs, Error **errp) return NULL; } +static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c, + const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, + uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) +{ + *nperm = perm & DEFAULT_PERM_PASSTHROUGH; + + /* + * We cannot share RESIZE or WRITE, as this would make the + * children differ from each other. + */ + *nshared = (shared & (BLK_PERM_CONSISTENT_READ | + BLK_PERM_WRITE_UNCHANGED)) + | DEFAULT_PERM_UNCHANGED; +} + static const char *const quorum_strong_runtime_opts[] = { QUORUM_OPT_VOTE_THRESHOLD, QUORUM_OPT_BLKVERIFY, @@ -1143,7 +1160,7 @@ static BlockDriver bdrv_quorum = { .bdrv_add_child = quorum_add_child, .bdrv_del_child = quorum_del_child, - .bdrv_child_perm = bdrv_filter_default_perms, + .bdrv_child_perm = quorum_child_perm, .is_filter = true, .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter, From patchwork Fri Sep 20 15:27:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154591 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C75731745 for ; Fri, 20 Sep 2019 15:41:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A883920882 for ; Fri, 20 Sep 2019 15:41:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A883920882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60988 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL1z-0003KE-1V for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:41:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43888) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpg-0000jE-2m for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpe-0004Qx-QV for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39886) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpa-0004NW-EX; Fri, 20 Sep 2019 11:28:22 -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 9754718C4270; Fri, 20 Sep 2019 15:28:20 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 301835C1B5; Fri, 20 Sep 2019 15:28:20 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 06/22] block: Add bdrv_recurse_can_replace() Date: Fri, 20 Sep 2019 17:27:48 +0200 Message-Id: <20190920152804.12875-7-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.62]); Fri, 20 Sep 2019 15:28:20 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" After a couple of follow-up patches, this function will replace bdrv_recurse_is_first_non_filter() in check_to_replace_node(). bdrv_recurse_is_first_non_filter() is both not sufficiently specific for check_to_replace_node() (it allows cases that should not be allowed, like replacing child nodes of quorum with dissenting data that have more parents than just quorum), and it is too restrictive (it is perfectly fine to replace filters). Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block_int.h | 10 ++++++++++ block.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/block/block_int.h b/include/block/block_int.h index 5fd4f17d93..0be7d12f04 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -103,6 +103,13 @@ struct BlockDriver { */ bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs, BlockDriverState *candidate); + /* + * Return true if @to_replace can be replaced by a BDS with the + * same data as @bs without it affecting @bs's behavior (that is, + * without it being visible to @bs's parents). + */ + bool (*bdrv_recurse_can_replace)(BlockDriverState *bs, + BlockDriverState *to_replace); int (*bdrv_probe)(const uint8_t *buf, int buf_size, const char *filename); int (*bdrv_probe_device)(const char *filename); @@ -1254,6 +1261,9 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared); +bool bdrv_recurse_can_replace(BlockDriverState *bs, + BlockDriverState *to_replace); + /* * Default implementation for drivers to pass bdrv_co_block_status() to * their file. diff --git a/block.c b/block.c index 7d99ca692c..a2deca4ac9 100644 --- a/block.c +++ b/block.c @@ -6206,6 +6206,44 @@ bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, return false; } +/* + * This function checks whether the given @to_replace is allowed to be + * replaced by a node that always shows the same data as @bs. This is + * used for example to verify whether the mirror job can replace + * @to_replace by the target mirrored from @bs. + * To be replaceable, @bs and @to_replace may either be guaranteed to + * always show the same data (because they are only connected through + * filters), or some driver may allow replacing one of its children + * because it can guarantee that this child's data is not visible at + * all (for example, for dissenting quorum children that have no other + * parents). + */ +bool bdrv_recurse_can_replace(BlockDriverState *bs, + BlockDriverState *to_replace) +{ + if (!bs || !bs->drv) { + return false; + } + + if (bs == to_replace) { + return true; + } + + /* For filters, we can recurse on our own */ + if (bs->drv->is_filter) { + BdrvChild *child = bs->file ?: bs->backing; + return bdrv_recurse_can_replace(child->bs, to_replace); + } + + /* See what the driver can do */ + if (bs->drv->bdrv_recurse_can_replace) { + return bs->drv->bdrv_recurse_can_replace(bs, to_replace); + } + + /* Safe default */ + return false; +} + BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, const char *node_name, Error **errp) { From patchwork Fri Sep 20 15:27:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154571 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6EC62912 for ; Fri, 20 Sep 2019 15:32:01 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4310A20882 for ; Fri, 20 Sep 2019 15:32:01 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4310A20882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60920 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKt5-0003mb-M4 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:31:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43921) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKph-0000m7-Vv for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpg-0004UH-Ur for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47246) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpc-0004PL-MJ; Fri, 20 Sep 2019 11:28:26 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E5CD3328E; Fri, 20 Sep 2019 15:28:22 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 80DC9600C6; Fri, 20 Sep 2019 15:28:22 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 07/22] blkverify: Implement .bdrv_recurse_can_replace() Date: Fri, 20 Sep 2019 17:27:49 +0200 Message-Id: <20190920152804.12875-8-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 20 Sep 2019 15:28:22 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Max Reitz --- block/blkverify.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/block/blkverify.c b/block/blkverify.c index 304b0a1368..0add3ab483 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -282,6 +282,20 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs, return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate); } +static bool blkverify_recurse_can_replace(BlockDriverState *bs, + BlockDriverState *to_replace) +{ + BDRVBlkverifyState *s = bs->opaque; + + /* + * blkverify quits the whole qemu process if there is a mismatch + * between bs->file->bs and s->test_file->bs. Therefore, we know + * know that both must match bs and we can recurse down to either. + */ + return bdrv_recurse_can_replace(bs->file->bs, to_replace) || + bdrv_recurse_can_replace(s->test_file->bs, to_replace); +} + static void blkverify_refresh_filename(BlockDriverState *bs) { BDRVBlkverifyState *s = bs->opaque; @@ -328,6 +342,7 @@ static BlockDriver bdrv_blkverify = { .is_filter = true, .bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter, + .bdrv_recurse_can_replace = blkverify_recurse_can_replace, }; static void bdrv_blkverify_init(void) From patchwork Fri Sep 20 15:27:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154613 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8AF0614DB for ; Fri, 20 Sep 2019 15:55:50 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6C1B4208C3 for ; Fri, 20 Sep 2019 15:55:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6C1B4208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32878 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLG8-0007ny-SA for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:55:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43947) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpk-0000pP-1k for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpi-0004Um-8u for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:21200) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpe-0004QY-PY; Fri, 20 Sep 2019 11:28:27 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6B934C057F88; Fri, 20 Sep 2019 15:28:25 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CB8B15D9C3; Fri, 20 Sep 2019 15:28:24 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 08/22] quorum: Store children in own structure Date: Fri, 20 Sep 2019 17:27:50 +0200 Message-Id: <20190920152804.12875-9-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 20 Sep 2019 15:28:25 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This will be useful when we want to store additional attributes for each child. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/quorum.c | 58 ++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/block/quorum.c b/block/quorum.c index 17b439056f..cf2171cc74 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -65,9 +65,13 @@ typedef struct QuorumVotes { bool (*compare)(QuorumVoteValue *a, QuorumVoteValue *b); } QuorumVotes; +typedef struct QuorumChild { + BdrvChild *child; +} QuorumChild; + /* the following structure holds the state of one quorum instance */ typedef struct BDRVQuorumState { - BdrvChild **children; /* children BlockDriverStates */ + QuorumChild *children; int num_children; /* children count */ unsigned next_child_index; /* the index of the next child that should * be added @@ -264,7 +268,7 @@ static void quorum_report_bad_versions(BDRVQuorumState *s, } QLIST_FOREACH(item, &version->items, next) { quorum_report_bad(QUORUM_OP_TYPE_READ, acb->offset, acb->bytes, - s->children[item->index]->bs->node_name, 0); + s->children[item->index].child->bs->node_name, 0); } } } @@ -279,7 +283,7 @@ static void quorum_rewrite_entry(void *opaque) * corrupted data. * Mask out BDRV_REQ_WRITE_UNCHANGED because this overwrites the * area with different data from the other children. */ - bdrv_co_pwritev(s->children[co->idx], acb->offset, acb->bytes, + bdrv_co_pwritev(s->children[co->idx].child, acb->offset, acb->bytes, acb->qiov, acb->flags & ~BDRV_REQ_WRITE_UNCHANGED); /* Wake up the caller after the last rewrite */ @@ -578,8 +582,8 @@ static void read_quorum_children_entry(void *opaque) int i = co->idx; QuorumChildRequest *sacb = &acb->qcrs[i]; - sacb->bs = s->children[i]->bs; - sacb->ret = bdrv_co_preadv(s->children[i], acb->offset, acb->bytes, + sacb->bs = s->children[i].child->bs; + sacb->ret = bdrv_co_preadv(s->children[i].child, acb->offset, acb->bytes, &acb->qcrs[i].qiov, 0); if (sacb->ret == 0) { @@ -605,7 +609,8 @@ static int read_quorum_children(QuorumAIOCB *acb) acb->children_read = s->num_children; for (i = 0; i < s->num_children; i++) { - acb->qcrs[i].buf = qemu_blockalign(s->children[i]->bs, acb->qiov->size); + acb->qcrs[i].buf = qemu_blockalign(s->children[i].child->bs, + acb->qiov->size); qemu_iovec_init(&acb->qcrs[i].qiov, acb->qiov->niov); qemu_iovec_clone(&acb->qcrs[i].qiov, acb->qiov, acb->qcrs[i].buf); } @@ -647,8 +652,8 @@ static int read_fifo_child(QuorumAIOCB *acb) /* We try to read the next child in FIFO order if we failed to read */ do { n = acb->children_read++; - acb->qcrs[n].bs = s->children[n]->bs; - ret = bdrv_co_preadv(s->children[n], acb->offset, acb->bytes, + acb->qcrs[n].bs = s->children[n].child->bs; + ret = bdrv_co_preadv(s->children[n].child, acb->offset, acb->bytes, acb->qiov, 0); if (ret < 0) { quorum_report_bad_acb(&acb->qcrs[n], ret); @@ -688,8 +693,8 @@ static void write_quorum_entry(void *opaque) int i = co->idx; QuorumChildRequest *sacb = &acb->qcrs[i]; - sacb->bs = s->children[i]->bs; - sacb->ret = bdrv_co_pwritev(s->children[i], acb->offset, acb->bytes, + sacb->bs = s->children[i].child->bs; + sacb->ret = bdrv_co_pwritev(s->children[i].child, acb->offset, acb->bytes, acb->qiov, acb->flags); if (sacb->ret == 0) { acb->success_count++; @@ -743,12 +748,12 @@ static int64_t quorum_getlength(BlockDriverState *bs) int i; /* check that all file have the same length */ - result = bdrv_getlength(s->children[0]->bs); + result = bdrv_getlength(s->children[0].child->bs); if (result < 0) { return result; } for (i = 1; i < s->num_children; i++) { - int64_t value = bdrv_getlength(s->children[i]->bs); + int64_t value = bdrv_getlength(s->children[i].child->bs); if (value < 0) { return value; } @@ -774,10 +779,10 @@ static coroutine_fn int quorum_co_flush(BlockDriverState *bs) error_votes.compare = quorum_64bits_compare; for (i = 0; i < s->num_children; i++) { - result = bdrv_co_flush(s->children[i]->bs); + result = bdrv_co_flush(s->children[i].child->bs); if (result) { quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0, 0, - s->children[i]->bs->node_name, result); + s->children[i].child->bs->node_name, result); result_value.l = result; quorum_count_vote(&error_votes, &result_value, i); } else { @@ -803,7 +808,7 @@ static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs, int i; for (i = 0; i < s->num_children; i++) { - bool perm = bdrv_recurse_is_first_non_filter(s->children[i]->bs, + bool perm = bdrv_recurse_is_first_non_filter(s->children[i].child->bs, candidate); if (perm) { return true; @@ -932,7 +937,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, } /* allocate the children array */ - s->children = g_new0(BdrvChild *, s->num_children); + s->children = g_new0(QuorumChild, s->num_children); opened = g_new0(bool, s->num_children); for (i = 0; i < s->num_children; i++) { @@ -940,8 +945,9 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, ret = snprintf(indexstr, 32, "children.%d", i); assert(ret < 32); - s->children[i] = bdrv_open_child(NULL, options, indexstr, bs, - &child_format, false, &local_err); + s->children[i].child = bdrv_open_child(NULL, options, indexstr, bs, + &child_format, false, + &local_err); if (local_err) { ret = -EINVAL; goto close_exit; @@ -962,7 +968,7 @@ close_exit: if (!opened[i]) { continue; } - bdrv_unref_child(bs, s->children[i]); + bdrv_unref_child(bs, s->children[i].child); } g_free(s->children); g_free(opened); @@ -979,7 +985,7 @@ static void quorum_close(BlockDriverState *bs) int i; for (i = 0; i < s->num_children; i++) { - bdrv_unref_child(bs, s->children[i]); + bdrv_unref_child(bs, s->children[i].child); } g_free(s->children); @@ -1022,8 +1028,10 @@ static void quorum_add_child(BlockDriverState *bs, BlockDriverState *child_bs, s->next_child_index--; goto out; } - s->children = g_renew(BdrvChild *, s->children, s->num_children + 1); - s->children[s->num_children++] = child; + s->children = g_renew(QuorumChild, s->children, s->num_children + 1); + s->children[s->num_children++] = (QuorumChild){ + .child = child, + }; out: bdrv_drained_end(bs); @@ -1036,7 +1044,7 @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child, int i; for (i = 0; i < s->num_children; i++) { - if (s->children[i] == child) { + if (s->children[i].child == child) { break; } } @@ -1059,7 +1067,7 @@ static void quorum_del_child(BlockDriverState *bs, BdrvChild *child, /* We can safely remove this child now */ memmove(&s->children[i], &s->children[i + 1], (s->num_children - i - 1) * sizeof(BdrvChild *)); - s->children = g_renew(BdrvChild *, s->children, --s->num_children); + s->children = g_renew(QuorumChild, s->children, --s->num_children); bdrv_unref_child(bs, child); bdrv_drained_end(bs); @@ -1100,7 +1108,7 @@ static void quorum_gather_child_options(BlockDriverState *bs, QDict *target, for (i = 0; i < s->num_children; i++) { qlist_append(children_list, - qobject_ref(s->children[i]->bs->full_open_options)); + qobject_ref(s->children[i].child->bs->full_open_options)); } } From patchwork Fri Sep 20 15:27:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154597 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id CD8AD15E6 for ; Fri, 20 Sep 2019 15:45:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AE24120882 for ; Fri, 20 Sep 2019 15:45:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AE24120882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32784 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL5y-0007Oj-H2 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:45:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43945) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpj-0000pL-TE for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpi-0004Uu-N1 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:11115) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpg-0004SF-Fa; Fri, 20 Sep 2019 11:28:28 -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 B8ED03082E10; Fri, 20 Sep 2019 15:28:27 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5244D60606; Fri, 20 Sep 2019 15:28:27 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 09/22] quorum: Add QuorumChild.to_be_replaced Date: Fri, 20 Sep 2019 17:27:51 +0200 Message-Id: <20190920152804.12875-10-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 20 Sep 2019 15:28:27 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" We will need this to verify that Quorum can let one of its children be replaced without breaking anything else. Signed-off-by: Max Reitz --- block/quorum.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/block/quorum.c b/block/quorum.c index cf2171cc74..207054a64e 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -67,6 +67,13 @@ typedef struct QuorumVotes { typedef struct QuorumChild { BdrvChild *child; + + /* + * If set, check whether this node can be replaced without any + * other parent noticing: Unshare CONSISTENT_READ, and take the + * WRITE permission. + */ + bool to_be_replaced; } QuorumChild; /* the following structure holds the state of one quorum instance */ @@ -1128,6 +1135,16 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c, uint64_t perm, uint64_t shared, uint64_t *nperm, uint64_t *nshared) { + BDRVQuorumState *s = bs->opaque; + int i; + + for (i = 0; i < s->num_children; i++) { + if (s->children[i].child == c) { + break; + } + } + assert(!c || i < s->num_children); + *nperm = perm & DEFAULT_PERM_PASSTHROUGH; /* @@ -1137,6 +1154,12 @@ static void quorum_child_perm(BlockDriverState *bs, BdrvChild *c, *nshared = (shared & (BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE_UNCHANGED)) | DEFAULT_PERM_UNCHANGED; + + if (c && s->children[i].to_be_replaced) { + /* Prepare for sudden data changes */ + *nperm |= BLK_PERM_WRITE; + *nshared &= ~BLK_PERM_CONSISTENT_READ; + } } static const char *const quorum_strong_runtime_opts[] = { From patchwork Fri Sep 20 15:27:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154625 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1CA3414DB for ; Fri, 20 Sep 2019 15:59:33 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F0A232086A for ; Fri, 20 Sep 2019 15:59:32 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F0A232086A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32916 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLJj-0003Ba-F4 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:59:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43982) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpo-0000ub-5Z for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpl-0004W1-FK for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48784) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpi-0004Uj-Of; Fri, 20 Sep 2019 11:28:30 -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 1643B18C890D; Fri, 20 Sep 2019 15:28:30 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9C59A60606; Fri, 20 Sep 2019 15:28:29 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 10/22] quorum: Implement .bdrv_recurse_can_replace() Date: Fri, 20 Sep 2019 17:27:52 +0200 Message-Id: <20190920152804.12875-11-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 20 Sep 2019 15:28:30 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Max Reitz --- block/quorum.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/block/quorum.c b/block/quorum.c index 207054a64e..81b57dbae2 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -825,6 +825,67 @@ static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs, return false; } +static bool quorum_recurse_can_replace(BlockDriverState *bs, + BlockDriverState *to_replace) +{ + BDRVQuorumState *s = bs->opaque; + int i; + + for (i = 0; i < s->num_children; i++) { + /* + * We have no idea whether our children show the same data as + * this node (@bs). It is actually highly likely that + * @to_replace does not, because replacing a broken child is + * one of the main use cases here. + * + * We do know that the new BDS will match @bs, so replacing + * any of our children by it will be safe. It cannot change + * the data this quorum node presents to its parents. + * + * However, replacing @to_replace by @bs in any of our + * children's chains may change visible data somewhere in + * there. We therefore cannot recurse down those chains with + * bdrv_recurse_can_replace(). + * (More formally, bdrv_recurse_can_replace() requires that + * @to_replace will be replaced by something matching the @bs + * passed to it. We cannot guarantee that.) + * + * Thus, we can only check whether any of our immediate + * children matches @to_replace. + * + * (In the future, we might add a function to recurse down a + * chain that checks that nothing there cares about a change + * in data from the respective child in question. For + * example, most filters do not care when their child's data + * suddenly changes, as long as their parents do not care.) + */ + if (s->children[i].child->bs == to_replace) { + Error *local_err = NULL; + + /* + * We now have to ensure that there is no other parent + * that cares about replacing this child by a node with + * potentially different data. + */ + s->children[i].to_be_replaced = true; + bdrv_child_refresh_perms(bs, s->children[i].child, &local_err); + + /* Revert permissions */ + s->children[i].to_be_replaced = false; + bdrv_child_refresh_perms(bs, s->children[i].child, &error_abort); + + if (local_err) { + error_free(local_err); + return false; + } + + return true; + } + } + + return false; +} + static int quorum_valid_threshold(int threshold, int num_children, Error **errp) { @@ -1195,6 +1256,7 @@ static BlockDriver bdrv_quorum = { .is_filter = true, .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter, + .bdrv_recurse_can_replace = quorum_recurse_can_replace, .strong_runtime_opts = quorum_strong_runtime_opts, }; From patchwork Fri Sep 20 15:27:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154593 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5862C16B1 for ; Fri, 20 Sep 2019 15:41:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 398ED20882 for ; Fri, 20 Sep 2019 15:41:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 398ED20882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60990 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL26-0003UL-Jv for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:41:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44029) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpy-00011H-4b for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpu-0004a4-7o for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42000) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpl-0004VY-4E; Fri, 20 Sep 2019 11:28:33 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5A5223086228; Fri, 20 Sep 2019 15:28:32 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E66BC100194E; Fri, 20 Sep 2019 15:28:31 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 11/22] block: Use bdrv_recurse_can_replace() Date: Fri, 20 Sep 2019 17:27:53 +0200 Message-Id: <20190920152804.12875-12-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Fri, 20 Sep 2019 15:28:32 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Let check_to_replace_node() use the more specialized bdrv_recurse_can_replace() instead of bdrv_recurse_is_first_non_filter(), which is too restrictive. Signed-off-by: Max Reitz --- block.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/block.c b/block.c index a2deca4ac9..02177bde9a 100644 --- a/block.c +++ b/block.c @@ -6244,6 +6244,17 @@ bool bdrv_recurse_can_replace(BlockDriverState *bs, return false; } +/* + * Check whether the given @node_name can be replaced by a node that + * has the same data as @parent_bs. If so, return @node_name's BDS; + * NULL otherwise. + * + * @node_name must be a (recursive) *child of @parent_bs (or this + * function will return NULL). + * + * The result (whether the node can be replaced or not) is only valid + * for as long as no graph changes occur. + */ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, const char *node_name, Error **errp) { @@ -6268,8 +6279,11 @@ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, * Another benefit is that this tests exclude backing files which are * blocked by the backing blockers. */ - if (!bdrv_recurse_is_first_non_filter(parent_bs, to_replace_bs)) { - error_setg(errp, "Only top most non filter can be replaced"); + if (!bdrv_recurse_can_replace(parent_bs, to_replace_bs)) { + error_setg(errp, "Cannot replace '%s' by a node mirrored from '%s', " + "because it cannot be guaranteed that doing so would not " + "lead to an abrupt change of visible data", + node_name, parent_bs->node_name); to_replace_bs = NULL; goto out; } From patchwork Fri Sep 20 15:27:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154609 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9BC5814DB for ; Fri, 20 Sep 2019 15:52:05 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7CE67208C3 for ; Fri, 20 Sep 2019 15:52:05 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7CE67208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32830 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLCV-0003dO-Cb for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:52:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44027) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKpy-00011E-3Y for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKpu-0004aE-91 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39996) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpo-0004WZ-40; Fri, 20 Sep 2019 11:28:36 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA21218C4277; Fri, 20 Sep 2019 15:28:34 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3F47C60C57; Fri, 20 Sep 2019 15:28:34 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 12/22] block: Remove bdrv_recurse_is_first_non_filter() Date: Fri, 20 Sep 2019 17:27:54 +0200 Message-Id: <20190920152804.12875-13-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.62]); Fri, 20 Sep 2019 15:28:34 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" It no longer has any users. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/block.h | 4 ---- include/block/block_int.h | 8 -------- block.c | 33 --------------------------------- block/blkverify.c | 15 --------------- block/copy-on-read.c | 9 --------- block/quorum.c | 18 ------------------ block/replication.c | 7 ------- block/throttle.c | 8 -------- 8 files changed, 102 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index d3ccab4722..2944980c03 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -400,10 +400,6 @@ int bdrv_amend_options(BlockDriverState *bs_new, QemuOpts *opts, BlockDriverAmendStatusCB *status_cb, void *cb_opaque, Error **errp); -/* external snapshots */ -bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate); - /* check if a named node can be replaced when doing drive-mirror */ BlockDriverState *check_to_replace_node(BlockDriverState *parent_bs, const char *node_name, Error **errp); diff --git a/include/block/block_int.h b/include/block/block_int.h index 0be7d12f04..70f26530c9 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -95,14 +95,6 @@ struct BlockDriver { * must implement them and return -ENOTSUP. */ bool is_filter; - /* for snapshots block filter like Quorum can implement the - * following recursive callback. - * It's purpose is to recurse on the filter children while calling - * bdrv_recurse_is_first_non_filter on them. - * For a sample implementation look in the future Quorum block filter. - */ - bool (*bdrv_recurse_is_first_non_filter)(BlockDriverState *bs, - BlockDriverState *candidate); /* * Return true if @to_replace can be replaced by a BDS with the * same data as @bs without it affecting @bs's behavior (that is, diff --git a/block.c b/block.c index 02177bde9a..0d9b3de98f 100644 --- a/block.c +++ b/block.c @@ -6173,39 +6173,6 @@ int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts, return bs->drv->bdrv_amend_options(bs, opts, status_cb, cb_opaque, errp); } -/* This function will be called by the bdrv_recurse_is_first_non_filter method - * of block filter and by bdrv_is_first_non_filter. - * It is used to test if the given bs is the candidate or recurse more in the - * node graph. - */ -bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ - /* return false if basic checks fails */ - if (!bs || !bs->drv) { - return false; - } - - /* the code reached a non block filter driver -> check if the bs is - * the same as the candidate. It's the recursion termination condition. - */ - if (!bs->drv->is_filter) { - return bs == candidate; - } - /* Down this path the driver is a block filter driver */ - - /* If the block filter recursion method is defined use it to recurse down - * the node graph. - */ - if (bs->drv->bdrv_recurse_is_first_non_filter) { - return bs->drv->bdrv_recurse_is_first_non_filter(bs, candidate); - } - - /* the driver is a block filter but don't allow to recurse -> return false - */ - return false; -} - /* * This function checks whether the given @to_replace is allowed to be * replaced by a node that always shows the same data as @bs. This is diff --git a/block/blkverify.c b/block/blkverify.c index 0add3ab483..ba6b1853ae 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -268,20 +268,6 @@ static int blkverify_co_flush(BlockDriverState *bs) return bdrv_co_flush(s->test_file->bs); } -static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ - BDRVBlkverifyState *s = bs->opaque; - - bool perm = bdrv_recurse_is_first_non_filter(bs->file->bs, candidate); - - if (perm) { - return true; - } - - return bdrv_recurse_is_first_non_filter(s->test_file->bs, candidate); -} - static bool blkverify_recurse_can_replace(BlockDriverState *bs, BlockDriverState *to_replace) { @@ -341,7 +327,6 @@ static BlockDriver bdrv_blkverify = { .bdrv_co_flush = blkverify_co_flush, .is_filter = true, - .bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter, .bdrv_recurse_can_replace = blkverify_recurse_can_replace, }; diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 6631f30205..3204259513 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -125,13 +125,6 @@ static void cor_lock_medium(BlockDriverState *bs, bool locked) } -static bool cor_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ - return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate); -} - - static BlockDriver bdrv_copy_on_read = { .format_name = "copy-on-read", @@ -151,8 +144,6 @@ static BlockDriver bdrv_copy_on_read = { .bdrv_co_block_status = bdrv_co_block_status_from_file, - .bdrv_recurse_is_first_non_filter = cor_recurse_is_first_non_filter, - .has_variable_length = true, .is_filter = true, }; diff --git a/block/quorum.c b/block/quorum.c index 81b57dbae2..7a8f8b5475 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -808,23 +808,6 @@ static coroutine_fn int quorum_co_flush(BlockDriverState *bs) return result; } -static bool quorum_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ - BDRVQuorumState *s = bs->opaque; - int i; - - for (i = 0; i < s->num_children; i++) { - bool perm = bdrv_recurse_is_first_non_filter(s->children[i].child->bs, - candidate); - if (perm) { - return true; - } - } - - return false; -} - static bool quorum_recurse_can_replace(BlockDriverState *bs, BlockDriverState *to_replace) { @@ -1255,7 +1238,6 @@ static BlockDriver bdrv_quorum = { .bdrv_child_perm = quorum_child_perm, .is_filter = true, - .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter, .bdrv_recurse_can_replace = quorum_recurse_can_replace, .strong_runtime_opts = quorum_strong_runtime_opts, diff --git a/block/replication.c b/block/replication.c index 99532ce521..d6681b6c84 100644 --- a/block/replication.c +++ b/block/replication.c @@ -306,12 +306,6 @@ out: return ret; } -static bool replication_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ - return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate); -} - static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp) { Error *local_err = NULL; @@ -699,7 +693,6 @@ static BlockDriver bdrv_replication = { .bdrv_co_writev = replication_co_writev, .is_filter = true, - .bdrv_recurse_is_first_non_filter = replication_recurse_is_first_non_filter, .has_variable_length = true, .strong_runtime_opts = replication_strong_runtime_opts, diff --git a/block/throttle.c b/block/throttle.c index 0349f42257..71f4bb0ad1 100644 --- a/block/throttle.c +++ b/block/throttle.c @@ -207,12 +207,6 @@ static void throttle_reopen_abort(BDRVReopenState *reopen_state) reopen_state->opaque = NULL; } -static bool throttle_recurse_is_first_non_filter(BlockDriverState *bs, - BlockDriverState *candidate) -{ - return bdrv_recurse_is_first_non_filter(bs->file->bs, candidate); -} - static void coroutine_fn throttle_co_drain_begin(BlockDriverState *bs) { ThrottleGroupMember *tgm = bs->opaque; @@ -252,8 +246,6 @@ static BlockDriver bdrv_throttle = { .bdrv_co_pwrite_zeroes = throttle_co_pwrite_zeroes, .bdrv_co_pdiscard = throttle_co_pdiscard, - .bdrv_recurse_is_first_non_filter = throttle_recurse_is_first_non_filter, - .bdrv_attach_aio_context = throttle_attach_aio_context, .bdrv_detach_aio_context = throttle_detach_aio_context, From patchwork Fri Sep 20 15:27:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154579 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AA81016B1 for ; Fri, 20 Sep 2019 15:37:53 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8A93520882 for ; Fri, 20 Sep 2019 15:37:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8A93520882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60958 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKyl-0007yV-RT for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:37:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44094) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKq3-00014T-QD for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKq1-0004fH-ON for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39978) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpq-0004XO-2v; Fri, 20 Sep 2019 11:28:38 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3259C8A1C92; Fri, 20 Sep 2019 15:28:37 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BFFD45D6A7; Fri, 20 Sep 2019 15:28:36 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 13/22] mirror: Double-check immediately before replacing Date: Fri, 20 Sep 2019 17:27:55 +0200 Message-Id: <20190920152804.12875-14-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.69]); Fri, 20 Sep 2019 15:28:37 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" There is no guarantee that we can still replace the node we want to replace at the end of the mirror job. Double-check by calling bdrv_recurse_can_replace(). Signed-off-by: Max Reitz --- block/mirror.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/block/mirror.c b/block/mirror.c index 706d80fced..d877637e1e 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -695,7 +695,19 @@ static int mirror_exit_common(Job *job) * drain potential other users of the BDS before changing the graph. */ assert(s->in_drain); bdrv_drained_begin(target_bs); - bdrv_replace_node(to_replace, target_bs, &local_err); + /* + * Cannot use check_to_replace_node() here, because that would + * check for an op blocker on @to_replace, and we have our own + * there. + */ + if (bdrv_recurse_can_replace(src, to_replace)) { + bdrv_replace_node(to_replace, target_bs, &local_err); + } else { + error_setg(&local_err, "Can no longer replace '%s' by '%s', " + "because it can no longer be guaranteed that doing so " + "would not lead to an abrupt change of visible data", + to_replace->node_name, target_bs->node_name); + } bdrv_drained_end(target_bs); if (local_err) { error_report_err(local_err); From patchwork Fri Sep 20 15:27:56 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154589 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B5DB11745 for ; Fri, 20 Sep 2019 15:41:09 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 96CD520882 for ; Fri, 20 Sep 2019 15:41:09 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 96CD520882 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:60986 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL1w-0003Hy-4h for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:41:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44093) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKq3-00014S-Oe for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKq1-0004fL-OL for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47268) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpu-0004Ys-8L; Fri, 20 Sep 2019 11:28:42 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7AFD9308421A; Fri, 20 Sep 2019 15:28:39 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 15FE45D9E5; Fri, 20 Sep 2019 15:28:38 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 14/22] quorum: Stop marking it as a filter Date: Fri, 20 Sep 2019 17:27:56 +0200 Message-Id: <20190920152804.12875-15-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Fri, 20 Sep 2019 15:28:39 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Quorum is not a filter, for example because it cannot guarantee which of its children will serve the next request. Thus, any of its children may differ from the data visible to quorum's parents. We have other filters with multiple children, but they differ in this aspect: - blkverify quits the whole qemu process if its children differ. As such, we can always skip it when we want to skip it (as a filter node) by going to any of its children. Both have the same data. - replication generally serves requests from bs->file, so this is its only actually filtered child. - Block job filters currently only have one child, but they will probably get more children in the future. Still, they will always have only one actually filtered child. Having "filters" as a dedicated node category only makes sense if you can skip them by going to a one fixed child that always shows the same data as the filter node. Quorum cannot fulfill this, so it is not a filter. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/quorum.c | 1 - 1 file changed, 1 deletion(-) diff --git a/block/quorum.c b/block/quorum.c index 7a8f8b5475..7f56b4df7c 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -1237,7 +1237,6 @@ static BlockDriver bdrv_quorum = { .bdrv_child_perm = quorum_child_perm, - .is_filter = true, .bdrv_recurse_can_replace = quorum_recurse_can_replace, .strong_runtime_opts = quorum_strong_runtime_opts, From patchwork Fri Sep 20 15:27:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154601 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D99F715E6 for ; Fri, 20 Sep 2019 15:45:47 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BA16D2086A for ; Fri, 20 Sep 2019 15:45:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BA16D2086A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32788 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL6P-0007i4-RV for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:45:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44162) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKq7-00016l-W1 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKq5-0004h5-Hg for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40788) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpy-0004Zt-11; Fri, 20 Sep 2019 11:28:47 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EFDB2308FC4D; Fri, 20 Sep 2019 15:28:41 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5E3E25D9E5; Fri, 20 Sep 2019 15:28:41 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 15/22] mirror: Prevent loops Date: Fri, 20 Sep 2019 17:27:57 +0200 Message-Id: <20190920152804.12875-16-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 20 Sep 2019 15:28:42 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" While bdrv_replace_node() will not follow through with it, a specific @replaces asks the mirror job to create a loop. For example, say both the source and the target share a child where the source is a filter; by letting @replaces point to the common child, you ask for a loop. Or if you use @replaces in drive-mirror with sync=none and mode=absolute-paths, you generally ask for a loop (@replaces must point to a child of the source, and sync=none makes the source the backing file of the target after the job). bdrv_replace_node() will not create those loops, but it by doing so, it ignores the user-requested configuration, which is not ideally either. (In the first example above, the target's child will remain what it was, which may still be reasonable. But in the second example, the target will just not become a child of the source, which is precisely what was requested with @replaces.) So prevent such configurations, both before the job, and before it actually completes. Signed-off-by: Max Reitz --- include/block/block_int.h | 3 +++ block.c | 30 ++++++++++++++++++++++++ block/mirror.c | 19 +++++++++++++++- blockdev.c | 48 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 98 insertions(+), 2 deletions(-) diff --git a/include/block/block_int.h b/include/block/block_int.h index 70f26530c9..8a26a0d88a 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -1256,6 +1256,9 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c, bool bdrv_recurse_can_replace(BlockDriverState *bs, BlockDriverState *to_replace); +bool bdrv_is_child_of(BlockDriverState *child, BlockDriverState *parent, + int min_level); + /* * Default implementation for drivers to pass bdrv_co_block_status() to * their file. diff --git a/block.c b/block.c index 0d9b3de98f..332191fb47 100644 --- a/block.c +++ b/block.c @@ -6260,6 +6260,36 @@ out: return to_replace_bs; } +/* + * Return true iff @child is a (recursive) child of @parent, with at + * least @min_level edges between them. + * + * (If @min_level == 0, return true if @child == @parent. For + * @min_level == 1, @child needs to be at least a real child; for + * @min_level == 2, it needs to be at least a grand-child; and so on.) + */ +bool bdrv_is_child_of(BlockDriverState *child, BlockDriverState *parent, + int min_level) +{ + BdrvChild *c; + + if (child == parent && min_level <= 0) { + return true; + } + + if (!parent) { + return false; + } + + QLIST_FOREACH(c, &parent->children, next) { + if (bdrv_is_child_of(child, c->bs, min_level - 1)) { + return true; + } + } + + return false; +} + /** * Iterates through the list of runtime option keys that are said to * be "strong" for a BDS. An option is called "strong" if it changes diff --git a/block/mirror.c b/block/mirror.c index d877637e1e..f30a6933d8 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -701,7 +701,24 @@ static int mirror_exit_common(Job *job) * there. */ if (bdrv_recurse_can_replace(src, to_replace)) { - bdrv_replace_node(to_replace, target_bs, &local_err); + /* + * It is OK for @to_replace to be an immediate child of + * @target_bs, because that is what happens with + * drive-mirror sync=none mode=absolute-paths: target_bs's + * backing file will be the source node, which is also + * to_replace (by default). + * bdrv_replace_node() handles this case by not letting + * target_bs->backing point to itself, but to the source + * still. + */ + if (!bdrv_is_child_of(to_replace, target_bs, 2)) { + bdrv_replace_node(to_replace, target_bs, &local_err); + } else { + error_setg(&local_err, "Can no longer replace '%s' by '%s', " + "because the former is now a child of the latter, " + "and doing so would thus create a loop", + to_replace->node_name, target_bs->node_name); + } } else { error_setg(&local_err, "Can no longer replace '%s' by '%s', " "because it can no longer be guaranteed that doing so " diff --git a/blockdev.c b/blockdev.c index 0420bc29be..27344247d5 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3845,7 +3845,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, } if (has_replaces) { - BlockDriverState *to_replace_bs; + BlockDriverState *to_replace_bs, *target_backing_bs; AioContext *replace_aio_context; int64_t bs_size, replace_size; @@ -3860,6 +3860,52 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, return; } + if (bdrv_is_child_of(to_replace_bs, target, 1)) { + error_setg(errp, "Replacing %s by %s would result in a loop, " + "because the former is a child of the latter", + to_replace_bs->node_name, target->node_name); + return; + } + + if (backing_mode == MIRROR_SOURCE_BACKING_CHAIN || + backing_mode == MIRROR_OPEN_BACKING_CHAIN) + { + /* + * While we do not quite know what OPEN_BACKING_CHAIN + * (used for mode=existing) will yield, it is probably + * best to restrict it exactly like SOURCE_BACKING_CHAIN, + * because that is our best guess. + */ + switch (sync) { + case MIRROR_SYNC_MODE_FULL: + target_backing_bs = NULL; + break; + + case MIRROR_SYNC_MODE_TOP: + target_backing_bs = backing_bs(bs); + break; + + case MIRROR_SYNC_MODE_NONE: + target_backing_bs = bs; + break; + + default: + abort(); + } + } else { + assert(backing_mode == MIRROR_LEAVE_BACKING_CHAIN); + target_backing_bs = backing_bs(target); + } + + if (bdrv_is_child_of(to_replace_bs, target_backing_bs, 0)) { + error_setg(errp, "Replacing '%s' by '%s' with this sync mode would " + "result in a loop, because the former would be a child " + "of the latter's backing file ('%s') after the mirror " + "job", to_replace_bs->node_name, target->node_name, + target_backing_bs->node_name); + return; + } + replace_aio_context = bdrv_get_aio_context(to_replace_bs); aio_context_acquire(replace_aio_context); replace_size = bdrv_getlength(to_replace_bs); From patchwork Fri Sep 20 15:27:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154643 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0620914ED for ; Fri, 20 Sep 2019 16:07:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id DAB43206B6 for ; Fri, 20 Sep 2019 16:07:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DAB43206B6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32998 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLRF-0000WV-Vq for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 12:07:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44160) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKq7-00016j-S2 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKq5-0004hS-Kd for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:15065) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpz-0004au-Nv; Fri, 20 Sep 2019 11:28:47 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4950810C0928; Fri, 20 Sep 2019 15:28:44 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D566A60C80; Fri, 20 Sep 2019 15:28:43 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 16/22] iotests: Use complete_and_wait() in 155 Date: Fri, 20 Sep 2019 17:27:58 +0200 Message-Id: <20190920152804.12875-17-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.66]); Fri, 20 Sep 2019 15:28:44 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This way, we get to see errors during the completion phase. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/155 | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/qemu-iotests/155 b/tests/qemu-iotests/155 index e19485911c..d7ef2579d3 100755 --- a/tests/qemu-iotests/155 +++ b/tests/qemu-iotests/155 @@ -163,12 +163,7 @@ class MirrorBaseClass(BaseClass): self.assert_qmp(result, 'return', {}) - self.vm.event_wait('BLOCK_JOB_READY') - - result = self.vm.qmp('block-job-complete', device='mirror-job') - self.assert_qmp(result, 'return', {}) - - self.vm.event_wait('BLOCK_JOB_COMPLETED') + self.complete_and_wait('mirror-job') def testFull(self): self.runMirror('full') From patchwork Fri Sep 20 15:27:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154599 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EDFB316B1 for ; Fri, 20 Sep 2019 15:45:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id CF582208C0 for ; Fri, 20 Sep 2019 15:45:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CF582208C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32786 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBL5y-0007Os-GU for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:45:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44159) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKq8-00016i-04 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKq5-0004hX-LZ for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45400) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKpz-0004dk-SV; Fri, 20 Sep 2019 11:28:49 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 924F410CC1E6; Fri, 20 Sep 2019 15:28:46 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2A2C319C5B; Fri, 20 Sep 2019 15:28:45 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 17/22] iotests: Add VM.assert_block_path() Date: Fri, 20 Sep 2019 17:27:59 +0200 Message-Id: <20190920152804.12875-18-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.65]); Fri, 20 Sep 2019 15:28:46 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Max Reitz --- tests/qemu-iotests/iotests.py | 48 +++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index daed4ee013..e6fb46287d 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -670,6 +670,54 @@ class VM(qtest.QEMUQtestMachine): return fields.items() <= ret.items() + ''' + @path is a string whose components are separated by slashes. + The first component is a node name, the rest are child names. + Examples: + - "qcow2-node/backing/file" + - "quorum-node/children.2/file" + + @expected_node may be None. + + @graph may be None or the result of an x-debug-query-block-graph + call that has already been performed. + ''' + def assert_block_path(self, path, expected_node, graph=None): + if graph is None: + graph = self.qmp('x-debug-query-block-graph')['return'] + + iter_path = iter(path.split('/')) + root = next(iter_path) + try: + node = next(node for node in graph['nodes'] if node['name'] == root) + except StopIteration: + node = None + + for path_node in iter_path: + assert node is not None, 'Cannot follow path %s' % path + + try: + node_id = next(edge['child'] for edge in graph['edges'] \ + if edge['parent'] == node['id'] and + edge['name'] == path_node) + + node = next(node for node in graph['nodes'] \ + if node['id'] == node_id) + except StopIteration: + node = None + + assert node is not None or expected_node is None, \ + 'No node found under %s (but expected %s)' % \ + (path, expected_node) + + assert expected_node is not None or node is None, \ + 'Found node %s under %s (but expected none)' % \ + (node['name'], path) + + if node is not None and expected_node is not None: + assert node['name'] == expected_node, \ + 'Found node %s under %s (but expected %s)' % \ + (node['name'], path, expected_node) index_re = re.compile(r'([^\[]+)\[([^\]]+)\]') From patchwork Fri Sep 20 15:28:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154607 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BDBA314DB for ; Fri, 20 Sep 2019 15:51:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9EC10208C3 for ; Fri, 20 Sep 2019 15:51:52 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9EC10208C3 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32828 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLCI-0003PL-Ja for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:51:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44198) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKq9-00018U-CE for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKq7-0004ib-RQ for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:48966) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKq1-0004f1-Qu; Fri, 20 Sep 2019 11:28:50 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DA1B218C8919; Fri, 20 Sep 2019 15:28:48 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 732DF5D6A7; Fri, 20 Sep 2019 15:28:48 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 18/22] iotests: Resolve TODOs in 041 Date: Fri, 20 Sep 2019 17:28:00 +0200 Message-Id: <20190920152804.12875-19-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 20 Sep 2019 15:28:48 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/041 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index d91f538276..ca126de3ff 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -921,8 +921,7 @@ class TestRepairQuorum(iotests.QMPTestCase): self.complete_and_wait(drive="job0") self.assert_has_block_node("repair0", quorum_repair_img) - # TODO: a better test requiring some QEMU infrastructure will be added - # to check that this file is really driven by quorum + self.vm.assert_block_path('quorum0/children.1', 'repair0') self.vm.shutdown() self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img), 'target image does not match source after mirroring') @@ -1074,9 +1073,7 @@ class TestRepairQuorum(iotests.QMPTestCase): self.complete_and_wait('job0') self.assert_has_block_node("repair0", quorum_repair_img) - # TODO: a better test requiring some QEMU infrastructure will be added - # to check that this file is really driven by quorum - self.vm.shutdown() + self.vm.assert_block_path('quorum0/children.1', 'repair0') # Test mirroring with a source that does not have any parents (not even a # BlockBackend) From patchwork Fri Sep 20 15:28:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154647 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D771414ED for ; Fri, 20 Sep 2019 16:11:10 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B7C91206B6 for ; Fri, 20 Sep 2019 16:11:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B7C91206B6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:33080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLUz-0005PG-7u for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 12:11:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44248) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKqC-0001C5-4E for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKqA-0004lV-E5 for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:28:59 -0400 Received: from mx1.redhat.com ([209.132.183.28]:54210) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKq5-0004g4-MO; Fri, 20 Sep 2019 11:28:55 -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 2ED4730832DC; Fri, 20 Sep 2019 15:28:51 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id BDDEE5C220; Fri, 20 Sep 2019 15:28:50 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 19/22] iotests: Use self.image_len in TestRepairQuorum Date: Fri, 20 Sep 2019 17:28:01 +0200 Message-Id: <20190920152804.12875-20-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Fri, 20 Sep 2019 15:28:51 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" 041's TestRepairQuorum has its own image_len, no need to refer to TestSingleDrive. (This patch allows uncommenting TestSingleDrive to speed up 041 during test testing.) Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/041 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index ca126de3ff..20ae9750b7 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -880,7 +880,7 @@ class TestRepairQuorum(iotests.QMPTestCase): # Add each individual quorum images for i in self.IMAGES: qemu_img('create', '-f', iotests.imgfmt, i, - str(TestSingleDrive.image_len)) + str(self.image_len)) # Assign a node name to each quorum image in order to manipulate # them opts = "node-name=img%i" % self.IMAGES.index(i) From patchwork Fri Sep 20 15:28:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154655 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1D00C912 for ; Fri, 20 Sep 2019 16:14:11 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F191D206B6 for ; Fri, 20 Sep 2019 16:14:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F191D206B6 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:33141 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLXt-0000Wh-68 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 12:14:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44285) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKqD-0001Eb-Oj for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKqC-0004mW-2s for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33956) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKq7-0004hf-Nz; Fri, 20 Sep 2019 11:28:55 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 839E78980F5; Fri, 20 Sep 2019 15:28:53 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1D8EA60167; Fri, 20 Sep 2019 15:28:52 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 20/22] iotests: Add tests for invalid Quorum @replaces Date: Fri, 20 Sep 2019 17:28:02 +0200 Message-Id: <20190920152804.12875-21-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.67]); Fri, 20 Sep 2019 15:28:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Add two tests to see that you cannot replace a Quorum child with the mirror job while the child is in use by a different parent. Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/041 | 57 +++++++++++++++++++++++++++++++++++++- tests/qemu-iotests/041.out | 4 +-- 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 20ae9750b7..148dc47ce4 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -34,6 +34,8 @@ quorum_img3 = os.path.join(iotests.test_dir, 'quorum3.img') quorum_repair_img = os.path.join(iotests.test_dir, 'quorum_repair.img') quorum_snapshot_file = os.path.join(iotests.test_dir, 'quorum_snapshot.img') +nbd_sock_path = os.path.join(iotests.test_dir, 'nbd.sock') + class TestSingleDrive(iotests.QMPTestCase): image_len = 1 * 1024 * 1024 # MB qmp_cmd = 'drive-mirror' @@ -901,7 +903,8 @@ class TestRepairQuorum(iotests.QMPTestCase): def tearDown(self): self.vm.shutdown() - for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file ]: + for i in self.IMAGES + [ quorum_repair_img, quorum_snapshot_file, + nbd_sock_path ]: # Do a try/except because the test may have deleted some images try: os.remove(i) @@ -1075,6 +1078,58 @@ class TestRepairQuorum(iotests.QMPTestCase): self.assert_has_block_node("repair0", quorum_repair_img) self.vm.assert_block_path('quorum0/children.1', 'repair0') + ''' + Check that we cannot replace a Quorum child when it has other + parents. + ''' + def test_with_other_parent(self): + result = self.vm.qmp('nbd-server-start', + addr={ + 'type': 'unix', + 'data': {'path': nbd_sock_path} + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('nbd-server-add', device='img1') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0', + sync='full', node_name='repair0', replaces='img1', + target=quorum_repair_img, format=iotests.imgfmt) + self.assert_qmp(result, 'error/desc', + "Cannot replace 'img1' by a node mirrored from " + "'quorum0', because it cannot be guaranteed that doing " + "so would not lead to an abrupt change of visible data") + + ''' + The same as test_with_other_parent(), but add the NBD server only + when the mirror job is already running. + ''' + def test_with_other_parents_after_mirror_start(self): + result = self.vm.qmp('nbd-server-start', + addr={ + 'type': 'unix', + 'data': {'path': nbd_sock_path} + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('drive-mirror', job_id='mirror', device='quorum0', + sync='full', node_name='repair0', replaces='img1', + target=quorum_repair_img, format=iotests.imgfmt) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('nbd-server-add', device='img1') + self.assert_qmp(result, 'return', {}) + + # The full error message goes to stderr, so we unfortunately + # cannot check it here + self.complete_and_wait('mirror', + completion_error='Operation not permitted') + + # Should not have been replaced + self.vm.assert_block_path('quorum0/children.1', 'img1') + + # Test mirroring with a source that does not have any parents (not even a # BlockBackend) class TestOrphanedSource(iotests.QMPTestCase): diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index f496be9197..ffc779b4d1 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -........................................................................................... +............................................................................................. ---------------------------------------------------------------------- -Ran 91 tests +Ran 93 tests OK From patchwork Fri Sep 20 15:28:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154611 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8A66916B1 for ; Fri, 20 Sep 2019 15:52:16 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6B22A2086A for ; Fri, 20 Sep 2019 15:52:16 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6B22A2086A Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32832 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLCg-0003pg-Oz for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:52:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44276) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKqD-0001E1-6b for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKqB-0004mL-RA for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:01 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49031) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKq8-0004ix-IS; Fri, 20 Sep 2019 11:28:56 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CFCE818C7780; Fri, 20 Sep 2019 15:28:55 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 693C35D6A7; Fri, 20 Sep 2019 15:28:55 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 21/22] iotests: Check that @replaces can replace filters Date: Fri, 20 Sep 2019 17:28:03 +0200 Message-Id: <20190920152804.12875-22-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.70]); Fri, 20 Sep 2019 15:28:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/041 | 45 ++++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/041.out | 4 ++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 148dc47ce4..e4cc829fe2 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -1220,6 +1220,51 @@ class TestOrphanedSource(iotests.QMPTestCase): self.assertFalse('mirror-filter' in nodes, 'Mirror filter node did not disappear') +# Test cases for @replaces that do not necessarily involve Quorum +class TestReplaces(iotests.QMPTestCase): + # Each of these test cases needs their own block graph, so do not + # create any nodes here + def setUp(self): + self.vm = iotests.VM() + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + for img in (test_img, target_img): + try: + os.remove(img) + except OSError: + pass + + ''' + Check that we can replace filter nodes. + ''' + def test_replace_filter(self): + result = self.vm.qmp('blockdev-add', **{ + 'driver': 'copy-on-read', + 'node-name': 'filter0', + 'file': { + 'driver': 'copy-on-read', + 'node-name': 'filter1', + 'file': { + 'driver': 'null-co' + } + } + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', + node_name='target', driver='null-co') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-mirror', job_id='mirror', device='filter0', + target='target', sync='full', replaces='filter1') + self.assert_qmp(result, 'return', {}) + + self.complete_and_wait('mirror') + + self.vm.assert_block_path('filter0/file', 'target') + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed'], supported_protocols=['file']) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index ffc779b4d1..877b76fd31 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -............................................................................................. +.............................................................................................. ---------------------------------------------------------------------- -Ran 93 tests +Ran 94 tests OK From patchwork Fri Sep 20 15:28:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 11154615 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BA85D14DB for ; Fri, 20 Sep 2019 15:55:58 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 9B7BA20644 for ; Fri, 20 Sep 2019 15:55:58 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9B7BA20644 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:32880 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBLGH-00080B-9L for patchwork-qemu-devel@patchwork.kernel.org; Fri, 20 Sep 2019 11:55:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44321) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iBKqG-0001Io-HF for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iBKqF-0004nz-0B for qemu-devel@nongnu.org; Fri, 20 Sep 2019 11:29:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33974) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iBKqB-0004lZ-0M; Fri, 20 Sep 2019 11:28:59 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 509148980EA; Fri, 20 Sep 2019 15:28:58 +0000 (UTC) Received: from localhost (unknown [10.40.205.102]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B25255D9C3; Fri, 20 Sep 2019 15:28:57 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH 22/22] iotests: Mirror must not attempt to create loops Date: Fri, 20 Sep 2019 17:28:04 +0200 Message-Id: <20190920152804.12875-23-mreitz@redhat.com> In-Reply-To: <20190920152804.12875-1-mreitz@redhat.com> References: <20190920152804.12875-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.67]); Fri, 20 Sep 2019 15:28:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Max Reitz --- tests/qemu-iotests/041 | 152 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/041.out | 4 +- 2 files changed, 154 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index e4cc829fe2..6ea4764ae8 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -1265,6 +1265,158 @@ class TestReplaces(iotests.QMPTestCase): self.vm.assert_block_path('filter0/file', 'target') + ''' + See what happens when the @sync/@replaces configuration dictates + creating a loop. + ''' + def test_loop(self): + qemu_img('create', '-f', iotests.imgfmt, test_img, str(1 * 1024 * 1024)) + + # Dummy group so we can create a NOP filter + result = self.vm.qmp('object-add', qom_type='throttle-group', id='tg0') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', **{ + 'driver': 'throttle', + 'node-name': 'source', + 'throttle-group': 'tg0', + 'file': { + 'driver': iotests.imgfmt, + 'node-name': 'filtered', + 'file': { + 'driver': 'file', + 'filename': test_img + } + } + }) + self.assert_qmp(result, 'return', {}) + + # Block graph is now: + # source[throttle] --file--> filtered[qcow2] --file--> ... + + result = self.vm.qmp('drive-mirror', job_id='mirror', device='source', + target=target_img, format=iotests.imgfmt, + node_name='target', sync='none', + replaces='filtered') + + ''' + Block graph before mirror exits would be (ignoring mirror_top): + source[throttle] --file--> filtered[qcow2] --file--> ... + target[qcow2] --file--> ... + + Then, because of sync=none and drive-mirror in absolute-paths mode, + the source is attached to the target: + source[throttle] --file--> filtered[qcow2] --file--> ... + ^ + backing + | + target[qcow2] --file--> ... + + Replacing filtered by target would yield: + source[throttle] --file--> target[qcow2] --file--> ... + ^ | + +------- backing --------+ + + I.e., a loop. bdrv_replace_node() detects this and simply + does not let source's file link point to target. However, + that means that target cannot really replace source. + + drive-mirror should detect this and not allow this case. + ''' + + self.assert_qmp(result, 'error/desc', + "Replacing 'filtered' by 'target' with this sync " + \ + "mode would result in a loop, because the former " + \ + "would be a child of the latter's backing file " + \ + "('source') after the mirror job") + + ''' + Test what happens when there would be no loop with the pre-mirror + configuration, but something changes during the mirror job that asks + for a loop to be created during completion. + ''' + def test_loop_during_mirror(self): + qemu_img('create', '-f', iotests.imgfmt, test_img, str(1 * 1024 * 1024)) + + result = self.vm.qmp('blockdev-add', **{ + 'driver': 'null-co', + 'node-name': 'common-base', + 'read-zeroes': True, + 'size': 1 * 1024 * 1024 + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-add', **{ + 'driver': 'copy-on-read', + 'node-name': 'source', + 'file': 'common-base' + }) + self.assert_qmp(result, 'return', {}) + + ''' + x-blockdev-change can only add children to a quorum node that + have no parent yet, so we need an intermediate node between + target and common-base that has no parents other than target. + We cannot use any parent that would forward the RESIZE + permission (because the job takes it, but unshares it on the + source), so we make it a backing child of a qcow2 node. + Unfortunately, we cannot add backing files to Quorum nodes + (because of an op blocker), so we put another raw node between + the qcow2 node and common-base. + ''' + result = self.vm.qmp('blockdev-add', **{ + 'driver': 'qcow2', + 'node-name': 'base-parent', + 'file': { + 'driver': 'file', + 'filename': test_img + }, + 'backing': { + 'driver': 'raw', + 'file': 'common-base' + } + }) + + # Add a quorum node with a single child, we will add + # base-parent to prepare a loop later + result = self.vm.qmp('blockdev-add', **{ + 'driver': 'quorum', + 'node-name': 'target', + 'vote-threshold': 1, + 'children': [ + { + 'driver': 'null-co', + 'read-zeroes': True + } + ] + }) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('blockdev-mirror', job_id='mirror', + device='source', target='target', sync='full', + replaces='common-base') + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('x-blockdev-change', + parent='target', node='base-parent') + self.assert_qmp(result, 'return', {}) + + ''' + This asks for this configuration post-mirror: + + source -> target (replaced common-base) -> base-parent + ^ | + | v + +----------------- [raw] + + bdrv_replace_node() would not allow such a configuration, but + we should not pretend we can create it, so the mirror job + should fail during completion. + ''' + + self.complete_and_wait('mirror', + completion_error='Operation not permitted') + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed'], supported_protocols=['file']) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index 877b76fd31..20a8158b99 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -.............................................................................................. +................................................................................................ ---------------------------------------------------------------------- -Ran 94 tests +Ran 96 tests OK