From patchwork Fri Jan 20 03:47:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhanghailiang X-Patchwork-Id: 9527247 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 C4F8060434 for ; Fri, 20 Jan 2017 03:53:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B45F0285D8 for ; Fri, 20 Jan 2017 03:53:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A5FB0285F5; Fri, 20 Jan 2017 03:53:44 +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 1B859285D8 for ; Fri, 20 Jan 2017 03:53:44 +0000 (UTC) Received: from localhost ([::1]:52384 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cUQGl-0000Pe-4k for patchwork-qemu-devel@patchwork.kernel.org; Thu, 19 Jan 2017 22:53:43 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46853) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cUQCC-0005Q8-S5 for qemu-devel@nongnu.org; Thu, 19 Jan 2017 22:49:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cUQCB-0006hE-Km for qemu-devel@nongnu.org; Thu, 19 Jan 2017 22:49:00 -0500 Received: from szxga03-in.huawei.com ([119.145.14.66]:27507) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1cUQC5-0006V0-0R; Thu, 19 Jan 2017 22:48:53 -0500 Received: from 172.24.1.137 (EHLO SZXEML423-HUB.china.huawei.com) ([172.24.1.137]) by szxrg03-dlp.huawei.com (MOS 4.4.3-GA FastPath queued) with ESMTP id COG95625; Fri, 20 Jan 2017 11:48:41 +0800 (CST) Received: from localhost (10.177.24.212) by SZXEML423-HUB.china.huawei.com (10.82.67.154) with Microsoft SMTP Server id 14.3.235.1; Fri, 20 Jan 2017 11:48:33 +0800 From: zhanghailiang To: , Date: Fri, 20 Jan 2017 11:47:59 +0800 Message-ID: <1484884080-28836-6-git-send-email-zhang.zhanghailiang@huawei.com> X-Mailer: git-send-email 2.7.2.windows.1 In-Reply-To: <1484884080-28836-1-git-send-email-zhang.zhanghailiang@huawei.com> References: <1484884080-28836-1-git-send-email-zhang.zhanghailiang@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.24.212] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] [fuzzy] X-Received-From: 119.145.14.66 Subject: [Qemu-devel] [PATCH v3 5/6] replication: Implement block replication for shared disk case 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, xuquan8@huawei.com, xiecl.fnst@cn.fujitsu.com, Wen Congyang , qemu-block@nongnu.org, zhangchen.fnst@cn.fujitsu.com, mreitz@redhat.com, zhanghailiang Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Just as the scenario of non-shared disk block replication, we are going to implement block replication from many basic blocks that are already in QEMU. The architecture is: virtio-blk || .---------- / || | Secondary / || '---------- / || virtio-blk / || | | || replication(5) | NBD --------> NBD (2) | | client || server ---> hidden disk <-- active disk(4) | ^ || | | replication(1) || | | | || | | +-----------------' || | (3) |drive-backup sync=none || | --------. | +-----------------+ || | Primary | | | || backing | --------' | | || | V | | +-------------------------------------------+ | | shared disk | <----------+ +-------------------------------------------+ 1) Primary writes will read original data and forward it to Secondary QEMU. 2) The hidden-disk is created automatically. It buffers the original content that is modified by the primary VM. It should also be an empty disk, and the driver supports bdrv_make_empty() and backing file. 3) Primary write requests will be written to Shared disk. 4) Secondary write requests will be buffered in the active disk and it will overwrite the existing sector content in the buffer. Signed-off-by: zhanghailiang Signed-off-by: Wen Congyang Signed-off-by: Zhang Chen --- block/replication.c | 48 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/block/replication.c b/block/replication.c index 70ec08c..a0b3e41 100644 --- a/block/replication.c +++ b/block/replication.c @@ -233,7 +233,7 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs, QEMUIOVector *qiov) { BDRVReplicationState *s = bs->opaque; - BdrvChild *child = s->secondary_disk; + BdrvChild *child = s->is_shared_disk ? s->primary_disk : s->secondary_disk; BlockJob *job = NULL; CowRequest req; int ret; @@ -415,7 +415,12 @@ static void backup_job_completed(void *opaque, int ret) s->error = -EIO; } - backup_job_cleanup(bs); + if (s->mode == REPLICATION_MODE_PRIMARY) { + s->replication_state = BLOCK_REPLICATION_DONE; + s->error = 0; + } else { + backup_job_cleanup(bs); + } } static bool check_top_bs(BlockDriverState *top_bs, BlockDriverState *bs) @@ -467,6 +472,19 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, switch (s->mode) { case REPLICATION_MODE_PRIMARY: + if (s->is_shared_disk) { + job = backup_job_create(NULL, s->primary_disk->bs, bs, 0, + MIRROR_SYNC_MODE_NONE, NULL, false, BLOCKDEV_ON_ERROR_REPORT, + BLOCKDEV_ON_ERROR_REPORT, BLOCK_JOB_INTERNAL, + backup_job_completed, bs, NULL, &local_err); + if (local_err) { + error_propagate(errp, local_err); + backup_job_cleanup(bs); + aio_context_release(aio_context); + return; + } + block_job_start(job); + } break; case REPLICATION_MODE_SECONDARY: s->active_disk = bs->file; @@ -485,7 +503,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, } s->secondary_disk = s->hidden_disk->bs->backing; - if (!s->secondary_disk->bs || !bdrv_has_blk(s->secondary_disk->bs)) { + if (!s->secondary_disk->bs || + (!s->is_shared_disk && !bdrv_has_blk(s->secondary_disk->bs))) { error_setg(errp, "The secondary disk doesn't have block backend"); aio_context_release(aio_context); return; @@ -580,11 +599,24 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp) switch (s->mode) { case REPLICATION_MODE_PRIMARY: + if (s->is_shared_disk) { + if (!s->primary_disk->bs->job) { + error_setg(errp, "Primary backup job was cancelled" + " unexpectedly"); + break; + } + + backup_do_checkpoint(s->primary_disk->bs->job, &local_err); + if (local_err) { + error_propagate(errp, local_err); + } + } break; case REPLICATION_MODE_SECONDARY: if (!s->is_shared_disk) { if (!s->secondary_disk->bs->job) { - error_setg(errp, "Backup job was cancelled unexpectedly"); + error_setg(errp, "Secondary backup job was cancelled" + " unexpectedly"); break; } backup_do_checkpoint(s->secondary_disk->bs->job, &local_err); @@ -663,8 +695,12 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp) switch (s->mode) { case REPLICATION_MODE_PRIMARY: - s->replication_state = BLOCK_REPLICATION_DONE; - s->error = 0; + if (s->is_shared_disk && s->primary_disk->bs->job) { + block_job_cancel(s->primary_disk->bs->job); + } else { + s->replication_state = BLOCK_REPLICATION_DONE; + s->error = 0; + } break; case REPLICATION_MODE_SECONDARY: /*