From patchwork Sun Sep 15 19:19:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1162495 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.b="k2aBxeNH"; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 46WfQH3Ybnz9sCJ for ; Mon, 16 Sep 2019 05:22:13 +1000 (AEST) Received: from localhost ([::1]:56530 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a65-0003bh-Nx for incoming@patchwork.ozlabs.org; Sun, 15 Sep 2019 15:22:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39555) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a4Q-0003bT-9j for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i9a4P-00010R-4W for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:26 -0400 Received: from mout.web.de ([212.227.15.3]:44085) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i9a4O-000109-Ot for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1568575204; bh=1aMK3WcfXGtXkTJdGeILldP4LKkJ6RJ1Yf8zxuMXcY0=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=k2aBxeNH4Y9aZe2flT4uY7DjFDLoWMQ/oD4kAxJXSbJWA7jGfNy4QODKorfXbhAO/ abv5RhozCQVmP/zkE3WMxJYKlgt+j2SEAmxctzdH4aq/cg/qirK6VIbCh66pf91vTa kVogEAcjCH4tXkalSD5opH5AGOCfwD1GE4TWUTbU= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([88.130.61.53]) by smtp.web.de (mrweb003 [213.165.67.108]) with ESMTPSA (Nemesis) id 0MNtP9-1i2iJb1WRP-007Xvf; Sun, 15 Sep 2019 21:20:04 +0200 Date: Sun, 15 Sep 2019 21:19:59 +0200 From: Lukas Straub To: qemu-devel Message-ID: <5305f30b0f798adfc3883bbcebbfc5030661dbe9.1568574478.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:KiGlgs7reKKA72JZG9lsooaNACPtkO175t9ldaIG5awBy7Nw92X VbSJfAc0rSfoGayof6+BxzWgMy/RpPMj5z5YgAMS6TGaAcbOPjrEeEftRAqL8RVODotwMip mLabJ0K05ZuzuqbFDmvVXWpgrYUsJwzK6xfCp+xkRjt5tIfutpVZtzWUjvHpSBjDagoc/pC un22cwZs9bvffpHEu960w== X-UI-Out-Filterresults: notjunk:1; V03:K0:yhEVqWDVeis=:tP+j4xQjscmSEdbBt5TVFC 9lKJApaF+vpOaWXm2uQxSoBv3sT7CuvVylNTfU/xAoT8wptOVa9AV7CIMF+D4K7R1JKqN5PI9 BSnFcpCA9VvdeoATmFxwQlLM2rAg5Go8uT86LqxkVoKMNp5F1/Smi2wQNUsGhBdhxWhYeYnDc iSri3BOtt7NjnSFDb7dxZdGFIM/4Mft3ERBfc5OTpfOlRgpJ+gpv0jlxtJCtme5MJaT3KgTfj hvyW+Hf+hYDrTEJNwB9XhtQX7hW5609SjI710GVMRVRaxoh2mdo1ECYkFqfFdNvjmNVXlIrf0 AQUB0NBHd5UMEtDyUYEDSIOUjQ60NWht/WaLhyjFCgZ7OUOooafpxaIvSrLzHiWWp1HorWNdr SCZuqvcR7Zdz28/o8K5ykPiOObIuf0rg4c70N8iPKP6KtTZyfsqI8PdZLfCyj6wjIJgq7TSsi aLNycYv8xWGcunxXB6mNiF96P48O6Wc9ay94w4hbKPSK/aXDZo+a4ny2oC6GGuzH2681d+/Qc FLMrHreSFlBjRssSqQcv7MjK/FkGR4bUPEScFJ7Clfz7Czb+ex/hbBTqoSsaWnoR85h9gzpiR 4KLMw+io5ChHP9ypwkMkCzEfEX6YryWYDFdDrndFMZuSYiMuXm3fWfA58ByNGt2I7KiSRSXUG 5mE+sH8Z6VkEdjvSKjV8UkqTkJP3P9AVN7sXXTozfVnn2xoaGOm7kwLhF9ky5bh8EFkcdqr8C hsiUCiLVepLKQUK9Cy5jhlH/+D9J4XN/2FA1uwyd5szfwDwBTCTUE8WhLXbgsD78PMCEqylmJ OMYkPnU22MFaxAuW7PXnOKu5JYpuaOr9vRe8gPERQ3duA10TUwixaIju2STRdaubI/Hef4WDr Fa7GjGswmQV+JdGlzc2buQMRO2kWUa1IFhCqnMozR65u6TJIA7IuGudYqA0XMiCZLo9Nx+dWz aRfGO4BWJSnDwIZWI28jUXTuC+dMI22TQuQz8j2N3QiKb2JIC+0igxC8wDhcPm3g2hyDMiumJ NUVI9xoP0RRNGkLRdMMfx+16yCHoLzB9Bfb3g0aNognQwMzfheYJQ7vpe16ULog1lrhRDc361 IScsIROklMAa+f2wfjfS7X32/aG80X8g8BrlFrflStc1MMdrRUxO/+WffXeI8TYYdvPO22GhV RPqKM/7WJU6CLz5ZBHFcihUryFGrvraFE6pSWQziT4YYz94sXavtKJoZuubkxHI3pIIpYaKFp dcwE7JlrvLivY8G/V7nAb8GfkRk4bkHxas5DsDSIlhoMAmIrgPKcWNbVZXjo= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.15.3 Subject: [Qemu-devel] [PATCH v5 1/4] block/replication.c: Ignore requests after failover 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: kwolf@redhat.com, Wen Congyang , Jason Wang , mreitz@redhat.com, Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.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 --- block/replication.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) -- 2.20.1 diff --git a/block/replication.c b/block/replication.c index 3d4dedddfc..97cc65c0cf 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); @@ -529,8 +540,7 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode, "Block device is in use by internal backup job"); top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL); - if (!top_bs || !bdrv_is_root_node(top_bs) || - !check_top_bs(top_bs, bs)) { + if (!top_bs || !check_top_bs(top_bs, bs)) { error_setg(errp, "No top_bs or it is invalid"); reopen_backing_file(bs, false, NULL); aio_context_release(aio_context); @@ -577,6 +587,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 +614,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 +656,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 Sun Sep 15 19:20:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1162494 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.b="qPSOLGEh"; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 46WfQL0S6xz9sP6 for ; Mon, 16 Sep 2019 05:22:18 +1000 (AEST) Received: from localhost ([::1]:56532 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a6B-0003dK-N1 for incoming@patchwork.ozlabs.org; Sun, 15 Sep 2019 15:22:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39580) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a4T-0003cC-Gp for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i9a4S-000135-Db for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:29 -0400 Received: from mout.web.de ([212.227.17.12]:48195) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i9a4S-00012p-5O for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1568575211; bh=lS0He1ZjyrE6labtN6cAGz+FTFA0a9A2XqfoJ6l9fU0=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=qPSOLGEhqn6jTwrNrZzeaC+n+e4vH1kbohGQdRd5pGFTTOcCcL0hEYblpm7uacEzO zZyD9wmd32hx1IO4Jh/BokEsdbAksFsQssAcEtImJDI0ySAmbUUqWlZDwEPb4SuHDL Az+nUc2nBCdp6eL8ZTkPk2Fb1LbglObAzTB34Q/s= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([88.130.61.53]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MEEa4-1huDz92iVM-00FTS3; Sun, 15 Sep 2019 21:20:11 +0200 Date: Sun, 15 Sep 2019 21:20:07 +0200 From: Lukas Straub To: qemu-devel Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:Vzl09lb6jnQfDzrpdso9QKB96CqjdVmHW1XbotCrhBPNcCpfiY0 9gzopBdCbXNDwn6WmmjoCTFL+0EXrH1fTQJrP/JF5sFBBCcAw+6DFbe/9N7VSSHlKujMw7y wwAO42bF3qWDz3CAo0QtWXOuBK7HBdyvOumscDbQxSEGmGy1+FgJ7BJJU2iugQFtGwF1rwr Krx8wNihHFJqUzu43lZNg== X-UI-Out-Filterresults: notjunk:1; V03:K0:lDJn2w27Pqk=:jiYHm9lNPCyFQH3xwHyU7k fUkyGyAQkwcSzsQo4igztbUa/lDN1a/iAf8g3hujgP0J0DUhSOGkoaJ1+lWjb3YZmBqvzESRq JJZL22UKzKyAFSnPQZSjd/7JiYJVAfzLJI8c79C/MD+33uDwEFJdOtDRQ7fOpymTHB8rY0/j/ +ziQIRMLXfZ4M3ZHj1r0+SJA92m3g0fV3JrGhwYlaOEtoAeVELAP9Od7cA9q/ecw/pX3qhbTo n+DtqVqjnaq/f8+rPmvES4WhdL02U2srXGiovBeZ2Tvtrn3OJJ6WC6Kxe2k1HaQacjHxRTghg J0+KEhRqIpoDjIzlJ1o5+c6PLqrYgoBLogR1RB1dIFLVKaUHw7u8cfv6du1elei98fiC6IAuD Jvsf1RLdXql37NR2vJMN7RXfw2RpzXCsnrWifniiJ4Lx7DAcnhflQAyT9eiUkYMk0buqG5tUc z+SQ55RR7+ONwYUCJgPSKuZrrtWTjjeEFLcXKNgxlctkrEfcWEB93ivAg3HPnpjlB0ceUErxA JlrMeYS/AlICWMhcQ1uxvOxH2ryD5LLpuGVi19lz0m5q6RxLqqmIYEOmqzHm4MWqOVLaUNv00 vk/TIwMpASRSp7oHc5JwkHIuara8w/RJxsjItdgzKNlQJtsQSL5JuJa2ten3i8p9y2mT7lzaR zYHklFeAtqhTc+vHBJRPcTrSu4P+h/2Nj5jAhsXv//KDtwOjiqc3mUnos36QZPS6P8qWAf+Fr GI0taiy7cHBgbM05w6sWXYVf5v8xH1E1kaFOupwdXjDu5IJFuYczdyCnAF7A2K429WpsVnVsM 2J3mldLtc0N/g4It5w29dSffrrtph2gH2F5Rf+8AYZn4YUnHRGOsgCowT6YAA7d07nYP+Dxxe Z/669YtxlWDJESIIIFQyNWOISA047PaKJU3oQTUeHh/DiwAJOCVEy50ud/ZRbAUnjuergW0Xk qmjcIh/gSabHDdWWJeDfSq4wZUHA9Wkh5/YfioE/Mo9CHE+tDuU0pr2xtSzzTZv0wvHL3/12c cUpeE42tosvBD0NGXYVKFkw0xKemhhs51QhvMB4+c1zv8zHVQ1xw7jzvzy8zJeiSq2JH5/+JL voAmaXXgcYklBBZaBmozLpWp8sNIfLcubJRUrbwlTnh5AStrtcE8kl7nE1i9MDTPLl3JnUZoq lZ/g3RrF9vvjBoN5H1V5nw9+Mgt3rfDHQyeYUDVR212YuQh50NQS3Z7Nm6neLZyw8Q+OV3i+k d7XhwXmyuDUJdnphpxC9L8Y4GqhZUaoKfD7puQ9iFLeBD4yWwgOf25MWsctc= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.12 Subject: [Qemu-devel] [PATCH v5 2/4] tests/test-replication.c: Add test for ignoring requests after failover 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: kwolf@redhat.com, Wen Congyang , Jason Wang , mreitz@redhat.com, Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.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..5addfc2227 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_failover_then_ignore_requests(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/failover_then_ignore_requests", + test_secondary_failover_then_ignore_requests); g_test_add_func("/replication/secondary/do_checkpoint", test_secondary_do_checkpoint); g_test_add_func("/replication/secondary/get_error_all", From patchwork Sun Sep 15 19:20:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1162502 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.b="gayAJpcO"; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 46WfYh5Gf0z9sNT for ; Mon, 16 Sep 2019 05:28:40 +1000 (AEST) Received: from localhost ([::1]:56574 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9aCM-0000bm-4p for incoming@patchwork.ozlabs.org; Sun, 15 Sep 2019 15:28:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39602) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a4d-0003ff-6n for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i9a4Z-00018W-5o for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:39 -0400 Received: from mout.web.de ([212.227.17.12]:34913) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i9a4Y-00018F-ST for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1568575216; bh=bYRVmCXfWTISAMgenBJtNWjJCiJGXddMTiif/GPDVlI=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=gayAJpcOBTUSUEWtN3IkCj6JKRw5Yys1A+eGuzMHbcJV48Ph4843cEF1q14gTXOby I6H0EK7De53nKzhkUjCu987BxAbVUDSKDPJ3H2dA5mroOEM3gV7zw+R6UzOZYfj+f5 ilV58UmmtX3Z/anLB1CR/wJgJ3o2Xqx6lf9uTe28= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([88.130.61.53]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Ls95v-1iEkwh0KRL-013yX9; Sun, 15 Sep 2019 21:20:16 +0200 Date: Sun, 15 Sep 2019 21:20:14 +0200 From: Lukas Straub To: qemu-devel Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:sEngW7Y9n3AfACaxfOoyxBEK/Ix+4SxuP7YwaONOsMxAb/0/LH1 epNIShIrKca6VPXBWDKltIZuZkilHCpmu2nSK8B9fAf1ck2ndf3kaPuQLwlInYmgHhaHHS4 A+Z3kM18LUKSiXAQsB9KynQPTsZKuNXzHp75mCkGr6P/aNpg4EexmLnzQa+gcklAU/E2Rwd BatC1kuj2sGYJXnln3B4Q== X-UI-Out-Filterresults: notjunk:1; V03:K0:qC9aMQaPfa0=:MSeq5Zz9eetrXM/QJih9E7 km9EcxeVjls2+vQs23HZ5CgyufVfgNNyDNZIum3Z8Phs1rjZCaOSwx5en0sCsD+FdBetCtV2W Wz1Sv2nVmuwtTkPLxYJ9zViYDFN+6WPwYNI6IZGPNwGuESVcfeQ9GgMIvgHx96GGdQgBqovBO mydozBlRQwMa8c2Lo0BsMBTsM7gmLwQGAuvJ6wSbtXqxhOQ2uJv52gG6c1HQxFSDzNHgFrfHj O4taQlAniqcDr6CxsehktWRKxDCYeTpVvcbfZPmnMZjWN3+eMUBB0CUKJNb3JqOIA3U3sIK7B E1vbndJnPeFSbmnZT9aBif+vIzwl5rhStotMoJ94yJhZqjKmMlBminJ/H/hKcn6sm7amXncZg 9LTaqCWxiAYG0M2WPA6e/gQ5Bkt9sZtW7ZeZ72ahN71ZwHM8cc568bZcXg+KRvNzDgF/hcXaR L3m+sZa0gayJ85lfy9CP/k5DYvV2R5IVNEoE+KuPt5rWImSmhb+OrnbT1yM0TvdA1DH7MbNPc n6otB56utwl2GcQm330UEss79Y5EOa8QVw5OCRZtJWmKF4uUROLC+L9QqNRFePzn2972Hu/pr PASCjfyfTNzekW/54KX7GagLbR6KFT7b/Km0TmjihR7hBSUgSrV93l6Z/qsrJrDfx1yvPZFUB 6ArpkvrLPfD8WVL6KX0cEJfMd5jp+O2+b7VHoOyiycQC35dY5Trmy8QPFI+LICzAFJM3XQd8l OFEKbHTfFhTptAs0GPDaCQBq3ZPp+SnU2y1z4GMLc6TWohqdUAA2U83p5ET8ljYxyVVKhlbcV 4F2FZyMqFgzcwWJb3ElaSKF3c2+EIiHxjJY+Sol5lpD+XgDJGcMrKWYSIFjPN3l/N+TYz48wm ziUrEoLul2fd8rQkcBV1SKCDCiKM3IW+LcR8Albrz9VSwQprN3ux+mIs6IiA2wrz4WzspbtM+ japeWd7v4oEXWB9GWE6mPsrA5kt7ItjrdyfpFlCWWsw4hgjbkH912SfjNsIDK67gaTC+SuPR8 vQOphivqMyrMMJ3XR/DFMzkb05nT1wV6DMqtVtOaHVdU7hzlYDVFIVef5g4RFbOu7JSUVKDTI qGPsVVJY5JV5PSZD58Mvj3H6UtIXgSvF7yvPdR1UiB5yoOKi6zGWs0h4WXX/N/0ptG6uM/hdw vO0wlKziEdxupI6AYI0rNqylNrUGNeul5WKN+H9tqnu1rYfo/bnG93UxLB/S0zZIGcjWkMyVE iwtC8x7q73KIZrluj3d7VBAqgBl7DwteMCSyW8x5FfJgvs7XYOIujancalvQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.12 Subject: [Qemu-devel] [PATCH v5 3/4] net/filter.c: Add Options to insert filters anywhere in the filter list 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: kwolf@redhat.com, Wen Congyang , Jason Wang , mreitz@redhat.com, Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.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 | 10 ++--- 3 files changed, 98 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..23fa5a344e 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,11 @@ 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] +@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 +4400,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 +4413,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 Sun Sep 15 19:20:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1162496 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=web.de Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=web.de header.i=@web.de header.b="XGOEOE7a"; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 46WfQS1TD7z9sCJ for ; Mon, 16 Sep 2019 05:22:24 +1000 (AEST) Received: from localhost ([::1]:56534 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a6H-0003gT-Ta for incoming@patchwork.ozlabs.org; Sun, 15 Sep 2019 15:22:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39592) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i9a4Z-0003ec-AE for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i9a4X-00017t-0z for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:35 -0400 Received: from mout.web.de ([212.227.17.12]:55825) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i9a4W-00017h-Nv for qemu-devel@nongnu.org; Sun, 15 Sep 2019 15:20:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1568575220; bh=XTji1Q1D6niQRYpoviBW/bANIkemiDMT704iPrFER84=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=XGOEOE7a0sjxqrilOko7myOFxu5OqoBFn5H4URETS1qSoviXJv52HRr9Wa5HburK2 xIj7UpdAR5Vibpft2LAqcnjfzf1A+f/fnV68wbBdDce6EBSftTqPKJ+8e33AoXJSXq /QzHhFPk1JlhY+xKK7bc+iBbWLAYmDej2SShUlSo= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([88.130.61.53]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Lu52Q-1iGgkc1oH8-011PUA; Sun, 15 Sep 2019 21:20:20 +0200 Date: Sun, 15 Sep 2019 21:20:19 +0200 From: Lukas Straub To: qemu-devel Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:OrVg3zz4pJVCP92APcYt3fsLCilrTRgVZ5I2jnNhl1g+oGw2a+f 6p86M22HbtMW+2TEU5wutO7JNX+k8ZJxm2CkjVGCEF6KSdlND6fX6lU7CSmtGTbGyVO+tux 8MqghUjVsmN0mlthe36G+pVtkcV2Ua+JBpWpWnKU3ARyNfmULGGuupXrvXlEFVZ1ENrAEPv dWohqCJqVFPGiOSGNT/dw== X-UI-Out-Filterresults: notjunk:1; V03:K0:Kxd5GXTcr1k=:1Y4nwjl45JI4FAjBmOT5zv 0etU/gLP2Z/bp4nlYF+UWnzHYqgnXhpc9Fm+mFus33C/iLyf5iDbHJFzZne2XBkKzSP/wNs6c KBoy0SQiC67cWa8Hy9b11rFWdh1ROb2MDGMaNmFbKbr1xDt3poZPqs7tVBHm7IVM5a5s4Z81h mXaZnC78H5Gy+COKsYd28DKYVk28CPK6WymRIBVtbPlQ/K8UT/mdsfwyJ6xTYQRK1pFRMue0q 1Mt3KWHjThbysGdrBZeOGegfC24LidWjNDHXj3ZlK05Us+n31OMybLOMejageNyoF3jxS1urs ZwOuGBbwsAHzS9LUbx2nHW1w//FthfZ3sZAsUcoGXGsU4ukopBOO//FnTNoYJhy9MVfhRn/ws leByflN8D2xdRX/WD2xRSc7BQwYu4IpRc0hgKqoWtiZKRfKmu/8fTBJ6pzujHQfgR9eA+zO93 n+5VMrlWnyjejG0jvptOdAecXrP7ZR/M5GA/GsQsMdtrr7JKXgoU+UyBkY+Gi5Cb6mLxxc1Kq kVsPbwBs8fsV6cMHfYuPBNOILkY7G8CBpsGo56QcJtN60ppvrGtOhiGkbliJkdjfv00HKU1uN dsmXYcSMOZpS9lcFYqOAuNVE7zp5kdBCVgXczZAQWR8/NkTmXeEt1ERvpuRI3WiRzxDNl7tiB Z33QbAXQAYI41wq5g0Abr1ZpxhTELCTuGgXgqev76ykaqU9UYaSFcE0GY07CGt7re7mCkSqmK hBA4QWCbVLfuBrrMOuUFPjWTw+SfReGaysDjtBjcb3hBxhyyJTV0ZWbQdfidnBLVOwLZCS5fh bYotRrW3yhDZOp+ZvO5TCz/cOI+jPA3IZ9TLLLwaeSPXFbxcc0XgGeJgln4wQ5NtDtnhD2Kru V0P7z6ChjiQDDvzYzyZAJYW0fsRT/BVWnbehdZo/Y97ZtJz4y4QYc30ePMOIexC7FXz4Pe2M9 5+mqE4VDJ7YdMTTAmsCDPDMk9049jYJplEGt35VXNSVrmpmiFfbiB/PyDAwhk1Sbf1Rdfomre B7ksRR0+T/RmBnKO85TTSbEbbl7ZZYSMn0FU2B5D2+X4eizSL75TlegaVynB5hLzLVH1vhIIe 88D1hi7SQRFF9XvoPgiw/x0vWhEU/S6GnMqOQ5EKwdae4txZC/ml77as2tpiRdwIkiYsMjl4L Nm9wknWXr4g/XRy2NmY9uG6fhKsjA/pZ4Tw5BZKu7lDubjiHB4VnNM07KJhlVcyzmK/ZMh3X4 D28plk+a8UKCT4IKlsch4MB6k6o1NdxiK6j7Mic9KmBjMueylrdtWimSpsEw= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.12 Subject: [Qemu-devel] [PATCH v5 4/4] colo: Update Documentation for continuous replication 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: kwolf@redhat.com, Wen Congyang , Jason Wang , mreitz@redhat.com, Zhang Chen , Xie Changlong Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Document the qemu command-line and qmp commands for continuous replication Signed-off-by: Lukas Straub --- docs/COLO-FT.txt | 212 +++++++++++++++++++++++++++---------- docs/block-replication.txt | 28 +++-- 2 files changed, 173 insertions(+), 67 deletions(-) diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index ad24680d13..e98c95ca2b 100644 --- a/docs/COLO-FT.txt +++ b/docs/COLO-FT.txt @@ -145,35 +145,65 @@ 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 Machine for testing, +change the IP Addresses if you want to run it on two Hosts + +== Startup qemu == +1. Primary: +# imagefolder="/mnt/vms/colo-test" + +The disks for the primary and secondary need to be the same before starting colo +# cp --reflink=auto $imagefolder/primary.qcow2 $imagefolder/primary-copy.qcow2 + +# qemu-system-x86_64 -enable-kvm -cpu qemu64,+kvmclock -m 512 -smp 1 -qmp stdio \ + -vnc :0 -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=127.0.0.1,port=9003,server,nowait \ + -chardev socket,id=compare1,host=127.0.0.1,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: +# imagefolder="/mnt/vms/colo-test" + +# 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 \ + -vnc :1 -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=127.0.0.1,port=9003,reconnect=1 \ + -chardev socket,id=red1,host=127.0.0.1,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-copy.qcow2,driver=qcow2 \ + -drive if=none,id=childs0,driver=replication,mode=secondary,file.driver=qcow2,\ +top-id=childs0,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: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': '127.0.0.1', '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 @@ -182,44 +212,112 @@ Note: same. c. It is better to put active disk and hidden disk in ramdisk. -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.1,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.1: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': '127.0.0.1', 'port': '9003' } }, 'server': true } } } } +{'execute': 'chardev-add', 'arguments':{ 'id': 'compare1', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', '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: +{'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'} } + +{'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' } } + +{'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.1: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': 'rew0'" Options. See below. + +== Secondary resume replication == +Become Primary and resume replication after new Secondary is up. + +Start the new Secondary (Steps 2 and 3 above, but with different image than +primary-copy.qcow2 and different VNC port), then: +{'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