From patchwork Thu Oct 24 14:25:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11210053 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 2BB52139A for ; Thu, 24 Oct 2019 15:33:04 +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 B1B3220650 for ; Thu, 24 Oct 2019 15:33:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=web.de header.i=@web.de header.b="ECteYd6W" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B1B3220650 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:45450 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNf6k-00017m-0X for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 11:33:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38886) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNe46-0008AA-TK for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNe45-0002eS-FD for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:14 -0400 Received: from mout.web.de ([212.227.17.11]:43101) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iNe40-0002RH-07; Thu, 24 Oct 2019 10:26:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1571927139; bh=9FbTgtuzcaCTjHUA8BY5mKaFybBmxQpiWe1iZMpLbP8=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=ECteYd6W7+tp3RAxMUKZ2oADi66QCSQVMtP+Pw595ghY+Rz/s1Idpn3PXaxkT5iO5 Ict4U5HrjWYjyMXkoOFSbRWjUKURK3hDInCIkz3AEcIr6VWeo1ezyPwvHtKSPkA0+d NT7hWX1IqqiSDVhnobU1upEvRUbVNu2+00JFOa6c= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.150]) by smtp.web.de (mrweb103 [213.165.67.124]) with ESMTPSA (Nemesis) id 0LbrZ2-1hgZWx132a-00jMnl; Thu, 24 Oct 2019 16:25:39 +0200 Date: Thu, 24 Oct 2019 16:25:35 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 1/4] block/replication.c: Ignore requests after failover Message-ID: <039d59f89205824273eef070cdfa7d5e94f95697.1571925699.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:N+uedjqvs76OPbOtDsp0z41+9k3NWKoNkTJgPFrKREuJ21iR//o ewMsA3MGKGDnBKEt3mZbmHUiuvusrrzdw6Y0n2g5zVy+pmlKmMrkzg2jG0d4Wfm23cU2QSG 1PcSZwCQ7XchdE9BZ4ki0HxdQNfRMFwHkCFYqs+yWvPBLMcBAdiYmYU2QRcb5FTzNYyexC6 XyG5WFbow66C0VRrgpFWQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:6iDpevWf7ak=:en4MnMBtuJfdrRM62TmJ0B o9lFzlR8nJUrQgAsMGv13tz6cfXNsp1tLlAy+MAOQj3IxjES9VExNgi/pbgwPxMZhgzC3tzFc UKC9aLLupGenudyQ8DkKglJB2tKIcb/8vlKiOEhsa6/0Vi8VKCDK+9Sy5/u0pzNzcqx9Ia3yi kJNhs1DabApFvxmGE/E7TfyvleRTLduQ6oMuYLxfAwdob6jbk9ys46ocp0n5+kN4yZq38eicu gJIFHKR4rhifIooNlHfCnpHevwB6tL3LNE4d4PO4icU5/kIHXKe4uzOuGnuGcag079W+VEgDu y98CiFnbUYiRa1p0Mfo4A6nQzjhX1FCUIxUIAVMj9xid3b/PsQzRfnCyJqrEqvjG1zNkGcQW+ IC1lKzpxZgmMleZEXDBYjZzsYCdcIAWFqB+4WuE3lCjYXFn7ZEk+VFsQmY1qMeaZQyw32lqUT wrJO2HKe+h6p/qW6DfAvgi4QrJgfghHxgCegcVqPWEJN2V2MU2AuHj9PCYXCUUOXNoT7k3UTc cpowuvCYtQHdPELz+SfZ3hxl7dCL030S+gWoJcWGtSBDQkYPwGsEWt95G+r06N5mNxdjx0AKv atRy4Ouqb9CakS+qSxcwFM84OnqI7Dikjo/te+1Iorv/t2nK7Tco0MTOYD5W7HtodyixHcgwu U1sn4ivjcre5EE/kJazkzeIzHpIRAaHAu1m/4nRj+7m2TsjZOA+sqatlHTlgh9G2rFsaOMhCV uB1F04GIjJo2PEBfXPKH8d7lTzIxBPBJd6DmJvq4rrLvLbArCxILiL6c+RVVd+lER6bjDtlqK hptyIBYmYmvfzKiz38E6qv/TvUWWtVMImfAmgcieHq3HAJXfxwDZo6+aOV65+yWmkbvTvFQRE NHgYylI5bTAVP4cAuy3Ur9lzNc8GlIxxsE+A9yAL47o5vSjaZ3pfIHNNeCe7F5S2ygZtjKsui BgaFLwnnkNfIg6IFjwMNIHDBQxgOZhYkI3iMBg12qY7bficlQDcfSSTEuyWPAKV/am5vl10By 5kehvgvJGKGID55kqqhxqq5pHjZQ6pSZ9pXNflEdJ27kXE5Hwrtd5m7Okk5XRRpTF99QQZYno rP4ZsBe3c5pzxcGXCX2qNJ9bD4CBqdIZ9vboE8XJNbZ0ZFs+vdCCSqj2GsSzqBClFq0qHKVvD k720+tEqLBHpocoAfNYEoVVCNNJMrGEes2mVTh115zxAbfPaSfLSxw29gyPVYaCGJ3+1CeaFo UIQyuewuET2/+mlCBMQcp/A9WemIVPFLN1L115R5an2JfQhgGTWMhoVzCUSE= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.11 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 , qemu-block , Wen Congyang , Wen Congyang , Jason Wang , Max Reitz , Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" After failover the Secondary side of replication shouldn't change state, because it now functions as our primary disk. In replication_start, replication_do_checkpoint, replication_stop, ignore the request if current state is BLOCK_REPLICATION_DONE (sucessful failover) or BLOCK_REPLICATION_FAILOVER (failover in progres i.e. currently merging active and hidden images into the base image). Signed-off-by: Lukas Straub Reviewed-by: Zhang Chen Acked-by: Max Reitz --- block/replication.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/block/replication.c b/block/replication.c index 3d4dedddfc..78234d1a04 100644 --- a/block/replication.c +++ b/block/replication.c @@ -454,6 +454,17 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, aio_context_acquire(aio_context); s = bs->opaque; + if (s->stage == BLOCK_REPLICATION_DONE || + s->stage == BLOCK_REPLICATION_FAILOVER) { + /* + * This case happens when a secondary is promoted to primary. + * Ignore the request because the secondary side of replication + * doesn't have to do anything anymore. + */ + aio_context_release(aio_context); + return; + } + if (s->stage != BLOCK_REPLICATION_NONE) { error_setg(errp, "Block replication is running or done"); aio_context_release(aio_context); @@ -577,6 +588,17 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp) aio_context_acquire(aio_context); s = bs->opaque; + if (s->stage == BLOCK_REPLICATION_DONE || + s->stage == BLOCK_REPLICATION_FAILOVER) { + /* + * This case happens when a secondary was promoted to primary. + * Ignore the request because the secondary side of replication + * doesn't have to do anything anymore. + */ + aio_context_release(aio_context); + return; + } + if (s->mode == REPLICATION_MODE_SECONDARY) { secondary_do_checkpoint(s, errp); } @@ -593,7 +615,7 @@ static void replication_get_error(ReplicationState *rs, Error **errp) aio_context_acquire(aio_context); s = bs->opaque; - if (s->stage != BLOCK_REPLICATION_RUNNING) { + if (s->stage == BLOCK_REPLICATION_NONE) { error_setg(errp, "Block replication is not running"); aio_context_release(aio_context); return; @@ -635,6 +657,17 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp) aio_context_acquire(aio_context); s = bs->opaque; + if (s->stage == BLOCK_REPLICATION_DONE || + s->stage == BLOCK_REPLICATION_FAILOVER) { + /* + * This case happens when a secondary was promoted to primary. + * Ignore the request because the secondary side of replication + * doesn't have to do anything anymore. + */ + aio_context_release(aio_context); + return; + } + if (s->stage != BLOCK_REPLICATION_RUNNING) { error_setg(errp, "Block replication is not running"); aio_context_release(aio_context); From patchwork Thu Oct 24 14:25:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11210107 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 157A614E5 for ; Thu, 24 Oct 2019 15:44:41 +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 E022220650 for ; Thu, 24 Oct 2019 15:44:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=web.de header.i=@web.de header.b="lGQgBB/F" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E022220650 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:45580 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNfHy-0006rr-Jh for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 11:44:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38932) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNe4B-0008QB-Vs for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNe4A-0002oC-Nf for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:19 -0400 Received: from mout.web.de ([212.227.15.4]:46739) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iNe47-0002hh-QU; Thu, 24 Oct 2019 10:26:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1571927145; bh=OfJkK2vnGkQe8T1r5KQyutlaZ4TJ+K9pB9jGve8qHNk=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=lGQgBB/FqY7YomFrbayzQXuH0TFlk1D6pOdg3MMZBzvSOpUKRJ5Ry/6AjD0gbQ2/+ i2FDuGDcMBi3vALQypOB54Yl1bmxe2rsH23IYFiCLldK8Ehr0L3/WMpbFb4fm9Kvod TpmAtoMZIZR6XAk4zvqmsf3F75Myo5RAJJLHQ3VM= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.150]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0M6V2p-1i430c1cYF-00yT6q; Thu, 24 Oct 2019 16:25:45 +0200 Date: Thu, 24 Oct 2019 16:25:44 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 2/4] tests/test-replication.c: Add test for for secondary node continuing replication Message-ID: <60b4c574f996824210f7b2282eac030dbe9f9e41.1571925699.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:V5s0lVOsEJp343Q4r+2aot8a5KDekal2vhV757BxhU3szgkIQkk Ca1LIXE/QxcdcWzTALMks8Tc5IOs6LJ1NayoFVk1Ab8qShiZ9UlPxVnIgyf03Z8S8sybf0H NrRtBysges0FuD41IzzWHByVvjcq26AOVYhbc+FESFqdrtNlAEbikvvG3Wq20+IsDx4Rkum UeD1wpNg3cMfSytJoTPSw== X-UI-Out-Filterresults: notjunk:1;V03:K0:uLNgf5N+nB8=:HLa0Py9yOmgtio6ntdlwv3 GkaWct/MAScNOCPofH445DxjJLIbCgte+ZxZneDz5uTKyh1m194AMveo7pwi06N/8NfUCi+Se FGH31cJolgPzmj3wz36sZ2w3uG/y6Qo6iCgiU5D9lVAgnTad1mfjzKjjKHkWpZ1Nsab/bUHdd k85gLY82DqedgsFYv7O0KdfwXquaV6Gh19vh7TFWIgzGX8B6eAvpFErAqxfQbOWT3fKmOY73r VehWk5IFK5DcVjs7uM/sCSkKei4IhuK5syKMy4TKJzq/7F541V+53GIKKZ9GXTuMKLreEvMxG fzSNaud/910YYBMrfAbU4AMzGXKrwwtUErs+GyFsz4Hf2OLWeWWSz6PCjjg+9Z/qYr/tF/Hnh NWgNQdx6QiNXYofyjEGp88y8TvqFY5O8FyP7Mlz1MSGXZf4FyE7Y+L3HxDa5wclJFm0HXk5k7 dF5DpuBznILwENzmvI9XJbdPvgQXjxIdYFy9mMlOOYb6UYKjipoU0rSzSFS837ilJrmAaMQS6 4I964NqijpDJtCm7970FwKPJjhtb6QCBs5z/ABeTZ7TnX/GGrO6Mr0774vUBUUe60yC8nuNck KmmqUAnsRa0CbY1nb9L4/MAWxNQjGt6mYjy5hyAC3VTY+w3taSI3X8qzWINs05fM3DxwBMO3h i/yQIr7ZnN72d3rK8deWl3q1wzCnAWJ247waCP3DgFz4/5vIaZ8gf5ySIVudPA59n9i5Jf0bc Kntd333/fNDzQlMTaUzMoa8WTMhhx5Pfw5ucCGcA7c/p3M+ghOTNtBPA51JpCdZQAi0sC010U Wzx37j7nVgOxJRtzWO3UYte1QwpkDXcG9fRa16Etk+emALczQiKs3g+s3VBfQEaGJ9rhTmAJf oA4M8eWakrzsEfBw01pXLlGyEsJ6RODD+G8EWvR5UODNI2BY0DrumYmOdKU3k1JDd5etKfSz8 vkj77pGQNQhOVOIz9FRaOiTs5sMDtlESukmT42lXYZQCHvGR6UR0y3/bQQyM2ggHNp0FVA+Mq eTNircCbTClk4GlLlLgJmEmAgEJFudVOnPI5f6B3eoC0tPDy/6YbMa1yxGAAwaICqv66VhVmS eL9Xvy+14rRQlBwjC5iIHOxMdNjT04csCMCSQd3rX7iTs+p1X8jr4EHIwQb8O28oLQ3v1SO8P Vhp7VESMdmMgPe5+fODNKz7RZCFVQJt1EZe6IC6Oev7qP2i6yyKVntJ8vAQZCib+YrRzpCnyH WiVOeWvSLoq5KnAMlKsxK71OowocDJwzx/hmvgq3hnThmM0N+DxwDKi3gOq4= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.4 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 , qemu-block , Wen Congyang , Wen Congyang , Jason Wang , Max Reitz , Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" This simulates the case that happens when we resume COLO after failover. Signed-off-by: Lukas Straub --- tests/test-replication.c | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) -- 2.20.1 diff --git a/tests/test-replication.c b/tests/test-replication.c index f085d1993a..8e18ecd998 100644 --- a/tests/test-replication.c +++ b/tests/test-replication.c @@ -489,6 +489,56 @@ static void test_secondary_stop(void) teardown_secondary(); } +static void test_secondary_continuous_replication(void) +{ + BlockBackend *top_blk, *local_blk; + Error *local_err = NULL; + + top_blk = start_secondary(); + replication_start_all(REPLICATION_MODE_SECONDARY, &local_err); + g_assert(!local_err); + + /* write 0x22 to s_local_disk (IMG_SIZE / 2, IMG_SIZE) */ + local_blk = blk_by_name(S_LOCAL_DISK_ID); + test_blk_write(local_blk, 0x22, IMG_SIZE / 2, IMG_SIZE / 2, false); + + /* replication will backup s_local_disk to s_hidden_disk */ + test_blk_read(top_blk, 0x11, IMG_SIZE / 2, + IMG_SIZE / 2, 0, IMG_SIZE, false); + + /* write 0x33 to s_active_disk (0, IMG_SIZE / 2) */ + test_blk_write(top_blk, 0x33, 0, IMG_SIZE / 2, false); + + /* do failover (active commit) */ + replication_stop_all(true, &local_err); + g_assert(!local_err); + + /* it should ignore all requests from now on */ + + /* start after failover */ + replication_start_all(REPLICATION_MODE_PRIMARY, &local_err); + g_assert(!local_err); + + /* checkpoint */ + replication_do_checkpoint_all(&local_err); + g_assert(!local_err); + + /* stop */ + replication_stop_all(true, &local_err); + g_assert(!local_err); + + /* read from s_local_disk (0, IMG_SIZE / 2) */ + test_blk_read(top_blk, 0x33, 0, IMG_SIZE / 2, + 0, IMG_SIZE / 2, false); + + + /* read from s_local_disk (IMG_SIZE / 2, IMG_SIZE) */ + test_blk_read(top_blk, 0x22, IMG_SIZE / 2, + IMG_SIZE / 2, 0, IMG_SIZE, false); + + teardown_secondary(); +} + static void test_secondary_do_checkpoint(void) { BlockBackend *top_blk, *local_blk; @@ -584,6 +634,8 @@ int main(int argc, char **argv) g_test_add_func("/replication/secondary/write", test_secondary_write); g_test_add_func("/replication/secondary/start", test_secondary_start); g_test_add_func("/replication/secondary/stop", test_secondary_stop); + g_test_add_func("/replication/secondary/continuous_replication", + test_secondary_continuous_replication); g_test_add_func("/replication/secondary/do_checkpoint", test_secondary_do_checkpoint); g_test_add_func("/replication/secondary/get_error_all", From patchwork Thu Oct 24 14:25:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11209959 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 2923F13B1 for ; Thu, 24 Oct 2019 14:48:31 +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 E1609205F4 for ; Thu, 24 Oct 2019 14:48:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=web.de header.i=@web.de header.b="D/M17jeY" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E1609205F4 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:44540 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNePU-0002Fp-Vu for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 10:48:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:38903) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNe48-0008DX-6h for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNe46-0002fF-2B for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:16 -0400 Received: from mout.web.de ([212.227.17.11]:57843) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iNe3z-0002T6-Vv; Thu, 24 Oct 2019 10:26:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1571927151; bh=6Uf5G14Now/peaYZfO+y9x/dGzGKbhnBYYKyspPJYcQ=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=D/M17jeYHTyUdlVEzF2vZUmGaAnQQYQJcB/Pm+/2BuuhJBRiQgsT4xvdoG/5wNNLI Y+wz4EnfgS12x426zTxksqA4MZjb9xN99doBAwl5/guWjNVS1csbZEviLCKkrj6aTU nyuSecSVXx7gUps5AXVQe8wRgWr3nM/iYRhZIXHY= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.150]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Mf0pJ-1icpWx31Yn-00OXC5; Thu, 24 Oct 2019 16:25:50 +0200 Date: Thu, 24 Oct 2019 16:25:48 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 3/4] net/filter.c: Add Options to insert filters anywhere in the filter list Message-ID: <08d0f857cead8b41d1dca5168dc9552c843644bd.1571925700.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:LCvjcEZF5weijcqBIA8BP5NO8f3y+5ePDyT69+hhBoud6ZGVa7F x+k0FawAvED/Cwr6HB0/8DZfGNNfuDms2PL1rnAqiigRURhBKbmxdO+H83UFVPt0wzv24F6 CcmCiz3cFbI/K7gyCurViVN1OZV2XClLfFAfqxuws7+rlH1DTaoIawXaeNjT7fuVxKAvU8P NtaAD0AC9hatlnEkSOy1A== X-UI-Out-Filterresults: notjunk:1;V03:K0:NVboErVue28=:HcpN6C5nYdGysiJZUoXyQl tdeJupE6NnP0Nq8gpBEKnmiOhY6P6ZnEA7hxT3TgfTGObYPSZZZo+b/sdG740Cki7BtJg/tMa 6J8DXpQkIToHITIYzbidKOwUOFB/Gk+1pHBYIaS0eKwyM1BxMeYNRUNEznUEmw+3pCnmnvm8y FsHalxdjWgfU3rFrFGwPxC1zaNxHaZu8Ww7isA3+1RcnIfU2sh51URwmEKCkmbL49qI88CFfr AB5ONX7RspbKYqVwzCFKvUa0J6QyAPc3My2jKOGqjanvSMcUWq0N2odtJev5/3X7F/4oBGTDG /mxAgdtjblO67FC46GGcDlZu7Zfh8zSz28/SEBe/UBpTPnBdvtbAd54Sn6ujj7Csx3Y/8DIQr BqIflJKfSdxPG8x6e8c5zLvuSND6YqAVT1gRyMOqcMsH1MkQ73eWqpvaUPwN3Ljh+QZSLUJFu 8nlKuGMYyUjnVx+ydgIHaF9/7LGcpZwG0E5HNIZiqz2NQxp0zYSym2vikK9VETk4toz8axJ8D lu75LHmryk44BFV3FB6rqZtx+ajtW0mDGRwsu5Kfcv0gDN7Cs4enojBoAUSJVNzcjU6StgCos VWVqfP6aCRhM87cBAYJZVfyR0BEZVOWnlGY5E1UpL1lgPDmp8MX64nhu7UF9ShLomuqgyfi0Y CfwmJUoIpbmC8iyatThM2l2mzyZRw64JfexkcNtziCdRtmv1zh6g7MRHNBA0kEE8Nj/AehIeM OOd9C5Y4n/dGYOSf/j2LWcuXlyLmr0JQzxWa146eQgyC5z0TcRkRViBOIin91K3J6FPMoJPbn Va5nAO1OJhM75RgVnvfMKKbK53QmIuhBAO+dFMPJs+IEniE5pYRxFXqRzSWjLfxpXcdEiWSNw 0GmKAtmAXNOMAzDVW4+OM2qg0t1XXTctu/UHMXOZVapXfOlwH/NfLepryrMBMRuxMA/QlMqSc ei7aCpggu3ha07V0DwJhRpPFIcwFgOnWltz1WOTafPgdiACZBgq+o+hnM6SiEGdqFPoVUYzZF D+MYPQUk1xrOHQl3/xonaUeYMMRveVFZN1foi9mhu+rPfc9qvqIuWlwCgxUwbJq2R+KzpuHfR jvSrGNE+Ws02ZuGagE4+nEw0Yv6OlzU1UBZQrOPr739L2zl26M9ceycSe59xwSeUxzPj1PDSR cPNcd1YAns8e/tbiVmBh64vZLV71Y/PMlyZzXY1SLD+hvQJhW1UpkHzd3O/gep5ZK2QGcSDwJ K3Mo8+oSylxzm1N6q5ciSIeY9ROc+V60KzeXekjyT61c/V2l1LudWhtT/tiE= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.11 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 , qemu-block , Wen Congyang , Wen Congyang , Jason Wang , Max Reitz , Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" To switch the Secondary to Primary, we need to insert new filters before the filter-rewriter. Add the options insert= and position= to be able to insert filters anywhere in the filter list. position should be "head" or "tail" to insert at the head or tail of the filter list or it should be "id=" to specify the id of another filter. insert should be either "before" or "behind" to specify where to insert the new filter relative to the one specified with position. Signed-off-by: Lukas Straub Reviewed-by: Zhang Chen --- include/net/filter.h | 2 + net/filter.c | 92 +++++++++++++++++++++++++++++++++++++++++++- qemu-options.hx | 31 ++++++++++++--- 3 files changed, 119 insertions(+), 6 deletions(-) -- 2.20.1 diff --git a/include/net/filter.h b/include/net/filter.h index 49da666ac0..22a723305b 100644 --- a/include/net/filter.h +++ b/include/net/filter.h @@ -62,6 +62,8 @@ struct NetFilterState { NetClientState *netdev; NetFilterDirection direction; bool on; + char *position; + bool insert_before_flag; QTAILQ_ENTRY(NetFilterState) next; }; diff --git a/net/filter.c b/net/filter.c index 28d1930db7..cd2ef9e979 100644 --- a/net/filter.c +++ b/net/filter.c @@ -171,11 +171,47 @@ static void netfilter_set_status(Object *obj, const char *str, Error **errp) } } +static char *netfilter_get_position(Object *obj, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + return g_strdup(nf->position); +} + +static void netfilter_set_position(Object *obj, const char *str, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + nf->position = g_strdup(str); +} + +static char *netfilter_get_insert(Object *obj, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + return nf->insert_before_flag ? g_strdup("before") : g_strdup("behind"); +} + +static void netfilter_set_insert(Object *obj, const char *str, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + if (strcmp(str, "before") && strcmp(str, "behind")) { + error_setg(errp, "Invalid value for netfilter insert, " + "should be 'before' or 'behind'"); + return; + } + + nf->insert_before_flag = !strcmp(str, "before"); +} + static void netfilter_init(Object *obj) { NetFilterState *nf = NETFILTER(obj); nf->on = true; + nf->insert_before_flag = false; + nf->position = g_strdup("tail"); object_property_add_str(obj, "netdev", netfilter_get_netdev_id, netfilter_set_netdev_id, @@ -187,11 +223,18 @@ static void netfilter_init(Object *obj) object_property_add_str(obj, "status", netfilter_get_status, netfilter_set_status, NULL); + object_property_add_str(obj, "position", + netfilter_get_position, netfilter_set_position, + NULL); + object_property_add_str(obj, "insert", + netfilter_get_insert, netfilter_set_insert, + NULL); } static void netfilter_complete(UserCreatable *uc, Error **errp) { NetFilterState *nf = NETFILTER(uc); + NetFilterState *position = NULL; NetClientState *ncs[MAX_QUEUE_NUM]; NetFilterClass *nfc = NETFILTER_GET_CLASS(uc); int queues; @@ -219,6 +262,41 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } + if (strcmp(nf->position, "head") && strcmp(nf->position, "tail")) { + Object *container; + Object *obj; + char *position_id; + + if (!g_str_has_prefix(nf->position, "id=")) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "position", + "'head', 'tail' or 'id='"); + return; + } + + /* get the id from the string */ + position_id = g_strndup(nf->position + 3, strlen(nf->position) - 3); + + /* Search for the position to insert before/behind */ + container = object_get_objects_root(); + obj = object_resolve_path_component(container, position_id); + if (!obj) { + error_setg(errp, "filter '%s' not found", position_id); + g_free(position_id); + return; + } + + position = NETFILTER(obj); + + if (position->netdev != ncs[0]) { + error_setg(errp, "filter '%s' belongs to a different netdev", + position_id); + g_free(position_id); + return; + } + + g_free(position_id); + } + nf->netdev = ncs[0]; if (nfc->setup) { @@ -228,7 +306,18 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } } - QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); + + if (position) { + if (nf->insert_before_flag) { + QTAILQ_INSERT_BEFORE(position, nf, next); + } else { + QTAILQ_INSERT_AFTER(&nf->netdev->filters, position, nf, next); + } + } else if (!strcmp(nf->position, "head")) { + QTAILQ_INSERT_HEAD(&nf->netdev->filters, nf, next); + } else if (!strcmp(nf->position, "tail")) { + QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); + } } static void netfilter_finalize(Object *obj) @@ -245,6 +334,7 @@ static void netfilter_finalize(Object *obj) QTAILQ_REMOVE(&nf->netdev->filters, nf, next); } g_free(nf->netdev_id); + g_free(nf->position); } static void default_handle_event(NetFilterState *nf, int event, Error **errp) diff --git a/qemu-options.hx b/qemu-options.hx index 08749a3391..d2a6cb7da1 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4368,7 +4368,7 @@ applications, they can do this through this parameter. Its format is a gnutls priority string as described at @url{https://gnutls.org/manual/html_node/Priority-Strings.html}. -@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}] +@item -object filter-buffer,id=@var{id},netdev=@var{netdevid},interval=@var{t}[,queue=@var{all|rx|tx}][,status=@var{on|off}][,position=@var{head|tail|id=}][,insert=@var{behind|before}] Interval @var{t} can't be 0, this filter batches the packet delivery: all packets arriving in a given interval on netdev @var{netdevid} are delayed @@ -4387,11 +4387,32 @@ queue @var{all|rx|tx} is an option that can be applied to any netfilter. @option{tx}: the filter is attached to the transmit queue of the netdev, where it will receive packets sent by the netdev. -@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support] +position @var{head|tail|id=} is an option to specify where the +filter should be inserted in the filter list. It can be applied to any +netfilter. + +@option{head}: the filter is inserted at the head of the filter + list, before any existing filters. + +@option{tail}: the filter is inserted at the tail of the filter + list, behind any existing filters (default). + +@option{id=}: the filter is inserted before or behind the filter + specified by , see the insert option below. + +insert @var{behind|before} is an option to specify where to insert the +new filter relative to the one specified with position=id=. It can +be applied to any netfilter. + +@option{before}: insert before the specified filter. + +@option{behind}: insert behind the specified filter (default). + +@item -object filter-mirror,id=@var{id},netdev=@var{netdevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support][,position=@var{head|tail|id=}][,insert=@var{behind|before}] filter-mirror on netdev @var{netdevid},mirror net packet to chardev@var{chardevid}, if it has the vnet_hdr_support flag, filter-mirror will mirror packet with vnet_hdr_len. -@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support] +@item -object filter-redirector,id=@var{id},netdev=@var{netdevid},indev=@var{chardevid},outdev=@var{chardevid},queue=@var{all|rx|tx}[,vnet_hdr_support][,position=@var{head|tail|id=}][,insert=@var{behind|before}] filter-redirector on netdev @var{netdevid},redirect filter's net packet to chardev @var{chardevid},and redirect indev's packet to filter.if it has the vnet_hdr_support flag, @@ -4400,7 +4421,7 @@ Create a filter-redirector we need to differ outdev id from indev id, id can not be the same. we can just use indev or outdev, but at least one of indev or outdev need to be specified. -@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support] +@item -object filter-rewriter,id=@var{id},netdev=@var{netdevid},queue=@var{all|rx|tx},[vnet_hdr_support][,position=@var{head|tail|id=}][,insert=@var{behind|before}] Filter-rewriter is a part of COLO project.It will rewrite tcp packet to secondary from primary to keep secondary tcp connection,and rewrite @@ -4413,7 +4434,7 @@ colo secondary: -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 -object filter-rewriter,id=rew0,netdev=hn0,queue=all -@item -object filter-dump,id=@var{id},netdev=@var{dev}[,file=@var{filename}][,maxlen=@var{len}] +@item -object filter-dump,id=@var{id},netdev=@var{dev}[,file=@var{filename}][,maxlen=@var{len}][,position=@var{head|tail|id=}][,insert=@var{behind|before}] Dump the network traffic on netdev @var{dev} to the file specified by @var{filename}. At most @var{len} bytes (64k by default) per packet are stored. From patchwork Thu Oct 24 14:25:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11210165 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 81CF9913 for ; Thu, 24 Oct 2019 15:59:51 +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 47A7920663 for ; Thu, 24 Oct 2019 15:59:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=web.de header.i=@web.de header.b="A40dSzhH" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 47A7920663 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:45866 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNfWf-0002ab-Uc for patchwork-qemu-devel@patchwork.kernel.org; Thu, 24 Oct 2019 11:59:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39067) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iNe4m-0001Nl-GJ for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iNe4j-0003lv-RB for qemu-devel@nongnu.org; Thu, 24 Oct 2019 10:26:56 -0400 Received: from mout.web.de ([212.227.15.14]:57109) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iNe4j-0003jg-Fm; Thu, 24 Oct 2019 10:26:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1571927158; bh=cVG1bLY5L9+nYtRj+WO7zWt1Gw2p3nmxFUVahyEkCtk=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=A40dSzhHcSRSrT2ykeDqs98l1c/8KmYRikoN3bc3cez1xMQZPJO0SLcn1LW91SI8e II9asTK0vtL1Ml7swEx4VnZU8VjpXtuwI9kPC69vu+8r1G7iJOlB1UryB1aNCXmQHS iMMLZZWgLo5bNju5bbB1sISRZrTOxMHNUXjX5asg= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.150]) by smtp.web.de (mrweb001 [213.165.67.108]) with ESMTPSA (Nemesis) id 0Lxf5f-1hvDIr1p0t-017BZs; Thu, 24 Oct 2019 16:25:58 +0200 Date: Thu, 24 Oct 2019 16:25:57 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v7 4/4] colo: Update Documentation for continuous replication Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:L74YIqEB2jOStZaOSWznWkcEJSiMDo3JJ4Tg1lpvkKDiwFwrH4H VdwiFo2UI98vbklhUyS99/d+JEujhcSUAOkhzjotrckBU4VCTGbWMWG3eZGuRPKRCHdfXMN SrzhD2nObycaOJLbtjpt+loaxkXCPInwhZvQ+rDIFRFPR0Xujn5K/YNe4gNWkT16jDePQyB IB1OP4HSpLq+GBJQviotg== X-UI-Out-Filterresults: notjunk:1;V03:K0:NFEqP7UqfmE=:0CujnuMaPTQxD+9DFphV1q /rlEMG6P3UT/D5NkiwViT42heAH6qR1jBkX5Hh1nr1v1kqLIWOkOamkvGw94+zPMLu+047WEU su58Nusoe99PvV37Tl3IvSR8/Pdi3T86gZ200VxNs2L1uTuepOVta8jTtgLvLTRCFHhm6bboc XsyRla/mrIIHj3pJ9AkGCAKCodmfI09sDaB/TEqrau30DIqoEozI4F6x3g6F8Q+JF8LQfwtA0 rX/HGYO8s70WT4BJedJQS6n0ZoIaPBUijVFNLU4sLRMDyby8jTnmZ1gC80ygXAbFd4IcfHZB+ V/KRnW8Y21/ARfLa9/2V0bwIjohmXva1El6z9dU+zV1313YiLUv1P6wqrsT4DwHOcC2Ru1zh8 UmN3Y5Zo6OqtaCqOvkDccV4lDbhxxxd30Qgt1GUc0KqEgGB7eYXE6DD/q1ToVNsY70hlrK/N2 D4AO0XKakNX9zRAoVlJrxsOzaq12EoSnNk0VsRXzWb00m4AYfOw3je24c89uQqxRDrUvPKe7p wF02upRaLWLzCrGkrnwMoNZMXNvgiznnjZOjDHyrglVBhw+V/glNgxG3rRi46x0ZO5Sqz1upP BDUOJImC33x9c8mlXQPbhsY1Lf5Us29wsdxQcF6i4gYSafWpxS9O3OxfIIRD1LDYcpuxuwoYC am1goNaL6zmipVeUgSGvyBE3jw2BerwxznsQ61tsacG/ihbxHM3myNsc3pWXFHO7YsjWuIHJJ CRt4cuGIJUPMgm6u2pwgb9/f5D2LhpOxWigtbBPNO2a+3ufvy72Ub0ombMDDDz2G4aJU3xmEG X5Gn+Az8xXOxE7j5MC3CwG7c5b5CJgluRFefXvIKTYJdONo5MEEcRjD+akx9K2B31knKfA9Ei J0i+rooKZlu3Z6/Sk5aG8Q9smF9CIRCiZdH+oLniAadJVLUCoVN9G4PMRlKPLcx58+vwE1UoS /Q30m02r16oJOgdiZGvGMVhLk9UOyVD1efStfOwmrEf/efjSzF0qZH9owKwq8wGBf1jj04xHd 5n8T8ccBN5e8wEZZvYCS8umkW9blVF+Y23YQcUehG7T1fEUP3FpVn6eiX1xV3BOIrBywtlX51 C1unFLC631sYoJn3ez1v3/I9r59v3ypeiXAn7lG8HgU93Ngpuf6bwe9frr9MtwzFf5dlpoZrn RbVJRSg0cnb8NfPigBP0+ZSv/JKz5hzci2lvsT4kpMCsCgs3ZaWO3Naz73K1b5y6+ILzQ5qk8 pbj6nvbBJEiwjtuViEXiNBhp2h5cTdr/x63tw2mmTbGFfI0RvJhzFhbGCxaI= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.15.14 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 , qemu-block , Wen Congyang , Wen Congyang , Jason Wang , Max Reitz , Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Document the qemu command-line and qmp commands for continuous replication Signed-off-by: Lukas Straub Reviewed-by: Zhang Chen --- docs/COLO-FT.txt | 224 +++++++++++++++++++++++++++---------- docs/block-replication.txt | 28 +++-- 2 files changed, 184 insertions(+), 68 deletions(-) diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index ad24680d13..c8e1740935 100644 --- a/docs/COLO-FT.txt +++ b/docs/COLO-FT.txt @@ -145,81 +145,189 @@ The diagram just shows the main qmp command, you can get the detail in test procedure. == Test procedure == -1. Startup qemu -Primary: -# qemu-system-x86_64 -accel kvm -m 2048 -smp 2 -qmp stdio -name primary \ - -device piix3-usb-uhci -vnc :7 \ - -device usb-tablet -netdev tap,id=hn0,vhost=off \ - -device virtio-net-pci,id=net-pci0,netdev=hn0 \ - -drive if=virtio,id=primary-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\ - children.0.file.filename=1.raw,\ - children.0.driver=raw -S -Secondary: -# qemu-system-x86_64 -accel kvm -m 2048 -smp 2 -qmp stdio -name secondary \ - -device piix3-usb-uhci -vnc :7 \ - -device usb-tablet -netdev tap,id=hn0,vhost=off \ - -device virtio-net-pci,id=net-pci0,netdev=hn0 \ - -drive if=none,id=secondary-disk0,file.filename=1.raw,driver=raw,node-name=node0 \ - -drive if=virtio,id=active-disk0,driver=replication,mode=secondary,\ - file.driver=qcow2,top-id=active-disk0,\ - file.file.filename=/mnt/ramfs/active_disk.img,\ - file.backing.driver=qcow2,\ - file.backing.file.filename=/mnt/ramfs/hidden_disk.img,\ - file.backing.backing=secondary-disk0 \ - -incoming tcp:0:8888 - -2. On Secondary VM's QEMU monitor, issue command +Note: Here we are running both instances on the same host for testing, +change the IP Addresses if you want to run it on two hosts. Initally +127.0.0.1 is the Primary Host and 127.0.0.2 is the Secondary Host. + +== Startup qemu == +1. Primary: +Note: Initally, $imagefolder/primary.qcow2 needs to be copied to all hosts. +You don't need to change any IP's here, because 0.0.0.0 listens on any +interface. The chardev's with 127.0.0.1 IP's loopback to the local qemu +instance. + +# imagefolder="/mnt/vms/colo-test-primary" + +# qemu-system-x86_64 -enable-kvm -cpu qemu64,+kvmclock -m 512 -smp 1 -qmp stdio \ + -device piix3-usb-uhci -device usb-tablet -name primary \ + -netdev tap,id=hn0,vhost=off,helper=/usr/lib/qemu/qemu-bridge-helper \ + -device rtl8139,id=e0,netdev=hn0 \ + -chardev socket,id=mirror0,host=0.0.0.0,port=9003,server,nowait \ + -chardev socket,id=compare1,host=0.0.0.0,port=9004,server,wait \ + -chardev socket,id=compare0,host=127.0.0.1,port=9001,server,nowait \ + -chardev socket,id=compare0-0,host=127.0.0.1,port=9001 \ + -chardev socket,id=compare_out,host=127.0.0.1,port=9005,server,nowait \ + -chardev socket,id=compare_out0,host=127.0.0.1,port=9005 \ + -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0 \ + -object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out \ + -object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0 \ + -object iothread,id=iothread1 \ + -object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,\ +outdev=compare_out0,iothread=iothread1 \ + -drive if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\ +children.0.file.filename=$imagefolder/primary.qcow2,children.0.driver=qcow2 -S + +2. Secondary: +Note: Active and hidden images need to be created only once and the +size should be the same as primary.qcow2. Again, you don't need to change +any IP's here, except for the $primary_ip variable. + +# imagefolder="/mnt/vms/colo-test-secondary" +# primary_ip=127.0.0.1 + +# qemu-img create -f qcow2 $imagefolder/secondary-active.qcow2 10G + +# qemu-img create -f qcow2 $imagefolder/secondary-hidden.qcow2 10G + +# qemu-system-x86_64 -enable-kvm -cpu qemu64,+kvmclock -m 512 -smp 1 -qmp stdio \ + -device piix3-usb-uhci -device usb-tablet -name secondary \ + -netdev tap,id=hn0,vhost=off,helper=/usr/lib/qemu/qemu-bridge-helper \ + -device rtl8139,id=e0,netdev=hn0 \ + -chardev socket,id=red0,host=$primary_ip,port=9003,reconnect=1 \ + -chardev socket,id=red1,host=$primary_ip,port=9004,reconnect=1 \ + -object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 \ + -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 \ + -object filter-rewriter,id=rew0,netdev=hn0,queue=all \ + -drive if=none,id=parent0,file.filename=$imagefolder/primary.qcow2,driver=qcow2 \ + -drive if=none,id=childs0,driver=replication,mode=secondary,file.driver=qcow2,\ +top-id=colo-disk0,file.file.filename=$imagefolder/secondary-active.qcow2,\ +file.backing.driver=qcow2,file.backing.file.filename=$imagefolder/secondary-hidden.qcow2,\ +file.backing.backing=parent0 \ + -drive if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\ +children.0=childs0 \ + -incoming tcp:0.0.0.0:9998 + + +3. On Secondary VM's QEMU monitor, issue command {'execute':'qmp_capabilities'} -{ 'execute': 'nbd-server-start', - 'arguments': {'addr': {'type': 'inet', 'data': {'host': 'xx.xx.xx.xx', 'port': '8889'} } } -} -{'execute': 'nbd-server-add', 'arguments': {'device': 'secondary-disk0', 'writable': true } } +{'execute': 'nbd-server-start', 'arguments': {'addr': {'type': 'inet', 'data': {'host': '0.0.0.0', 'port': '9999'} } } } +{'execute': 'nbd-server-add', 'arguments': {'device': 'parent0', 'writable': true } } Note: a. The qmp command nbd-server-start and nbd-server-add must be run before running the qmp command migrate on primary QEMU b. Active disk, hidden disk and nbd target's length should be the same. - c. It is better to put active disk and hidden disk in ramdisk. + c. It is better to put active disk and hidden disk in ramdisk. They + will be merged into the parent disk on failover. -3. On Primary VM's QEMU monitor, issue command: +4. On Primary VM's QEMU monitor, issue command: {'execute':'qmp_capabilities'} -{ 'execute': 'human-monitor-command', - 'arguments': {'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xx.xx.xx.xx,file.port=8889,file.export=secondary-disk0,node-name=nbd_client0'}} -{ 'execute':'x-blockdev-change', 'arguments':{'parent': 'primary-disk0', 'node': 'nbd_client0' } } -{ 'execute': 'migrate-set-capabilities', - 'arguments': {'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } -{ 'execute': 'migrate', 'arguments': {'uri': 'tcp:xx.xx.xx.xx:8888' } } +{'execute': 'human-monitor-command', 'arguments': {'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} +{'execute': 'x-blockdev-change', 'arguments':{'parent': 'colo-disk0', 'node': 'replication0' } } +{'execute': 'migrate-set-capabilities', 'arguments': {'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } +{'execute': 'migrate', 'arguments': {'uri': 'tcp:127.0.0.2:9998' } } Note: a. There should be only one NBD Client for each primary disk. - b. xx.xx.xx.xx is the secondary physical machine's hostname or IP - c. The qmp command line must be run after running qmp command line in + b. The qmp command line must be run after running qmp command line in secondary qemu. -4. After the above steps, you will see, whenever you make changes to PVM, SVM will be synced. +5. After the above steps, you will see, whenever you make changes to PVM, SVM will be synced. You can issue command '{ "execute": "migrate-set-parameters" , "arguments":{ "x-checkpoint-delay": 2000 } }' -to change the checkpoint period time +to change the idle checkpoint period time + +6. Failover test +You can kill one of the VMs and Failover on the surviving VM: + +If you killed the Secondary, then follow "Primary Failover". After that, +if you want to resume the replication, follow "Primary resume replication" + +If you killed the Primary, then follow "Secondary Failover". After that, +if you want to resume the replication, follow "Secondary resume replication" + +== Primary Failover == +The Secondary died, resume on the Primary + +{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'child': 'children.1'} } +{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_del replication0' } } +{'execute': 'object-del', 'arguments':{ 'id': 'comp0' } } +{'execute': 'object-del', 'arguments':{ 'id': 'iothread1' } } +{'execute': 'object-del', 'arguments':{ 'id': 'm0' } } +{'execute': 'object-del', 'arguments':{ 'id': 'redire0' } } +{'execute': 'object-del', 'arguments':{ 'id': 'redire1' } } +{'execute': 'x-colo-lost-heartbeat' } + +== Secondary Failover == +The Primary died, resume on the Secondary and prepare to become the new Primary + +{'execute': 'nbd-server-stop'} +{'execute': 'x-colo-lost-heartbeat'} + +{'execute': 'object-del', 'arguments':{ 'id': 'f2' } } +{'execute': 'object-del', 'arguments':{ 'id': 'f1' } } +{'execute': 'chardev-remove', 'arguments':{ 'id': 'red1' } } +{'execute': 'chardev-remove', 'arguments':{ 'id': 'red0' } } + +{'execute': 'chardev-add', 'arguments':{ 'id': 'mirror0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9003' } }, 'server': true } } } } +{'execute': 'chardev-add', 'arguments':{ 'id': 'compare1', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9004' } }, 'server': true } } } } +{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': true } } } } +{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0-0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': false } } } } +{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': true } } } } +{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': false } } } } + +== Primary resume replication == +Resume replication after new Secondary is up. + +Start the new Secondary (Steps 2 and 3 above), then on the Primary: +{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.2:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} } + +Wait until disk is synced, then: +{'execute': 'stop'} +{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync'} } + +{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} +{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } + +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } } + +{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } +{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.2:9998' } } + +Note: +If this Primary previously was a Secondary, then we need to insert the +filters before the filter-rewriter by using the +"'insert': 'before', 'position': 'id=rew0'" Options. See below. + +== Secondary resume replication == +Become Primary and resume replication after new Secondary is up. Note +that now 127.0.0.1 is the Secondary and 127.0.0.2 is the Primary. + +Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2), +then on the old Secondary: +{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.1:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} } + +Wait until disk is synced, then: +{'execute': 'stop'} +{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync' } } -5. Failover test -You can kill Primary VM and run 'x_colo_lost_heartbeat' in Secondary VM's -monitor at the same time, then SVM will failover and client will not detect this -change. +{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0'}} +{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } -Before issuing '{ "execute": "x-colo-lost-heartbeat" }' command, we have to -issue block related command to stop block replication. -Primary: - Remove the nbd child from the quorum: - { 'execute': 'x-blockdev-change', 'arguments': {'parent': 'colo-disk0', 'child': 'children.1'}} - { 'execute': 'human-monitor-command','arguments': {'command-line': 'drive_del blk-buddy0'}} - Note: there is no qmp command to remove the blockdev now +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } } -Secondary: - The primary host is down, so we should do the following thing: - { 'execute': 'nbd-server-stop' } +{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } +{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.1:9998' } } == TODO == -1. Support continuous VM replication. -2. Support shared storage. -3. Develop the heartbeat part. -4. Reduce checkpoint VM’s downtime while doing checkpoint. +1. Support shared storage. +2. Develop the heartbeat part. +3. Reduce checkpoint VM’s downtime while doing checkpoint. diff --git a/docs/block-replication.txt b/docs/block-replication.txt index 6bde6737fb..108e9166a8 100644 --- a/docs/block-replication.txt +++ b/docs/block-replication.txt @@ -65,12 +65,12 @@ blocks that are already in QEMU. ^ || .---------- | || | Secondary 1 Quorum || '---------- - / \ || - / \ || - Primary 2 filter - disk ^ virtio-blk - | ^ - 3 NBD -------> 3 NBD | + / \ || virtio-blk + / \ || ^ + Primary 2 filter | + disk ^ 7 Quorum + | / + 3 NBD -------> 3 NBD / client || server 2 filter || ^ ^ --------. || | | @@ -106,6 +106,10 @@ any state that would otherwise be lost by the speculative write-through of the NBD server into the secondary disk. So before block replication, the primary disk and secondary disk should contain the same data. +7) The secondary also has a quorum node, so after secondary failover it +can become the new primary and continue replication. + + == Failure Handling == There are 7 internal errors when block replication is running: 1. I/O error on primary disk @@ -171,16 +175,18 @@ Primary: leading whitespace. 5. The qmp command line must be run after running qmp command line in secondary qemu. - 6. After failover we need remove children.1 (replication driver). + 6. After primary failover we need remove children.1 (replication driver). Secondary: -drive if=none,driver=raw,file.filename=1.raw,id=colo1 \ - -drive if=xxx,id=topxxx,driver=replication,mode=secondary,top-id=topxxx\ + -drive if=none,id=childs1,driver=replication,mode=secondary,top-id=childs1 file.file.filename=active_disk.qcow2,\ file.driver=qcow2,\ file.backing.file.filename=hidden_disk.qcow2,\ file.backing.driver=qcow2,\ file.backing.backing=colo1 + -drive if=xxx,driver=quorum,read-pattern=fifo,id=top-disk1,\ + vote-threshold=1,children.0=childs1 Then run qmp command in secondary qemu: { 'execute': 'nbd-server-start', @@ -234,6 +240,8 @@ Secondary: The primary host is down, so we should do the following thing: { 'execute': 'nbd-server-stop' } +Promote Secondary to Primary: + see COLO-FT.txt + TODO: -1. Continuous block replication -2. Shared disk +1. Shared disk