From patchwork Tue May 24 13:47:27 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 9133715 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4135B6075E for ; Tue, 24 May 2016 13:56:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 310C42824F for ; Tue, 24 May 2016 13:56:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 25C8828285; Tue, 24 May 2016 13:56:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8C92C2824F for ; Tue, 24 May 2016 13:56:37 +0000 (UTC) Received: from localhost ([::1]:53520 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5Cp2-0001L6-8o for patchwork-qemu-devel@patchwork.kernel.org; Tue, 24 May 2016 09:56:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46150) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5Cgx-0002KA-4U for qemu-devel@nongnu.org; Tue, 24 May 2016 09:48:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1b5Cgq-00055t-0A for qemu-devel@nongnu.org; Tue, 24 May 2016 09:48:14 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49931) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1b5Cgg-00050A-Lr; Tue, 24 May 2016 09:47:58 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3B60EC0718B3; Tue, 24 May 2016 13:47:58 +0000 (UTC) Received: from noname.redhat.com (ovpn-116-43.ams2.redhat.com [10.36.116.43]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u4ODlfTp022386; Tue, 24 May 2016 09:47:56 -0400 From: Kevin Wolf To: qemu-block@nongnu.org Date: Tue, 24 May 2016 15:47:27 +0200 Message-Id: <1464097654-12977-8-git-send-email-kwolf@redhat.com> In-Reply-To: <1464097654-12977-1-git-send-email-kwolf@redhat.com> References: <1464097654-12977-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 24 May 2016 13:47: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 Subject: [Qemu-devel] [PATCH v2 07/14] mirror: Allow target that already has a BlockBackend X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, berto@igalia.com, jcody@redhat.com, qemu-devel@nongnu.org, mreitz@redhat.com, jsnow@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We had to forbid mirroring to a target BDS that already had a BB attached because the node swapping at job completion would add a second BB and we didn't support multiple BBs on a single BDS at the time. Now we do, so we can lift the restriction. As we allow additional BlockBackends for the target, we must expect other users to be sending requests. There may no requests be in flight during the graph modification, so we have to drain those users now. The core part of this patch is a revert of commit 40365552. Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz --- block/mirror.c | 33 ++++++--------------------------- blockdev.c | 4 ---- tests/qemu-iotests/041 | 27 --------------------------- tests/qemu-iotests/041.out | 4 ++-- 4 files changed, 8 insertions(+), 60 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index efca8fc..23aa10e 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -20,7 +20,6 @@ #include "qapi/qmp/qerror.h" #include "qemu/ratelimit.h" #include "qemu/bitmap.h" -#include "qemu/error-report.h" #define SLICE_TIME 100000000ULL /* ns */ #define MAX_IN_FLIGHT 16 @@ -466,24 +465,20 @@ static void mirror_exit(BlockJob *job, void *opaque) to_replace = s->to_replace; } - /* This was checked in mirror_start_job(), but meanwhile one of the - * nodes could have been newly attached to a BlockBackend. */ - if (bdrv_has_blk(to_replace) && bdrv_has_blk(s->target)) { - error_report("block job: Can't create node with two BlockBackends"); - data->ret = -EINVAL; - goto out; - } - if (bdrv_get_flags(s->target) != bdrv_get_flags(to_replace)) { bdrv_reopen(s->target, bdrv_get_flags(to_replace), NULL); } + + /* The mirror job has no requests in flight any more, but we need to + * drain potential other users of the BDS before changing the graph. */ + bdrv_drained_begin(s->target); bdrv_replace_in_backing_chain(to_replace, s->target); + bdrv_drained_end(s->target); + /* We just changed the BDS the job BB refers to */ blk_remove_bs(job->blk); blk_insert_bs(job->blk, src); } - -out: if (s->to_replace) { bdrv_op_unblock_all(s->to_replace, s->replace_blocker); error_free(s->replace_blocker); @@ -807,7 +802,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, bool is_none_mode, BlockDriverState *base) { MirrorBlockJob *s; - BlockDriverState *replaced_bs; if (granularity == 0) { granularity = bdrv_get_default_bitmap_granularity(target); @@ -824,21 +818,6 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, buf_size = DEFAULT_MIRROR_BUF_SIZE; } - /* We can't support this case as long as the block layer can't handle - * multiple BlockBackends per BlockDriverState. */ - if (replaces) { - replaced_bs = bdrv_lookup_bs(replaces, replaces, errp); - if (replaced_bs == NULL) { - return; - } - } else { - replaced_bs = bs; - } - if (bdrv_has_blk(replaced_bs) && bdrv_has_blk(target)) { - error_setg(errp, "Can't create node with two BlockBackends"); - return; - } - s = block_job_create(driver, bs, speed, cb, opaque, errp); if (!s) { return; diff --git a/blockdev.c b/blockdev.c index af0b022..3c06746 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3459,10 +3459,6 @@ static void blockdev_mirror_common(BlockDriverState *bs, if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_MIRROR_TARGET, errp)) { return; } - if (bdrv_has_blk(target)) { - error_setg(errp, "Cannot mirror to an attached block device"); - return; - } if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) { sync = MIRROR_SYNC_MODE_FULL; diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index b1c542f..ed1d9d4 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -207,33 +207,6 @@ class TestSingleBlockdev(TestSingleDrive): test_image_not_found = None test_small_buffer2 = None -class TestBlockdevAttached(iotests.QMPTestCase): - image_len = 1 * 1024 * 1024 # MB - - def setUp(self): - iotests.create_image(backing_img, self.image_len) - qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) - qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, target_img) - self.vm = iotests.VM().add_drive(test_img) - self.vm.launch() - - def tearDown(self): - self.vm.shutdown() - os.remove(test_img) - os.remove(target_img) - - def test_blockdev_attached(self): - self.assert_no_active_block_jobs() - args = {'options': - {'driver': iotests.imgfmt, - 'id': 'drive1', - 'file': { 'filename': target_img, 'driver': 'file' } } } - result = self.vm.qmp("blockdev-add", **args) - self.assert_qmp(result, 'return', {}) - result = self.vm.qmp('blockdev-mirror', device='drive0', sync='full', - target='drive1') - self.assert_qmp(result, 'error/class', 'GenericError') - class TestSingleDriveZeroLength(TestSingleDrive): image_len = 0 test_small_buffer2 = None diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index b67d050..b0cadc8 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -............................................................................ +........................................................................... ---------------------------------------------------------------------- -Ran 76 tests +Ran 75 tests OK