From patchwork Thu Oct 6 13:02:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 9364771 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 932546075E for ; Thu, 6 Oct 2016 13:11:00 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8501128558 for ; Thu, 6 Oct 2016 13:11:00 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7996D28FE0; Thu, 6 Oct 2016 13:11:00 +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 8D22B28558 for ; Thu, 6 Oct 2016 13:10:59 +0000 (UTC) Received: from localhost ([::1]:55972 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8Ru-0003Zq-L7 for patchwork-qemu-devel@patchwork.kernel.org; Thu, 06 Oct 2016 09:10:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33244) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8Kf-0005jW-QJ for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:03:34 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bs8KZ-00018a-8D for qemu-devel@nongnu.org; Thu, 06 Oct 2016 09:03:29 -0400 Received: from smtp3.mundo-r.com ([212.51.32.191]:63646 helo=smtp4.mundo-r.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bs8KY-00018C-Rr; Thu, 06 Oct 2016 09:03:23 -0400 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2A8AgCgSvZX/5tjdVtdHQEFAQsBgz0BAQEBAR5XfI0ylV0BAQUBgRaSIYIPggsehgICgX84FAECAQEBAQEBAV4nhGICBCdSED8SPBsZiFIBvmEBAQgohXKCT4ZgB3yFEwWPLoRihW+GKIlTgW5Oh1CBA4RlkHYeNj8FB4IZUhyBVm+GEYIvAQEB X-IPAS-Result: A2A8AgCgSvZX/5tjdVtdHQEFAQsBgz0BAQEBAR5XfI0ylV0BAQUBgRaSIYIPggsehgICgX84FAECAQEBAQEBAV4nhGICBCdSED8SPBsZiFIBvmEBAQgohXKCT4ZgB3yFEwWPLoRihW+GKIlTgW5Oh1CBA4RlkHYeNj8FB4IZUhyBVm+GEYIvAQEB X-IronPort-AV: E=Sophos;i="5.31,454,1473112800"; d="scan'208";a="195926144" Received: from fanzine.igalia.com ([91.117.99.155]) by smtp4.mundo-r.com with ESMTP; 06 Oct 2016 15:03:19 +0200 Received: from a88-114-146-170.elisa-laajakaista.fi ([88.114.146.170] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim) id 1bs8KU-0001gM-S5; Thu, 06 Oct 2016 15:03:19 +0200 Received: from berto by perseus.local with local (Exim 4.87) (envelope-from ) id 1bs8KH-0007Xo-G8; Thu, 06 Oct 2016 16:03:05 +0300 From: Alberto Garcia To: qemu-devel@nongnu.org Date: Thu, 6 Oct 2016 16:02:51 +0300 Message-Id: <7e86a00cdda718d14f583e3228ecb1524396b21b.1475757437.git.berto@igalia.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 212.51.32.191 Subject: [Qemu-devel] [PATCH v10 08/16] block: Support streaming to an intermediate layer 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: Kevin Wolf , Alberto Garcia , qemu-block@nongnu.org, Markus Armbruster , Max Reitz , Stefan Hajnoczi Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This makes sure that the image we are streaming into is open in read-write mode during the operation. Operation blockers are also set in all intermediate nodes, since they will be removed from the chain afterwards. Finally, this also unblocks the stream operation in backing files. Signed-off-by: Alberto Garcia --- block.c | 4 +++- block/stream.c | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/block.c b/block.c index c80b528..8255d75 100644 --- a/block.c +++ b/block.c @@ -1428,9 +1428,11 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) backing_hd->drv ? backing_hd->drv->format_name : ""); bdrv_op_block_all(backing_hd, bs->backing_blocker); - /* Otherwise we won't be able to commit due to check in bdrv_commit */ + /* Otherwise we won't be able to commit or stream */ bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET, bs->backing_blocker); + bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_STREAM, + bs->backing_blocker); /* * We do backup in 3 ways: * 1. drive backup diff --git a/block/stream.c b/block/stream.c index 3187481..b8ab89a 100644 --- a/block/stream.c +++ b/block/stream.c @@ -37,6 +37,7 @@ typedef struct StreamBlockJob { BlockDriverState *base; BlockdevOnError on_error; char *backing_file_str; + int bs_flags; } StreamBlockJob; static int coroutine_fn stream_populate(BlockBackend *blk, @@ -81,6 +82,11 @@ static void stream_complete(BlockJob *job, void *opaque) bdrv_set_backing_hd(bs, base); } + /* Reopen the image back in read-only mode if necessary */ + if (s->bs_flags != bdrv_get_flags(bs)) { + bdrv_reopen(bs, s->bs_flags, NULL); + } + g_free(s->backing_file_str); block_job_completed(&s->common, data->ret); g_free(data); @@ -220,6 +226,8 @@ void stream_start(const char *job_id, BlockDriverState *bs, BlockCompletionFunc *cb, void *opaque, Error **errp) { StreamBlockJob *s; + BlockDriverState *iter; + int orig_bs_flags; s = block_job_create(job_id, &stream_job_driver, bs, speed, cb, opaque, errp); @@ -227,8 +235,24 @@ void stream_start(const char *job_id, BlockDriverState *bs, return; } + /* Make sure that the image is opened in read-write mode */ + orig_bs_flags = bdrv_get_flags(bs); + if (!(orig_bs_flags & BDRV_O_RDWR)) { + if (bdrv_reopen(bs, orig_bs_flags | BDRV_O_RDWR, errp) != 0) { + block_job_unref(&s->common); + return; + } + } + + /* Block all intermediate nodes between bs and base, because they + * will disappear from the chain after this operation */ + for (iter = backing_bs(bs); iter && iter != base; iter = backing_bs(iter)) { + block_job_add_bdrv(&s->common, iter); + } + s->base = base; s->backing_file_str = g_strdup(backing_file_str); + s->bs_flags = orig_bs_flags; s->on_error = on_error; s->common.co = qemu_coroutine_create(stream_run, s);