From patchwork Sat Oct 5 13:05:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11175643 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 61D8016B1 for ; Sat, 5 Oct 2019 13:11:13 +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 36A1F222C8 for ; Sat, 5 Oct 2019 13:11:13 +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="ehfGa9U9" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 36A1F222C8 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]:56654 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjq2-0004yz-B6 for patchwork-qemu-devel@patchwork.kernel.org; Sat, 05 Oct 2019 09:11:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56745) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjkt-0002ki-An for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGjks-0005SV-39 for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:51 -0400 Received: from mout.web.de ([217.72.192.78]:52685) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iGjkr-0005Qu-MM for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1570280725; bh=R0IRo8VMRmUK4dg5KQRbFBwzAqI8nGg0X+OwDoGxLWM=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=ehfGa9U9l/1J0bEnnjAUzFhCeV8F5HcWz/0jyLMXdMWEwWXUQyPDCZdQGTnh5+lI9 L6D2ljk2rDNaoQ12cWSsMAt20sH0V/FV2PVB1ZTA83pU82BHKZhmlaX731GSgT7DBt a//2Fy6+2WJZSdkMSebYIKWKZeOqT9T8iw3FKEQA= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([87.123.206.231]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MTh6a-1ihErV2C5A-00QTQZ; Sat, 05 Oct 2019 15:05:25 +0200 Date: Sat, 5 Oct 2019 15:05:23 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 1/4] block/replication.c: Ignore requests after failover Message-ID: <596a6f07850002a09461f317afa75f3e0c9bb784.1570280098.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:YOVCmClvx9HEE1dFzp4GHc9NXGOxuebHDtMPBOu9EOhb9psnocK xUjUxlxc3wlDfaMwPRKBshOSW5MDOfpfX89dPkVhGNsxtZ8s3r0DulmbrJv1iRv1HBzdvNQ Ql3pBpIeQzy78d/9sMSIFMaJNiH7WLlMn+4lit3kCV/puC6w8DLaRKaDMsSWSnGCibI9NU9 xRCEnimUZXSCzmEezWmXQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:w0A6Urtw3cA=:UgS6dH2fGSksF4B+YgeDB6 GxxTWEAWlYLtgfnhiIdvm9rvFyNSZDHomiMMdjpmScr1TpCG5SYB9ROHGVGbfd0m8YlBdIt1K uWsYY5vuVrvmrCnj1Bg6smzrwaAOexR3+1oMRCxbvstj2+ZfP7mIRaGtziIZROPVb8KNuHzhS nWjx6tJ1TQWgcl1WzeTqQT/AUSZeTYdGjxFpaUGcRGXWuDzv6Ro2LBvEmaHNxMnTL3tWSok1B wp8Bsak4XOXHauPtCV8cl9Uy+sjp41OUaUPB/epabmmqIQfGhmmBZ/dVlg6Dx6BMFvLv4z7oy Y2Wt4UXzoistUzRQ+isxhzwcNTJhjc81nC7NoQXer+lq5+qs0jdaC3CGj8e4UXhao3tvow3Xs tGG4MyY4k2FmhK8+i2PXZuzLlGh9mvBkt5lA8FgAeULlHxLRvtlkUVSyrJlsT6chxgdebErHh XurnaznFFz8hWosHXbmF1c9+qIBzXsnHDS6MBBqM6Hgk7JZs/3aB9pwHH5Ei4gAiwogIR2ccl r+qRA5Dc/I5AFnS/1CvpQ6Z2sYjII+2zrwtsD981ufM2yW6ec+PPipcdUUf82cyYIwS/jLQW/ fsML6XnNtrLTw9xv3muCkEvQvG1rrCgc6p4oopr4apX6On1h5abZWbcwA9LKcZxcDz3hxwG/R j1MLhJ1Su78wamV9G6JOaolnvxFsqQFaw1zzuVQRAIW6Vq+hd2yumt8ivLXn2K/J1GIBslrx+ kySfXj8Ima5tIBX/HV6S6TEhYR28gsv4jND5SZF9iRWDH3MS8xp/nVENqdLv6MI+IlV/rwt6R 2w+lnbzERHqOZQwLscBMK0yQCmTwliADrnl1v65E+9+mNpWhJTuhQLcD7h6KaLZ8qyF0KrjaI ThzobHjvK1nh2XVIlU9rMuxcImBtUhvwV31sGzBUsbQfN4lJfuF+l5iGR+zqpI9gE4HNG7csM NlUNn5DRO/NFBFV3KgVPJTvJR/t5xu0ORU5za1ynPS7sE/938RkxLcZ8L84HfyMtgJsk7F8NS rUlHFVdULOutJvPhS+KJt62y26v+GX+tG4mlujEj9UW7+uuLVUd4kVOWyDBrcQ9DSwW2gZUkc Ozl/stij6jSGWMYD/qYT87SkcxJ9GDJz8dOBN+Dm8BH9/Ckd9sLT6XI/Ggqx9zAljKA4gKEuW 8162exq47M+No9puzorOSfdwsNNjbYB4nnDXztmRXu3a8q0Tuey68jVneD2Bl0nDXUqHEk1SO YI47H7djA6NPQyapgW6j1/Hl5/YaWdFD7IttmfTNGEisbCS6wb9bwOzdI7dc= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 217.72.192.78 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 , 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 --- 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 Sat Oct 5 13:05:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11175645 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 70C1716B1 for ; Sat, 5 Oct 2019 13:11:21 +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 4742F222C8 for ; Sat, 5 Oct 2019 13:11:21 +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="ZmWk2My6" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4742F222C8 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]:56656 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjqA-00050m-6V for patchwork-qemu-devel@patchwork.kernel.org; Sat, 05 Oct 2019 09:11:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56748) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjkt-0002kj-HZ for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGjks-0005Sc-71 for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:51 -0400 Received: from mout.web.de ([212.227.17.12]:48575) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iGjkr-0005R7-UR; Sat, 05 Oct 2019 09:05:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1570280731; bh=OfJkK2vnGkQe8T1r5KQyutlaZ4TJ+K9pB9jGve8qHNk=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=ZmWk2My6W3rN89JKwpuOhr20MQ7JMNh0Z0ck5HnWsSSLMsrnDK2LhXr7W0CWLlnOA CsrrBBecLa49GTYUmfjQtcgNmmnYrfXVESbx7aNAmvfs9ryEd4Myu4TNYMtybgdcD4 x+/91z9JpClebvHcMJpk37+AOWg3HyyCN3zEXhN0= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([87.123.206.231]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MMmx9-1iC3BF3Izf-008a6C; Sat, 05 Oct 2019 15:05:30 +0200 Date: Sat, 5 Oct 2019 15:05:30 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 2/4] tests/test-replication.c: Add test for for secondary node continuing replication Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:wGo+s/4GRs3tXN8+Khn7ib2ssYy9FPq1Y48rkFPRq4SDS0DANe7 QIyxfhe65SWwXDOqmVzrKVAYHF1Zobczc+jarW2KcnCN9Mt94en2u/Ql1wUCcIxCP11L5Ya nWlbjdAFKL5l4RllFkN5vLujmL9R2PLu7R7RS0/NaVinFIapzaL5JD3/CPumnUQ3jpSFgaY 7/IBqjKHkoTsZsLy8tg0w== X-UI-Out-Filterresults: notjunk:1;V03:K0:J9pNGHNLzfU=:1EkZSUnsUhk+yYf7VZfJH8 ZmC73q/QLSSSljflGD9zjj7Ya8Rv7d2Q1H/xzfe6o1cf4SpmAY0A0pO/g/NrOoJ1oPVkTDR+0 TWQd+77DA+Q/BgYlLCOaBe/SCYEMFRDCj7JnU1ZwGmWz3hlqHmaaF8qqPy0wXYm6LPqqvvZ3r tvK233Fh1o0lNsJMJy05wN+/z+H0hDxOc0qcUC1knaAJG2mIdd0SnGJCY9rY+zX21Nw4A6rm/ TsWKNugxIkSBd2GfcV88v/p5c8EwrMm787vvQV25lJLZl0DqTyvbCNTk8y5QKmA8q9lmPCZAB aPvTQZw9r2P+rJbgWTaJV/HE9y7M+2GHwu4sWRbWG97B7KD9R856bZd5b29FN26r4rbwQRejs ZenbA3zzE45l1psd9EMOWk3+/W5zEHxDIjoMUzHe6Wawvm8tcYxgZlNn4YAnDPdHZNLGYyKGI aLnIiLLIX7iHMCiQD7Y2VejT5bP+vYjnq/t6Q03T+fm8Nq0uQ5PhFrTxGMfqugV6f4M+0L7HA sSdi1XV+q82W1dmU8irldDjBfa1dYdKHc3UqR7D2pImV6/bPpfbeP2RNsC+iD42hWfyF9/YgX TMRe1Icv1LdIRPH4IupDQix+fBwsdg2F/U+2Z2b73dnANTeY3OtiTJHpnvYvpSinyeeV4QpFa kNE41bvAdfU0NJAAGD5SgXLtWjOSCu/Pr99esDwfobLhlCYOmCi2SaHYlR6NSK5dLLHNaUyRW /Jd7b1ZF8M1dVfbjxgkgbMEgwIY3ebHlA8qgdBLh7q5fYOFlx1pQN9UmIqU8WmhCwU4X7DWPw bbUhc2L/Nifyknhrk91+bhT6a+Bi8f2+V6+AtATifYv6CsgdcLqNBSiXXpfOcekSGTNf6DfY5 DkwAAbUnzvMhVGiQ01KTrQ1A9Roza6ICPMQGWqVLs8d7mmLE3pWvKuKvqUKvjmovC6Ce8r7ip Tn9j1rTb7s+/DupOzXHQwiegXQfn2nDdaVfiSX4Lb6ny1fy1u70DkuT8MykCiJGLRqmAdWmWk daOYKwZ0zX2A7szhKJrN4ZyqUxkuTB3RbJoUnX9T0ob3sjh3WjYxpL+YIVWj3n+EtUs9cGhoa BYUmHqMIlouZEAe9FP/xZ+cMrxRm1ejh0+0Js6fdFUKpsOALn3ZffCerQBSxfN0f0tW8zBxzI 1cz+knSFJ/UauKI30ylYzx/LZ7R9YIealTfIsoSUNz5Bagw0AuoPsvVYQS7i5ZEct7pIkM75u SaxNJg1MN8ikL1tRXcJkQ2ILrIpWD8Yfi4n9J1n5W8S6v/JmNVv9EJT2ZwWs= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.12 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 , 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 Sat Oct 5 13:05:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11175647 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 D93AD76 for ; Sat, 5 Oct 2019 13:11:39 +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 9DDF1222C8 for ; Sat, 5 Oct 2019 13:11:39 +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="ntFd4+ce" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9DDF1222C8 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]:56658 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjqT-0005BP-Jg for patchwork-qemu-devel@patchwork.kernel.org; Sat, 05 Oct 2019 09:11:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56825) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjl3-0002pd-F9 for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:06:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGjl0-0005Zl-MG for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:06:01 -0400 Received: from mout.web.de ([212.227.17.12]:48885) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iGjku-0005U8-7F; Sat, 05 Oct 2019 09:05:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1570280737; bh=6Uf5G14Now/peaYZfO+y9x/dGzGKbhnBYYKyspPJYcQ=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=ntFd4+ceclW+eSssdfkGcqGFvry5yU5MB6OTNaJrfBLYstwr+VIOj/9uFgJhRO1Xf G0u1WGbLcdRbFcDeYzI5pktMlYyjHMUSL1tDaxscg2vF/c8loqIHTntpzKmICxMPCS iLcRUgSdeJ56yWET3Ov0v1DxF9a/VnU0C0BFGHSU= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([87.123.206.231]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MXpdL-1iek9G2SwB-00Wiz3; Sat, 05 Oct 2019 15:05:37 +0200 Date: Sat, 5 Oct 2019 15:05:34 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 3/4] net/filter.c: Add Options to insert filters anywhere in the filter list Message-ID: <233911f2d68d72126bf93fd746eadb30ab0307e0.1570280098.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:YjyHhRSr8xij19R2Pt/xEUysFg9bBACSmQ7DFPfUpOANcQ6/8b0 /4lnBzodf/2Bci7LdxGYUlLdXWQF4xUtxqkwPCWmxXAq7VcFARsEYqvFsE584yBYVtr7r/h D5CswyZdgMvAlsIPlZNZWYxU4FNim7CvG97oNW1PdSgx5y3hS6/xXYua5tUWqeTvrtqqkdL iXLoW/DMKRkzNzPTFRbOw== X-UI-Out-Filterresults: notjunk:1;V03:K0:BaRS/0d0LPI=:HBPgMPY3kWYmQrpB7QuhY5 0jY8QOy60NVThUXTxJPRWMttdlXxjO74gj3e/kF7EUEV5QESBHdrc+EBi4sc6mzcduMV8iVlx kPq5GmXbG9n/RHaamVwP5yNMSe65IM0h6JIcV4GqAQgznPYowWCYy3I3GULXkKwh6xDPZTuaQ QeazeF6jR6HRsr8NrHK/znTZjEFpQe3z8WmiTqYTLOh4gTa6sV+72f2L1nTF9ezJLA5RbsTb4 dT4rOgBaaNOMRpuC6FN9qfzvAK7jnTOZNlAEa35ymGcKX5lCry+ngKewk46fuMHiAd1+Qvnbi ngRc7eE39LJlhd6dDM2EqXEvfZ+Jx4tU3w7VtJ7398p6Dkupz7bgF47Y6JiSFH7y3/0RIwdDG TH1LADOf7FZsBO5I84orkGd6PrRR18oT47JyBMALJ8CykCvT906WiVFsPF9VAdIlqSWej8GrX TqnYzZO20oVt9wzhpSttkUHu4uZGa/+p2I18ogNUAEOJJWD8rIpx2fwlmqmdNXF4leGUlrxUw vdLXc2k1Ek4bTUpK0nkyV/dcDc7tozdzf+W2M8eReUlTe9R6PD74jb0zAzOLnsAjAVACjPTWn ORq1UQg4JoerTfbfeFapigCsPNiYcbrdz7a/HrGE0XwLV1Q/P827M3tvMgkWuhNq7zqQpG7Fx kJKaIocos3QjeuS2MagEcUBAbEuFy7j8oyp4huaEmUwU9OigvO+Wx79YIsyMKNLw3GLMS2Nn/ Et9ayRRs5kVDFH/xVQqxwrnFWqwI5/xSLvepoTQBEeeNtA6Wx38MITtuitSTaq8jvzRQh6LrT ubgYVTCXqdhtAHKItrh3eaJFArR+VzqyzrxuLo6YKWz8AQsBDb+1qETEA1MUVqS8tdqFKdmaS +wi27RTibKG0tRlBj84h1V4sEBJ80vQ4vJTCVHj1Dkdxp9UXGyl186QRLoUPhUXRk+n162Syh Tlk9LalHPd+nfKC+2UzFo6VVGEnbjlzhM64/zrHGLhxeFd8dLLnrzM4lED20LviHSfm/HFEyF 6+HsR+tiW9AyBDdeP7yB1EeDzab24Wy2Gdh2LAAkq+CB++KkK2VSvVJWj8pQqJ9a1Ksg9j67z +NhjSlOqwnbUVoq5qOUwdnHzgCkXIzoDr6h3lELjDj7+6UJodBNuPAPnrFla2zAeq31bTMTxj b8IaoRZB5k45ibtwydJTdLV3dDm23vmtcvPwGG+/hA/P6Nm/NdjmAxtTD99KkKTGp77I4bCQP TuqHjVKorVYJAWV374pr7ro2P3DA0W53clU/awtL/SYKfke8w8vU1V07Px+A= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.12 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 , 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 Sat Oct 5 13:05:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 11175651 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 E3CA517E6 for ; Sat, 5 Oct 2019 13:24:16 +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 9EC662133F for ; Sat, 5 Oct 2019 13:24:16 +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="kUO43oqf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9EC662133F 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]:56736 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGk2h-0002lj-FL for patchwork-qemu-devel@patchwork.kernel.org; Sat, 05 Oct 2019 09:24:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:56790) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iGjkx-0002mv-CR for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iGjku-0005V5-Og for qemu-devel@nongnu.org; Sat, 05 Oct 2019 09:05:55 -0400 Received: from mout.web.de ([212.227.17.12]:34451) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1iGjku-0005UC-AK; Sat, 05 Oct 2019 09:05:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1570280741; bh=eRknjklDO4NY1lsxHvB+cdjugcevyUUzS5Qo8fAz594=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=kUO43oqfertyRVoX3BHKfgSFWnU9yEMdS0lP4sy3Qe32RAPINvWDlk5qNZXUAb6QO MB7xQitoVJKVdRJKFahCCiDsnqXtZV2LI+XN9VMtSHXGxRAtH0TwUrNde1AfOm+4j5 XJ3AsrALNGk0DsPkRkrL40lsipO5nluPfQfoOtSk= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([87.123.206.231]) by smtp.web.de (mrweb102 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MBTEQ-1iRDbH1Mv8-00ARyr; Sat, 05 Oct 2019 15:05:41 +0200 Date: Sat, 5 Oct 2019 15:05:40 +0200 From: Lukas Straub To: qemu-devel Subject: [PATCH v6 4/4] colo: Update Documentation for continuous replication Message-ID: <23a8a3d00523999e2b6f52074fa0f4c7f3f469ef.1570280098.git.lukasstraub2@web.de> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:ELni6//FQTpoTrgUs0yyob4vpjF/H8Ymoca3aZLNyFHlqvh3GqZ g3mIoANPHXLmRGVpVvEm5e9yCe11yzPB2fLLARwduyin0V5A90z0ApOgvOEnYKG9sIJPDWn pwsjbAwAmNsV8pEEYlSG+2FPJkxMPUr7sYL8B5+IRo87WdNQTuCH+76dPNnVXAiesBaKqUy rvhh+n0/nKlMuX9A0Cq0Q== X-UI-Out-Filterresults: notjunk:1;V03:K0:69SM3qQhG1M=:DvHJngTg+PnCrZMaFozd7J y/brXX17fogZrIgx/r9ZmOvngmzHsC98b9X9+zneMDk534SWXOuSyDIFetcxiiA2vl4XDXzNZ oiKRj9lxxk0I5UT6sjvAXMh2CoZR/s6PTyIQpB9P+3Sqr4j6/opITEbBC/rMQ2XNHxSEXRXZs RdJsV3E4IYMb/F50KJRMyrkQAfJQ1iEs2WSTC8iKzHocy5apyJZh7xeGW7SEruDbrujjdQuOM 4IRfbw6GL0attcWH7MbCvzLu9oKt8OO3C4ufeAj7eVM22nzev8zaZg57pautRst8p2tSEhzIe /086jfs776egn1IrdVaaB5L0ijEzMfDeFztp1lyzZLd3MiN/Sis7Pt8RCi9p9hW7Cpdn9QXYR JyhnCISct77Moq9ZpzUl1FujnMFYdb/9jjVr5Q3rIwtUsHPtUFxyuzlvfQbayuvwn6xVwXd6K UpcJwXlreATS+o8aI/hWBuUHOWI/ch015g/TByju5aLXTPtpy+T7C8rdoM2mvKWy+AMhSEtBp 2437khHUexbKaHe0LjEKuEtKlvqpIp0SpreKD8THLFCLPeiByj4XU9d9iB4X8mFWYkBe7U283 BcxOFFPagSRWCmJb68AhPprf1TvYB4gPoR3OhWli8fVgBOO463/G5lxYf2Ms3k3olpR+iVXCk SuYIkn77frwr2tCC5LC1zHHteMJjlt2ZTg9uBMmjwZBQ+TXzJw83GKGdQTYSYcu6T1Nj5J0CY sYpdR0qfBMSweqDUlZMHisWHQrENfhLisjaLr+dVYr/AGQH5YcNlLaoFrj1tMh5fuR4jpBGfN +MHq/DUDkJNz9AU01yL4DmG/6/whuhsiWlLjhdMVQagIiwx9w1c3Jir20ljgqZlVvBrSUiBij CL5KJPhl6f90AVC64UojcWMcqRoa/cB0L0oe1iZx7jFFleLP2EEwrwr8whaVA6J9zkLkajK1f +wnWB1v5Yeq2Lm7nEzibna24fRsbzm4Zy4POh2AaIaBWdU9vvaVjgJ3m8dkzmsnZ5S0317A3E EkfvTBLJo3FIo5KFWPeYAbKswT06ufbskRAw9hXGI4brSLUkcuvOeZYENGi1wzUmboNdox2Zw YKKzvsEA4kTB1TIfpMds+kv+Xr0WqqkN956CUN4mYbf+9s3DKfUUWYCOKenpQhPhhO1kWiGHd lhCBBOpCBiOM1aUGB3Gps/HVA1X63GC6S4v1lrrpLFBi+mKHHEqt57+VqBEcuKYUHQky9n/qI YCXi/PXmGSBcnbPmppTh/gTb4fuKXCivs/yXRGBBULErrz3hsKy3xWbh7+ls= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.12 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 , 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 --- docs/COLO-FT.txt | 213 +++++++++++++++++++++++++++---------- docs/block-replication.txt | 28 +++-- 2 files changed, 174 insertions(+), 67 deletions(-) diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index ad24680d13..bc1a0ccb99 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 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. +# 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: +# 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=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.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 @@ -182,44 +212,113 @@ 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.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