From patchwork Thu Aug 15 18:08: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: 1147746 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="JtTS9op+"; 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 468ZJR0784z9sN6 for ; Fri, 16 Aug 2019 04:11:03 +1000 (AEST) Received: from localhost ([::1]:45818 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKDE-00087N-SA for incoming@patchwork.ozlabs.org; Thu, 15 Aug 2019 14:11:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34257) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKB8-0007RV-Bl for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hyKB5-0006c0-Vw for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:50 -0400 Received: from mout.web.de ([217.72.192.78]:49285) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hyKB3-0006WD-Pr for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1565892506; bh=1aMK3WcfXGtXkTJdGeILldP4LKkJ6RJ1Yf8zxuMXcY0=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=JtTS9op+mNlmcwE89uGiKLqsFcKRsAeTbjDAXk7rFPUbAbYALNvgIdYuODi2xSk1+ Gfk9jKMPQOA/vMkvUTk2c29ZpJEQKN0anw/DAMKyGJ00myHaNrsLlHiP469oP0T0RB EbLb+AooWQo0ylXJeoVjwXDMhuE3ilxzmMXoKvKc= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.245]) by smtp.web.de (mrweb103 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Maaur-1hii3v2OrZ-00K7tj; Thu, 15 Aug 2019 20:08:26 +0200 Date: Thu, 15 Aug 2019 20:08:23 +0200 From: Lukas Straub To: qemu-devel Message-ID: <20190815200823.3de1bd14@luklap> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:rM1nWaZ12bjUfaU57768Ifo1LoOkeyHGgiBGivHQ36HR+pe99mB ZFr6ZyvdhoclTvIBydSrvru0Gq2ozdWVQf1anXr9dkTObBH8KTwiYlZUwAYXqM5P/92M1ac UFywEHBBIlteyIWs7U8fD8P4JKG8T1vUQ1XA9XlRCaAniEUMKihxqbg+5PgMhU4GiCMtUds bMN9NHq4WGlfSQoMYOGgA== X-UI-Out-Filterresults: notjunk:1; V03:K0:1uReHKE3F4A=:8CNo+FMgWhHDQ9awysVLHq KgFt0p/13cmKAFUYC+8oFk8/25LudFgCPkQYehszrGSOATqXcr+/Y3sETWqXitUYYyKjmTBR1 6D9JY/8SDuusvAiOSPfPayX5gePpXPcFSrw7tNEadnZaPBo/ldV9QVkuKNsqhroC9vQUZOOsk mm0TxbR4XnwtbN5wHdhb1yxU5mroe4D3QVsumaRqwu7n5MJh/3obnm5U1hf8eoWYNf80XDBNi AdgcOE+rA58vILoz84fzHtjM02wV7c7CnOru65QQ54WxvSb7DXaG2hifLkrmJ8lJ6HgkYR+jr pvUTGHRA0vG0zzuGV5tvAGk4DUL1r579DnacXrQIiV8DwiDprN4K8hMY9edCKnrcKcHOqim5s 0dgPUeagXXa/02J55964Vy0z4LrGtz5r70k+ub+cCnad/JQJ7ye/VsbQOG9JNDyCevLHsYHTz sU81BUqo3vZysYk0pDouCUtmxQ3RBIVHadBLmp0GVcguNB7ViLevecB3T1Trj069ZGn3k2twQ 5tGp/GNpeqbeRKDfAxvKUmYBX4xqRVZAAxqDeOto9CoS+ryuDiD1ZlkUS+r4detk3BAZJJifu YIdfTafu3UqPTQAVPdcYm/zs/74Nsx/wYjwYXCT86H6YlPT6krEZ7je6KsYK/K13TTGU1YxoV tEWCPe9pJCRIs0oFv2P5p33tJZ9fCLMG8IOlbvO+DSOrEXZhoUp+6c1E5aOLzJH4rGd92zoFK oSqmvm4N9LgKIk+OBnTnB0sWIL4htL/+2gAE1Ej9/xuo9SZqs/IHNp1xl7xMbrB5PxILdDice N55BBLkQEY268FJvuJyLW+qHKprIxzT/raDl3Xu2to/lTF0R9Ae5dQVydC4Vi0iRIhyC/Freg kPLbnYuHFgI+vqFopPT6Zp+fY0cTt4SKzCXN+0StjBgqGAnFVmnc3Ok1rtH97egl/SiBW2Yb3 uLu+j2rVblew1uhxD+hKbLbP6f/WOupZNBL4dHa5p7mSplJMI2BpFh+bnmQrIJe/eVmb5HRWO 1vczH2He7cHXQ2UGsoW67v/esy0uF88dJpw/0+BAVoO93nux9x6WKkHD39ul/RcB3eKstQgtk Pvg+UgUdlftsb6sIx5mshmgJ6/95yfSt9skBH8xbm82flbKIYebhdYdqmyz0Sve3qM8MTcR34 ivLUA= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 217.72.192.78 Subject: [Qemu-devel] [PATCH v2 1/3] Replication: 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: Zhang Chen , Jason Wang , Xie Changlong , Wen Congyang 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 --- 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 Thu Aug 15 18:08:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1147749 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="Imy/ms8r"; 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 468ZR32kGYz9sND for ; Fri, 16 Aug 2019 04:16:46 +1000 (AEST) Received: from localhost ([::1]:45856 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKIl-0004UX-Hw for incoming@patchwork.ozlabs.org; Thu, 15 Aug 2019 14:16:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34312) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKBI-0007iV-7V for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:09:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hyKBG-0006qo-5l for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:09:00 -0400 Received: from mout.web.de ([212.227.17.11]:35653) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hyKBE-0006kf-39 for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1565892513; bh=lWpltg5ktOFn/3NdP2OLih9c+P9SmdyvyAgJtuJDT7s=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=Imy/ms8r3hklR3pGNTHVuj1K8aNajJRvu4zKVMb+4uZ3N/Ws+6yTrvGb7OORC8ePs 0jmJn8eAtTNY68J4bKWImeqgx7/KH2Qx16J7eobW+kIpb/EcMlbeZXcbrdaEAYmA/q 5FxyMmPW0eeSZX/j3K72jgPCVDcCBBm5zzwVhG3c= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.245]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0MT8o6-1hp4Vy42lS-00S42u; Thu, 15 Aug 2019 20:08:33 +0200 Date: Thu, 15 Aug 2019 20:08:29 +0200 From: Lukas Straub To: qemu-devel Message-ID: <20190815200829.3a558eb8@luklap> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:OdPUBM2o7+QBccgn4o3g/7MZ6CLZ9QT4Eau3BLw2SO4aeBc1d7U pOYjuIfgGJOfW4+46S6ViSm0y3JVrZUv7yzCbWXgN7oFCRbZbCTu1xejNXM2dz9ZIXh/Vjs o2oduRhbes6+Uadmp0tWDvR5PmzyR8yoRA/rmPvbSljNJwwomNL22h9GsIX+azWU5GK4BqG 2/PG1mxl7ByqyrxNm6Ukw== X-UI-Out-Filterresults: notjunk:1; V03:K0:W8lim6rwjeM=:GBUnWdVPVRaZBXrZJFQXcz z2Qday3Y7rRwW1Uu/z6nBAQ3zw6vlNbRTCVLcW6LzSngoNqJOnqC/P7Mxw4IwPnZ8Mg//cNUP GZvaN4LFt9RGTGxNax3G643sfv7fOPe3dHPHUO70CSNjX4K+zQiEITt0k+Kh7zrSUN3I+NUTy ZPay6TshDBqdkThEDlToVEEQ8c1OfPjRjQX/LMBAAM4Ug/0A45KjpVmPpn1Fs6NwcOnzyAo46 RZYq0uAFx++3zqMYAOh1mjoJmypJdi98D5sooM9aaYD8MJezXeJEtQjqIHSlBner+MMtMTBaO nLSeIkJvK3zHlzCXAEAMP0AhSHkNaaeTeUF6jWcy1qs43aAb1vcqhN2e/SXvBAB4c6Vz2q7bb fANECEqtBLh0H2e1A3b7fpqRoUvr0gowtlWS+LsOjGsf7RppZ30GMJeAKiS4ffUlB25aJZxpy tY9MP9S5tPArEZ+IeLmLXELzFDAEVvle7IyXbtN4V4o3kPDwTHhh7nY68Wi+qS2Ii/tkFCH1B Feem5kl5RfeWArKzu48w2fhbTlK2jXvp959Uv91dMJdagX6NLoIhL8nT2Xn6QXQOENWsZgUe5 FOcbkGrl1r0IxIJ4u5Iu4QRtA1gbNkmttT26eh7CNue5CF921zPV9wRljzaKeqGu1qCHx2svk rm64SYEhcZXea+79aJUwsZbFr2AjqP222IVTlplvfXtMXMCCnNv5ghp7ZMcEsOn3sqtZ7rLy7 FGyXPHhf4oNpaCv0bVph4bC5ktn69z3Wdp6VjdUqLiFibOkn2lZXSjpG4kX1dTBWYhXI1ddin JHBBB0qGdpVe5YSs4iBlXUgtmTjRMUH0lSHVtOi+qasNjwt6Lzy//6XUk7ONctw72fsHBfwzy ZTj4WvxXkIJNhX2eciMOreHdb6qRq23nNjscAOem56wPjOjcY1+8YcMnCnIlXdaFjK3b3aTd/ chsWJe42lzm/QQY6HKnhcv6HsdUrj3xIBOea/uOG3y9sUBv3EqeU5vMCkbNwejK8AQ48GZQfL zU0HkA5PbjF0+9PTC5KfyXVdHq6lyrFLYmAtN8WiRM1adG9QkY/H3m21oVO9YopUvBzQRuADZ R/7c8wvvHd8CDEYOOcC/4mdHKkvljy8DiMhQHsX2UzfKlT0U5fxWwqiHLuYoRhPv2UpIN9ziu 1y2woGqS08w+oH502+3xv2Zw43rCAEQIAJ6WrVXCEHHG1kassLOTbYkOv8SivUM/YMDc8= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 212.227.17.11 Subject: [Qemu-devel] [PATCH v2 2/3] 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: Zhang Chen , Jason Wang , Xie Changlong , Wen Congyang 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 either "head", "tail" or the id of another filter. insert should be either "before" or "after" to specify where to insert the new filter relative to the one specified with position. Signed-off-by: Lukas Straub --- include/net/filter.h | 2 ++ net/filter.c | 71 +++++++++++++++++++++++++++++++++++++++++++- qemu-options.hx | 10 +++---- 3 files changed, 77 insertions(+), 6 deletions(-) -- 2.20.1 diff --git a/include/net/filter.h b/include/net/filter.h index 49da666ac0..355c178f75 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; QTAILQ_ENTRY(NetFilterState) next; }; diff --git a/net/filter.c b/net/filter.c index 28d1930db7..309fd778df 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 ? g_strdup("before") : g_strdup("after"); +} + +static void netfilter_set_insert(Object *obj, const char *str, Error **errp) +{ + NetFilterState *nf = NETFILTER(obj); + + if (strcmp(str, "before") && strcmp(str, "after")) { + error_setg(errp, "Invalid value for netfilter insert, " + "should be 'head' or 'tail'"); + return; + } + + nf->insert_before = !strcmp(str, "before"); +} + static void netfilter_init(Object *obj) { NetFilterState *nf = NETFILTER(obj); nf->on = true; + nf->insert_before = 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,20 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } + if (strcmp(nf->position, "head") && strcmp(nf->position, "tail")) { + /* Search for the position to insert before/after */ + Object *container; + Object *obj; + + container = object_get_objects_root(); + obj = object_resolve_path_component(container, nf->position); + if (!obj) { + error_setg(errp, "filter '%s' not found", nf->position); + return; + } + position = NETFILTER(obj); + } + nf->netdev = ncs[0]; if (nfc->setup) { @@ -228,7 +285,18 @@ static void netfilter_complete(UserCreatable *uc, Error **errp) return; } } - QTAILQ_INSERT_TAIL(&nf->netdev->filters, nf, next); + + if (position) { + if (nf->insert_before) { + 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 +313,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..f0a47a0746 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{after|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{after|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{after|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{after|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{after|before}] Dump the network traffic on netdev @var{dev} to the file specified by @var{filename}. At most @var{len} bytes (64k by default) per packet are stored. From patchwork Thu Aug 15 18:08:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Lukas Straub X-Patchwork-Id: 1147744 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="fTUhRiLD"; 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 468ZJJ37Phz9sNk for ; Fri, 16 Aug 2019 04:10:56 +1000 (AEST) Received: from localhost ([::1]:45806 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKD8-0007jz-3F for incoming@patchwork.ozlabs.org; Thu, 15 Aug 2019 14:10:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34287) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1hyKBD-0007Ud-DP for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hyKB8-0006fH-92 for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:54 -0400 Received: from mout.web.de ([217.72.192.78]:46047) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hyKB5-0006au-Vs for qemu-devel@nongnu.org; Thu, 15 Aug 2019 14:08:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=web.de; s=dbaedf251592; t=1565892516; bh=JG1Avi7Oca3GslRcQqG5Jk+YrYiZWG7vyGoqSBKja0o=; h=X-UI-Sender-Class:Date:From:To:Cc:Subject:In-Reply-To:References; b=fTUhRiLDBQ35x1euexk5XIbpPBh6f6AyTi/+HJdnckJxwWYIQ5/K5uguD/Qm6CJqQ BVZ700FXByvnO97Eayv9E72ODJQnVsFB5HwNfMvfv4KhVClLVYMe4LikVJ3tdokeYS NypQ0bTe2+Dh7v3ScDh6tm13XIBEDIHL7uCiOBfM= X-UI-Sender-Class: c548c8c5-30a9-4db5-a2e7-cb6cb037b8f9 Received: from luklap ([89.247.255.245]) by smtp.web.de (mrweb103 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Lm4hJ-1iX6lJ1lWD-00Zjkh; Thu, 15 Aug 2019 20:08:36 +0200 Date: Thu, 15 Aug 2019 20:08:35 +0200 From: Lukas Straub To: qemu-devel Message-ID: <20190815200835.20f24b5f@luklap> In-Reply-To: References: MIME-Version: 1.0 X-Provags-ID: V03:K1:wJiT6/HV0o8p7nIfWhPWjRouTpAlH4Xc1bka5IZRbJZj+GXH3f4 qQoKv0Np713y+UVRIedkchc2LYhXX/AlY1d9jSBuryN2AaFVWUvmw5e4N6mkG+bB8a7Swix msirlZqrTxO5bKtv3He/IiEgg607yvqbbNOUG3giKmtr6bcF5OuAT8QeamcyUW5gud0mos8 9yO4uAoxEegxXP9H62kyQ== X-UI-Out-Filterresults: notjunk:1; V03:K0:5uHPlfZxhqc=:jwcTjFXue3XqeggVfZfhnn kZL6n26W5Gi+dB9tbmmUtY13MVsDGq+OgHAKMvRmVN7an+3KcVD5IjzBPE8lfn+y+zDbLFtrZ UF6xdvtDKm0Pftdck2NRC3UHUomFikvhIMMUGArS2FsTKZKMLCDWew4RgTXRK1GCFJvuRD/Wh DiSCc23wIltE7ByW70kJVArbr3UVsBGosymXueu+0GdE+oSvqX88IsIN2I/cgX9e+nAGzLudP NZohBrJcU2fIezOMpfyZSy4ouvBbk7UcQd790n6LkE7d9OqheyP+f4tkeDAOD/pfkwZvZE7cC uj494t0drdlw4RsDHM+4e6De+8aFZ2pWWOUD54YygxcY3B2CmHW8P4a5b+h0ROoZRdfEAJcQ4 rCOsEDes3lhjtOyom6FG9x6ScOgrdopOekx3qGkCoMNknIhf0M/GF3r4jyropJDS5DOBggR9o ksCpLET5fAhXjMx7o0asvifwlUhp8sARGYk2GDnL95Utp2MfaBaqebEhSavwzDAZu0Jvb/225 ScKtpT4KTmLUMYDjkpu/mJ0vtecIPQYxBz+GWbZcqJD1XhA6yTYBSo45k4XDqpSuo26rVq6N3 GxYDujr1w9So+Aa+MnhZMU8DuzyhAIjnPAUHHKCFcPDOphUs5irSDHY2Euz9UcBAXsPRegSx2 BB244v89pGYD8LcC/YhbnpV7vBGBp48MXJ6A1sb6lyh7zcf0AfOoedOl6yzzlcrod69bO93SM KuU0xW7QA5ik0Mpgr9v/AYkaNaJgrEexdNPZtz7//mP5IDFFsgVseXbKVl6I3Wrso8EY0HFxE 0YdDf8mkYoNRw2uciWS48ZS90wyhUSWAgMgyxV/E5KWfjsxwWGLUpBPJMq3qNjiY2/3L7JyDP tjgWt6aRfjG89JfJl1mQntP0j9ZklB1TIW4MafSlCrHrqwGbPSLt0xLuOgX3ZiciPKrzv0rOX VQsoF+RsTvcBjcm39Qyi4BY2eaWSb7qMmH3JCVFy2CU1cIU8cLmqOmJM08uuThnEGHEEhSNQx SN+HLfsdLLkbmlPyAwau6laP4ySLoCzBcS+nLc0b1JQ7HsYG4l3hwlToQR1fFbz53S0QjtO9R B14828MFjrQosyPkipco7664zWG/jN+AaFp8GMnBrpyn/yIDf9tKz/Ihfv3Z5yXqFdmw09E42 AgvGU= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 217.72.192.78 Subject: [Qemu-devel] [PATCH v2 3/3] Update Documentation 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: Zhang Chen , Jason Wang , Xie Changlong , Wen Congyang Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Document the qemu command-line and qmp commands for continious replication Signed-off-by: Lukas Straub --- docs/COLO-FT.txt | 185 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 138 insertions(+), 47 deletions(-) diff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt index ad24680d13..c08bfbd3a8 100644 --- a/docs/COLO-FT.txt +++ b/docs/COLO-FT.txt @@ -145,35 +145,64 @@ The diagram just shows the main qmp command, you can get the detail in test procedure. == Test procedure == +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 + 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 +# imagefolder="/mnt/vms/colo-test" + +# 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 -k de -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 + 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 +# 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 -k de -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.file=childs0,children.0.driver=raw \ + -incoming tcp:0:9998 + 2. 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 @@ -184,12 +213,10 @@ Note: 3. 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. @@ -199,27 +226,91 @@ Note: 4. 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 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. +You can kill one of the VMs and Failover on the surviving VM: -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 +== Primary Failover == +The Secondary died, resume on the Primary -Secondary: - The primary host is down, so we should do the following thing: - { 'execute': 'nbd-server-stop' } +{'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, 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, 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': { 'insert': 'before', 'position': 'rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'insert': 'before', 'position': 'rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } +{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'insert': 'before', 'position': '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' } } } + +{'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.