get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/2195197/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2195197,
    "url": "http://patchwork.ozlabs.org/api/patches/2195197/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260210-colo_unit_test_multifd-v7-15-23bd32f36828@web.de/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20260210-colo_unit_test_multifd-v7-15-23bd32f36828@web.de>",
    "list_archive_url": null,
    "date": "2026-02-10T14:26:27",
    "name": "[v7,15/18] Convert colo main documentation to restructuredText",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "bd76c3da3b78c81bdfdcd2ad374e6514e5add803",
    "submitter": {
        "id": 76468,
        "url": "http://patchwork.ozlabs.org/api/people/76468/?format=api",
        "name": "Lukas Straub",
        "email": "lukasstraub2@web.de"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260210-colo_unit_test_multifd-v7-15-23bd32f36828@web.de/mbox/",
    "series": [
        {
            "id": 491685,
            "url": "http://patchwork.ozlabs.org/api/series/491685/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=491685",
            "date": "2026-02-10T14:26:13",
            "name": "migration: Add COLO multifd support and COLO migration unit test",
            "version": 7,
            "mbox": "http://patchwork.ozlabs.org/series/491685/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2195197/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2195197/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=web.de header.i=lukasstraub2@web.de header.a=rsa-sha256\n header.s=s29768273 header.b=JVii5CjG;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f9P7H29Zxz1xtr\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 11 Feb 2026 01:28:27 +1100 (AEDT)",
            "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1vpohc-00058t-39; Tue, 10 Feb 2026 09:26:56 -0500",
            "from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <lukasstraub2@web.de>)\n id 1vpohT-00055s-PL\n for qemu-devel@nongnu.org; Tue, 10 Feb 2026 09:26:48 -0500",
            "from mout.web.de ([212.227.15.14])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <lukasstraub2@web.de>)\n id 1vpohP-0005j6-Ol\n for qemu-devel@nongnu.org; Tue, 10 Feb 2026 09:26:47 -0500",
            "from [127.0.1.1] ([141.58.43.188]) by smtp.web.de (mrweb005\n [213.165.67.108]) with ESMTPSA (Nemesis) id 1MG996-1w1yqU1SaS-004cAU; Tue, 10\n Feb 2026 15:26:42 +0100"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de;\n s=s29768273; t=1770733602; x=1771338402; i=lukasstraub2@web.de;\n bh=hGC+m0tA3M0So0oR7D2e5cbVpsMtE6mQ3ydGsBOWEV8=;\n h=X-UI-Sender-Class:From:Date:Subject:MIME-Version:Content-Type:\n Content-Transfer-Encoding:Message-Id:References:In-Reply-To:To:Cc:\n cc:content-transfer-encoding:content-type:date:from:message-id:\n mime-version:reply-to:subject:to;\n b=JVii5CjGKW33l29wUsx5JBmxugg89r9GYcLfLsXYue9eVteV6WBg3u32zEuKNuin\n 8j4dxCH5SCIEOtatFn1sn2mz2sGCABKD4mdcS/FGXyEpBBB4OUsCsehhy+wGym9Mv\n QnkqRvb9H29rZRttpqwiaEHMr2bSRtIxA2kb05He4V6hiDDc5SorqC9YcVNu/W8hB\n JgsC65908FOiX9YqSPLvCpZsFLUsISTXSCg5s9O+ByWOvEpXXA8AANo5zXlhpEdUu\n 52jKFA3ktAcXJQARGeK1ZUByIW7t7SbqcPCSY/YBxoCZDNx+lJxepkM9ORK5iqGe2\n Sn7b9SubX2RanTgqQg==",
        "X-UI-Sender-Class": "814a7b36-bfc1-4dae-8640-3722d8ec6cd6",
        "From": "Lukas Straub <lukasstraub2@web.de>",
        "Date": "Tue, 10 Feb 2026 15:26:27 +0100",
        "Subject": "[PATCH v7 15/18] Convert colo main documentation to restructuredText",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "Message-Id": "<20260210-colo_unit_test_multifd-v7-15-23bd32f36828@web.de>",
        "References": "<20260210-colo_unit_test_multifd-v7-0-23bd32f36828@web.de>",
        "In-Reply-To": "<20260210-colo_unit_test_multifd-v7-0-23bd32f36828@web.de>",
        "To": "qemu-devel@nongnu.org",
        "Cc": "Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>,\n Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>,\n Zhang Chen <zhangckid@gmail.com>,\n Hailiang Zhang <zhanghailiang@xfusion.com>,\n Markus Armbruster <armbru@redhat.com>, Li Zhijian <lizhijian@fujitsu.com>,\n \"Dr. David Alan Gilbert\" <dave@treblig.org>,\n Lukas Straub <lukasstraub2@web.de>",
        "X-Mailer": "b4 0.14.2",
        "X-Developer-Signature": "v=1; a=openpgp-sha256; l=41531; i=lukasstraub2@web.de;\n h=from:subject:message-id;\n bh=+Fe4mH4KK78+TLQ/FOH4wNoY+Th9EiHhTnmw9JF8BDE=;\n b=owEBbQKS/ZANAwAKATWrCyicXbJYAcsmYgBpi0Ac/cxIJkOwjq8PsnZFJHntLWJBlCLoPvsQu\n b+TOdUxUWqJAjMEAAEKAB0WIQSD+rFYoNm4+3Jij6Q1qwsonF2yWAUCaYtAHAAKCRA1qwsonF2y\n WKmvD/9SCQkleCYh4F5NNuPcHXyOTDOnR83zDb3bZeyrmkuiGxkihn4q6NQbL+7iwO9P5ulT8Fs\n LdbDhLGPWw54KiRwJ24iqHY3i91iMt12eUMRWK1RykKsFL+NcTGjk9lGugbt7U1icS6+NAb+RTy\n WtapoRT7rx1Y38gf6VUeEDUZfvAYq1xBrTiwkwjtYMUo0PAulI5ClGOdBOe5snM8Jvl3oxGg+Ox\n /ikgP6wpT3LdtFmJNUbTe/3v99FkDkFOHeu09Ug5dOTHcy/upOSiGPcaO/ueciCxID3tUEUJDtN\n 8Jaw3Q7cJaynIg13NSsuUzYF/FBmZq4XDXbab8nTGMolgfSMamIx+1lQHxnKfas8cM+6Ht9cHtM\n 2oNgJeMB2uB5yKRCBaS+o0p3hDZ6qM+EKKCZ4EnM0KjGr1QWgIjgtvgE/PGoAKmg3uwpxEoNbTV\n XRz8qvMOeNXe5fY+/3dePwFW+u8N5/NNE3Z47nExFK3aMhzX5/kcC2qkEb3URMVr0RbtQWkviQ6\n 15bBZ6d5/GgiMLZUMCvmglKoRlGLBJwhKKTjXWinI88LHdyzB2UrojvBIoICe0bE8sSWtKxQIXr\n dD3wHPVAbBHrAM2hxF+K2rKthwm/Z6NbeJZexCDA7StidB6wEn97MIs2r1TpfJKAMBhEXpR++5e\n RgJ4lAmt3TQxhjw==",
        "X-Developer-Key": "i=lukasstraub2@web.de; a=openpgp;\n fpr=83FAB158A0D9B8FB72628FA435AB0B289C5DB258",
        "X-Provags-ID": "V03:K1:6rWul1ozgUP4efaI/SaQqLxvDgCgqyFCKWhLMmDKAaxcsfaoXuH\n pmHljA6ldFc/lOvNnYRbpj438Js1WgQuQqmijbWlVw+mWd/acs1XIQjOntQ3nQfepTFHDoP\n sFsOKhTZmYzkU37zBvn/Mvc9pOW6siGgd1Go0+Lq/8qNnaxJAutcm4hi/B4Lk6xgHkm/uJ9\n etW31me3NRkCqNEknvsBQ==",
        "UI-OutboundReport": "notjunk:1;M01:P0:VmdSWoPGNQk=;4RTPKoxhP75RJJkmNyAtbAq03lk\n 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",
        "Received-SPF": "pass client-ip=212.227.15.14; envelope-from=lukasstraub2@web.de;\n helo=mout.web.de",
        "X-Spam_score_int": "-24",
        "X-Spam_score": "-2.5",
        "X-Spam_bar": "--",
        "X-Spam_report": "(-2.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1,\n DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7,\n RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001,\n RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,\n SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no",
        "X-Spam_action": "no action",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "qemu development <qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"
    },
    "content": "Reviewed-by: Fabiano Rosas <farosas@suse.de>\nReviewed-by: Zhang Chen <zhangckid@gmail.com>\nSigned-off-by: Lukas Straub <lukasstraub2@web.de>\n---\n MAINTAINERS               |   2 +-\n docs/COLO-FT.txt          | 334 ------------------------------------------\n docs/system/index.rst     |   1 +\n docs/system/qemu-colo.rst | 360 ++++++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 362 insertions(+), 335 deletions(-)",
    "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex fe6010929fc4cb83bc8a7686fbe537f1120f1eba..50beba7cb105efb867c7d8cb140357f329241654 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -3863,7 +3863,7 @@ F: migration/multifd-colo.*\n F: include/migration/colo.h\n F: include/migration/failover.h\n F: tests/qtest/migration/colo-tests.c\n-F: docs/COLO-FT.txt\n+F: docs/system/qemu-colo.rst\n \n COLO Proxy\n M: Zhang Chen <zhangckid@gmail.com>\ndiff --git a/docs/COLO-FT.txt b/docs/COLO-FT.txt\ndeleted file mode 100644\nindex 2283a09c080b8996f9767eeb415e8d4fbdc940af..0000000000000000000000000000000000000000\n--- a/docs/COLO-FT.txt\n+++ /dev/null\n@@ -1,334 +0,0 @@\n-COarse-grained LOck-stepping Virtual Machines for Non-stop Service\n-----------------------------------------\n-Copyright (c) 2016 Intel Corporation\n-Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.\n-Copyright (c) 2016 Fujitsu, Corp.\n-\n-This work is licensed under the terms of the GNU GPL, version 2 or later.\n-See the COPYING file in the top-level directory.\n-\n-This document gives an overview of COLO's design and how to use it.\n-\n-== Background ==\n-Virtual machine (VM) replication is a well known technique for providing\n-application-agnostic software-implemented hardware fault tolerance,\n-also known as \"non-stop service\".\n-\n-COLO (COarse-grained LOck-stepping) is a high availability solution.\n-Both primary VM (PVM) and secondary VM (SVM) run in parallel. They receive the\n-same request from client, and generate response in parallel too.\n-If the response packets from PVM and SVM are identical, they are released\n-immediately. Otherwise, a VM checkpoint (on demand) is conducted.\n-\n-== Architecture ==\n-\n-The architecture of COLO is shown in the diagram below.\n-It consists of a pair of networked physical nodes:\n-The primary node running the PVM, and the secondary node running the SVM\n-to maintain a valid replica of the PVM.\n-PVM and SVM execute in parallel and generate output of response packets for\n-client requests according to the application semantics.\n-\n-The incoming packets from the client or external network are received by the\n-primary node, and then forwarded to the secondary node, so that both the PVM\n-and the SVM are stimulated with the same requests.\n-\n-COLO receives the outbound packets from both the PVM and SVM and compares them\n-before allowing the output to be sent to clients.\n-\n-The SVM is qualified as a valid replica of the PVM, as long as it generates\n-identical responses to all client requests. Once the differences in the outputs\n-are detected between the PVM and SVM, COLO withholds transmission of the\n-outbound packets until it has successfully synchronized the PVM state to the SVM.\n-\n-  Primary Node                                                            Secondary Node\n-+------------+  +-----------------------+       +------------------------+  +------------+\n-|            |  |       HeartBeat       +<----->+       HeartBeat        |  |            |\n-| Primary VM |  +-----------+-----------+       +-----------+------------+  |Secondary VM|\n-|            |              |                               |               |            |\n-|            |  +-----------|-----------+       +-----------|------------+  |            |\n-|            |  |QEMU   +---v----+      |       |QEMU  +----v---+        |  |            |\n-|            |  |       |Failover|      |       |      |Failover|        |  |            |\n-|            |  |       +--------+      |       |      +--------+        |  |            |\n-|            |  |   +---------------+   |       |   +---------------+    |  |            |\n-|            |  |   | VM Checkpoint +-------------->+ VM Checkpoint |    |  |            |\n-|            |  |   +---------------+   |       |   +---------------+    |  |            |\n-|Requests<--------------------------\\ /-----------------\\ /--------------------->Requests|\n-|            |  |                   ^ ^ |       |       | |              |  |            |\n-|Responses+---------------------\\ /-|-|------------\\ /-------------------------+Responses|\n-|            |  |               | | | | |       |  | |  | |              |  |            |\n-|            |  | +-----------+ | | | | |       |  | |  | | +----------+ |  |            |\n-|            |  | | COLO disk | | | | | |       |  | |  | | | COLO disk| |  |            |\n-|            |  | |   Manager +---------------------------->| Manager  | |  |            |\n-|            |  | ++----------+ v v | | |       |  | v  v | +---------++ |  |            |\n-|            |  |  |+-----------+-+-+-++|       | ++-+--+-+---------+ |  |  |            |\n-|            |  |  ||   COLO Proxy     ||       | |   COLO Proxy    | |  |  |            |\n-|            |  |  || (compare packet  ||       | |(adjust sequence | |  |  |            |\n-|            |  |  ||and mirror packet)||       | |    and ACK)     | |  |  |            |\n-|            |  |  |+------------+---+-+|       | +-----------------+ |  |  |            |\n-+------------+  +-----------------------+       +------------------------+  +------------+\n-+------------+     |             |   |                                |     +------------+\n-| VM Monitor |     |             |   |                                |     | VM Monitor |\n-+------------+     |             |   |                                |     +------------+\n-+---------------------------------------+       +----------------------------------------+\n-|   Kernel         |             |   |  |       |   Kernel            |                  |\n-+---------------------------------------+       +----------------------------------------+\n-                   |             |   |                                |\n-    +--------------v+  +---------v---+--+       +------------------+ +v-------------+\n-    |   Storage     |  |External Network|       | External Network | |   Storage    |\n-    +---------------+  +----------------+       +------------------+ +--------------+\n-\n-\n-== Components introduction ==\n-\n-You can see there are several components in COLO's diagram of architecture.\n-Their functions are described below.\n-\n-HeartBeat:\n-Runs on both the primary and secondary nodes, to periodically check platform\n-availability. When the primary node suffers a hardware fail-stop failure,\n-the heartbeat stops responding, the secondary node will trigger a failover\n-as soon as it determines the absence.\n-\n-COLO disk Manager:\n-When primary VM writes data into image, the colo disk manager captures this data\n-and sends it to secondary VM's which makes sure the context of secondary VM's\n-image is consistent with the context of primary VM 's image.\n-For more details, please refer to docs/block-replication.txt.\n-\n-Checkpoint/Failover Controller:\n-Modifications of save/restore flow to realize continuous migration,\n-to make sure the state of VM in Secondary side is always consistent with VM in\n-Primary side.\n-\n-COLO Proxy:\n-Delivers packets to Primary and Secondary, and then compare the responses from\n-both side. Then decide whether to start a checkpoint according to some rules.\n-Please refer to docs/colo-proxy.txt for more information.\n-\n-Note:\n-HeartBeat has not been implemented yet, so you need to trigger failover process\n-by using 'x-colo-lost-heartbeat' command.\n-\n-== COLO operation status ==\n-\n-+-----------------+\n-|                 |\n-|    Start COLO   |\n-|                 |\n-+--------+--------+\n-         |\n-         |  Main qmp command:\n-         |  migrate-set-capabilities with x-colo\n-         |  migrate\n-         |\n-         v\n-+--------+--------+\n-|                 |\n-|  COLO running   |\n-|                 |\n-+--------+--------+\n-         |\n-         |  Main qmp command:\n-         |  x-colo-lost-heartbeat\n-         |  or\n-         |  some error happened\n-         v\n-+--------+--------+\n-|                 |  send qmp event:\n-|  COLO failover  |  COLO_EXIT\n-|                 |\n-+-----------------+\n-\n-COLO use the qmp command to switch and report operation status.\n-The diagram just shows the main qmp command, you can get the detail\n-in test procedure.\n-\n-== Test procedure ==\n-Note: Here we are running both instances on the same host for testing,\n-change the IP Addresses if you want to run it on two hosts. Initially\n-127.0.0.1 is the Primary Host and 127.0.0.2 is the Secondary Host.\n-\n-== Startup qemu ==\n-1. Primary:\n-Note: Initially, $imagefolder/primary.qcow2 needs to be copied to all hosts.\n-You don't need to change any IP's here, because 0.0.0.0 listens on any\n-interface. The chardev's with 127.0.0.1 IP's loopback to the local qemu\n-instance.\n-\n-# imagefolder=\"/mnt/vms/colo-test-primary\"\n-\n-# qemu-system-x86_64 -enable-kvm -cpu qemu64,kvmclock=on -m 512 -smp 1 -qmp stdio \\\n-   -device piix3-usb-uhci -device usb-tablet -name primary \\\n-   -netdev tap,id=hn0,vhost=off,helper=/usr/lib/qemu/qemu-bridge-helper \\\n-   -device rtl8139,id=e0,netdev=hn0 \\\n-   -chardev socket,id=mirror0,host=0.0.0.0,port=9003,server=on,wait=off \\\n-   -chardev socket,id=compare1,host=0.0.0.0,port=9004,server=on,wait=on \\\n-   -chardev socket,id=compare0,host=127.0.0.1,port=9001,server=on,wait=off \\\n-   -chardev socket,id=compare0-0,host=127.0.0.1,port=9001 \\\n-   -chardev socket,id=compare_out,host=127.0.0.1,port=9005,server=on,wait=off \\\n-   -chardev socket,id=compare_out0,host=127.0.0.1,port=9005 \\\n-   -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0 \\\n-   -object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out \\\n-   -object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0 \\\n-   -object iothread,id=iothread1 \\\n-   -object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,\\\n-outdev=compare_out0,iothread=iothread1 \\\n-   -drive if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\\\n-children.0.file.filename=$imagefolder/primary.qcow2,children.0.driver=qcow2 -S\n-\n-2. Secondary:\n-Note: Active and hidden images need to be created only once and the\n-size should be the same as primary.qcow2. Again, you don't need to change\n-any IP's here, except for the $primary_ip variable.\n-\n-# imagefolder=\"/mnt/vms/colo-test-secondary\"\n-# primary_ip=127.0.0.1\n-\n-# qemu-img create -f qcow2 $imagefolder/secondary-active.qcow2 10G\n-\n-# qemu-img create -f qcow2 $imagefolder/secondary-hidden.qcow2 10G\n-\n-# qemu-system-x86_64 -enable-kvm -cpu qemu64,kvmclock=on -m 512 -smp 1 -qmp stdio \\\n-   -device piix3-usb-uhci -device usb-tablet -name secondary \\\n-   -netdev tap,id=hn0,vhost=off,helper=/usr/lib/qemu/qemu-bridge-helper \\\n-   -device rtl8139,id=e0,netdev=hn0 \\\n-   -chardev socket,id=red0,host=$primary_ip,port=9003,reconnect-ms=1000 \\\n-   -chardev socket,id=red1,host=$primary_ip,port=9004,reconnect-ms=1000 \\\n-   -object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 \\\n-   -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 \\\n-   -object filter-rewriter,id=rew0,netdev=hn0,queue=all \\\n-   -drive if=none,id=parent0,file.filename=$imagefolder/primary.qcow2,driver=qcow2 \\\n-   -drive if=none,id=childs0,driver=replication,mode=secondary,file.driver=qcow2,\\\n-top-id=colo-disk0,file.file.filename=$imagefolder/secondary-active.qcow2,\\\n-file.backing.driver=qcow2,file.backing.file.filename=$imagefolder/secondary-hidden.qcow2,\\\n-file.backing.backing=parent0 \\\n-   -drive if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\\\n-children.0=childs0 \\\n-   -incoming tcp:0.0.0.0:9998\n-\n-\n-3. On Secondary VM's QEMU monitor, issue command\n-{\"execute\":\"qmp_capabilities\"}\n-{\"execute\": \"migrate-set-capabilities\", \"arguments\": {\"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n-{\"execute\": \"nbd-server-start\", \"arguments\": {\"addr\": {\"type\": \"inet\", \"data\": {\"host\": \"0.0.0.0\", \"port\": \"9999\"} } } }\n-{\"execute\": \"nbd-server-add\", \"arguments\": {\"device\": \"parent0\", \"writable\": true } }\n-\n-Note:\n-  a. The qmp command nbd-server-start and nbd-server-add must be run\n-     before running the qmp command migrate on primary QEMU\n-  b. Active disk, hidden disk and nbd target's length should be the\n-     same.\n-  c. It is better to put active disk and hidden disk in ramdisk. They\n-     will be merged into the parent disk on failover.\n-\n-4. On Primary VM's QEMU monitor, issue command:\n-{\"execute\":\"qmp_capabilities\"}\n-{\"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\"}}\n-{\"execute\": \"x-blockdev-change\", \"arguments\":{\"parent\": \"colo-disk0\", \"node\": \"replication0\" } }\n-{\"execute\": \"migrate-set-capabilities\", \"arguments\": {\"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n-{\"execute\": \"migrate\", \"arguments\": {\"uri\": \"tcp:127.0.0.2:9998\" } }\n-\n-  Note:\n-  a. There should be only one NBD Client for each primary disk.\n-  b. The qmp command line must be run after running qmp command line in\n-     secondary qemu.\n-\n-5. After the above steps, you will see, whenever you make changes to PVM, SVM will be synced.\n-You can issue command '{ \"execute\": \"migrate-set-parameters\" , \"arguments\":{ \"x-checkpoint-delay\": 2000 } }'\n-to change the idle checkpoint period time\n-\n-6. Failover test\n-You can kill one of the VMs and Failover on the surviving VM:\n-\n-If you killed the Secondary, then follow \"Primary Failover\". After that,\n-if you want to resume the replication, follow \"Primary resume replication\"\n-\n-If you killed the Primary, then follow \"Secondary Failover\". After that,\n-if you want to resume the replication, follow \"Secondary resume replication\"\n-\n-== Primary Failover ==\n-The Secondary died, resume on the Primary\n-\n-{\"execute\": \"x-blockdev-change\", \"arguments\":{ \"parent\": \"colo-disk0\", \"child\": \"children.1\"} }\n-{\"execute\": \"human-monitor-command\", \"arguments\":{ \"command-line\": \"drive_del replication0\" } }\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"comp0\" } }\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"iothread1\" } }\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"m0\" } }\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"redire0\" } }\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"redire1\" } }\n-{\"execute\": \"x-colo-lost-heartbeat\" }\n-\n-== Secondary Failover ==\n-The Primary died, resume on the Secondary and prepare to become the new Primary\n-\n-{\"execute\": \"nbd-server-stop\"}\n-{\"execute\": \"x-colo-lost-heartbeat\"}\n-\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"f2\" } }\n-{\"execute\": \"object-del\", \"arguments\":{ \"id\": \"f1\" } }\n-{\"execute\": \"chardev-remove\", \"arguments\":{ \"id\": \"red1\" } }\n-{\"execute\": \"chardev-remove\", \"arguments\":{ \"id\": \"red0\" } }\n-\n-{\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"mirror0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"0.0.0.0\", \"port\": \"9003\" } }, \"server\": true } } } }\n-{\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare1\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"0.0.0.0\", \"port\": \"9004\" } }, \"server\": true } } } }\n-{\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9001\" } }, \"server\": true } } } }\n-{\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare0-0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9001\" } }, \"server\": false } } } }\n-{\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare_out\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9005\" } }, \"server\": true } } } }\n-{\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare_out0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9005\" } }, \"server\": false } } } }\n-\n-== Primary resume replication ==\n-Resume replication after new Secondary is up.\n-\n-Start the new Secondary (Steps 2 and 3 above), then on the Primary:\n-{\"execute\": \"drive-mirror\", \"arguments\":{ \"device\": \"colo-disk0\", \"job-id\": \"resync\", \"target\": \"nbd://127.0.0.2:9999/parent0\", \"mode\": \"existing\", \"format\": \"raw\", \"sync\": \"full\"} }\n-\n-Wait until disk is synced, then:\n-{\"execute\": \"stop\"}\n-{\"execute\": \"block-job-cancel\", \"arguments\":{ \"device\": \"resync\"} }\n-\n-{\"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\"}}\n-{\"execute\": \"x-blockdev-change\", \"arguments\":{ \"parent\": \"colo-disk0\", \"node\": \"replication0\" } }\n-\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-mirror\", \"id\": \"m0\", \"netdev\": \"hn0\", \"queue\": \"tx\", \"outdev\": \"mirror0\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire0\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"indev\": \"compare_out\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire1\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"outdev\": \"compare0\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"iothread\", \"id\": \"iothread1\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"colo-compare\", \"id\": \"comp0\", \"primary_in\": \"compare0-0\", \"secondary_in\": \"compare1\", \"outdev\": \"compare_out0\", \"iothread\": \"iothread1\" } }\n-\n-{\"execute\": \"migrate-set-capabilities\", \"arguments\":{ \"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n-{\"execute\": \"migrate\", \"arguments\":{ \"uri\": \"tcp:127.0.0.2:9998\" } }\n-\n-Note:\n-If this Primary previously was a Secondary, then we need to insert the\n-filters before the filter-rewriter by using the\n-\"\"insert\": \"before\", \"position\": \"id=rew0\"\" Options. See below.\n-\n-== Secondary resume replication ==\n-Become Primary and resume replication after new Secondary is up. Note\n-that now 127.0.0.1 is the Secondary and 127.0.0.2 is the Primary.\n-\n-Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2),\n-then on the old Secondary:\n-{\"execute\": \"drive-mirror\", \"arguments\":{ \"device\": \"colo-disk0\", \"job-id\": \"resync\", \"target\": \"nbd://127.0.0.1:9999/parent0\", \"mode\": \"existing\", \"format\": \"raw\", \"sync\": \"full\"} }\n-\n-Wait until disk is synced, then:\n-{\"execute\": \"stop\"}\n-{\"execute\": \"block-job-cancel\", \"arguments\":{ \"device\": \"resync\" } }\n-\n-{\"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\"}}\n-{\"execute\": \"x-blockdev-change\", \"arguments\":{ \"parent\": \"colo-disk0\", \"node\": \"replication0\" } }\n-\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-mirror\", \"id\": \"m0\", \"insert\": \"before\", \"position\": \"id=rew0\", \"netdev\": \"hn0\", \"queue\": \"tx\", \"outdev\": \"mirror0\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire0\", \"insert\": \"before\", \"position\": \"id=rew0\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"indev\": \"compare_out\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire1\", \"insert\": \"before\", \"position\": \"id=rew0\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"outdev\": \"compare0\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"iothread\", \"id\": \"iothread1\" } }\n-{\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"colo-compare\", \"id\": \"comp0\", \"primary_in\": \"compare0-0\", \"secondary_in\": \"compare1\", \"outdev\": \"compare_out0\", \"iothread\": \"iothread1\" } }\n-\n-{\"execute\": \"migrate-set-capabilities\", \"arguments\":{ \"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n-{\"execute\": \"migrate\", \"arguments\":{ \"uri\": \"tcp:127.0.0.1:9998\" } }\n-\n-== TODO ==\n-1. Support shared storage.\n-2. Develop the heartbeat part.\n-3. Reduce checkpoint VM’s downtime while doing checkpoint.\ndiff --git a/docs/system/index.rst b/docs/system/index.rst\nindex 427b020483104f6589878bbf255a367ae114c61b..6268c41aea9c74dc3e59d896b5ae082360bfbb1a 100644\n--- a/docs/system/index.rst\n+++ b/docs/system/index.rst\n@@ -41,3 +41,4 @@ or Hypervisor.Framework.\n    igvm\n    vm-templating\n    sriov\n+   qemu-colo\ndiff --git a/docs/system/qemu-colo.rst b/docs/system/qemu-colo.rst\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..4b5fbbf398f8a5c4ea6baad615bde94b2b4678d2\n--- /dev/null\n+++ b/docs/system/qemu-colo.rst\n@@ -0,0 +1,360 @@\n+Qemu COLO Fault Tolerance\n+=========================\n+\n+| Copyright (c) 2016 Intel Corporation\n+| Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.\n+| Copyright (c) 2016 Fujitsu, Corp.\n+\n+This work is licensed under the terms of the GNU GPL, version 2 or later.\n+See the COPYING file in the top-level directory.\n+\n+This document gives an overview of COLO's design and how to use it.\n+\n+Background\n+----------\n+Virtual machine (VM) replication is a well known technique for providing\n+application-agnostic software-implemented hardware fault tolerance,\n+also known as \"non-stop service\".\n+\n+COLO (COarse-grained LOck-stepping) is a high availability solution.\n+Both primary VM (PVM) and secondary VM (SVM) run in parallel. They receive the\n+same request from client, and generate response in parallel too.\n+If the response packets from PVM and SVM are identical, they are released\n+immediately. Otherwise, a VM checkpoint (on demand) is conducted.\n+\n+Architecture\n+------------\n+The architecture of COLO is shown in the diagram below.\n+It consists of a pair of networked physical nodes:\n+The primary node running the PVM, and the secondary node running the SVM\n+to maintain a valid replica of the PVM.\n+PVM and SVM execute in parallel and generate output of response packets for\n+client requests according to the application semantics.\n+\n+The incoming packets from the client or external network are received by the\n+primary node, and then forwarded to the secondary node, so that both the PVM\n+and the SVM are stimulated with the same requests.\n+\n+COLO receives the outbound packets from both the PVM and SVM and compares them\n+before allowing the output to be sent to clients.\n+\n+The SVM is qualified as a valid replica of the PVM, as long as it generates\n+identical responses to all client requests. Once the differences in the outputs\n+are detected between the PVM and SVM, COLO withholds transmission of the\n+outbound packets until it has successfully synchronized the PVM state to the SVM.\n+\n+Overview::\n+\n+      Primary Node                                                            Secondary Node\n+    +------------+  +-----------------------+       +------------------------+  +------------+\n+    |            |  |       HeartBeat       +<----->+       HeartBeat        |  |            |\n+    | Primary VM |  +-----------+-----------+       +-----------+------------+  |Secondary VM|\n+    |            |              |                               |               |            |\n+    |            |  +-----------|-----------+       +-----------|------------+  |            |\n+    |            |  |QEMU   +---v----+      |       |QEMU  +----v---+        |  |            |\n+    |            |  |       |Failover|      |       |      |Failover|        |  |            |\n+    |            |  |       +--------+      |       |      +--------+        |  |            |\n+    |            |  |   +---------------+   |       |   +---------------+    |  |            |\n+    |            |  |   | VM Checkpoint +-------------->+ VM Checkpoint |    |  |            |\n+    |            |  |   +---------------+   |       |   +---------------+    |  |            |\n+    |Requests<--------------------------\\ /-----------------\\ /--------------------->Requests|\n+    |            |  |                   ^ ^ |       |       | |              |  |            |\n+    |Responses+---------------------\\ /-|-|------------\\ /-------------------------+Responses|\n+    |            |  |               | | | | |       |  | |  | |              |  |            |\n+    |            |  | +-----------+ | | | | |       |  | |  | | +----------+ |  |            |\n+    |            |  | | COLO disk | | | | | |       |  | |  | | | COLO disk| |  |            |\n+    |            |  | |   Manager +---------------------------->| Manager  | |  |            |\n+    |            |  | ++----------+ v v | | |       |  | v  v | +---------++ |  |            |\n+    |            |  |  |+-----------+-+-+-++|       | ++-+--+-+---------+ |  |  |            |\n+    |            |  |  ||   COLO Proxy     ||       | |   COLO Proxy    | |  |  |            |\n+    |            |  |  || (compare packet  ||       | |(adjust sequence | |  |  |            |\n+    |            |  |  ||and mirror packet)||       | |    and ACK)     | |  |  |            |\n+    |            |  |  |+------------+---+-+|       | +-----------------+ |  |  |            |\n+    +------------+  +-----------------------+       +------------------------+  +------------+\n+    +------------+     |             |   |                                |     +------------+\n+    | VM Monitor |     |             |   |                                |     | VM Monitor |\n+    +------------+     |             |   |                                |     +------------+\n+    +---------------------------------------+       +----------------------------------------+\n+    |   Kernel         |             |   |  |       |   Kernel            |                  |\n+    +---------------------------------------+       +----------------------------------------+\n+                       |             |   |                                |\n+        +--------------v+  +---------v---+--+       +------------------+ +v-------------+\n+        |   Storage     |  |External Network|       | External Network | |   Storage    |\n+        +---------------+  +----------------+       +------------------+ +--------------+\n+\n+Components introduction\n+^^^^^^^^^^^^^^^^^^^^^^^\n+You can see there are several components in COLO's diagram of architecture.\n+Their functions are described below.\n+\n+HeartBeat\n+~~~~~~~~~\n+Runs on both the primary and secondary nodes, to periodically check platform\n+availability. When the primary node suffers a hardware fail-stop failure,\n+the heartbeat stops responding, the secondary node will trigger a failover\n+as soon as it determines the absence.\n+\n+COLO disk Manager\n+~~~~~~~~~~~~~~~~~\n+When primary VM writes data into image, the colo disk manager captures this data\n+and sends it to secondary VM's which makes sure the context of secondary VM's\n+image is consistent with the context of primary VM 's image.\n+For more details, please refer to docs/block-replication.txt.\n+\n+Checkpoint/Failover Controller\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+Modifications of save/restore flow to realize continuous migration,\n+to make sure the state of VM in Secondary side is always consistent with VM in\n+Primary side.\n+\n+COLO Proxy\n+~~~~~~~~~~\n+Delivers packets to Primary and Secondary, and then compare the responses from\n+both side. Then decide whether to start a checkpoint according to some rules.\n+Please refer to docs/colo-proxy.txt for more information.\n+\n+Note:\n+HeartBeat has not been implemented yet, so you need to trigger failover process\n+by using 'x-colo-lost-heartbeat' command.\n+\n+COLO operation status\n+^^^^^^^^^^^^^^^^^^^^^\n+\n+Overview::\n+\n+    +-----------------+\n+    |                 |\n+    |    Start COLO   |\n+    |                 |\n+    +--------+--------+\n+             |\n+             |  Main qmp command:\n+             |  migrate-set-capabilities with x-colo\n+             |  migrate\n+             |\n+             v\n+    +--------+--------+\n+    |                 |\n+    |  COLO running   |\n+    |                 |\n+    +--------+--------+\n+             |\n+             |  Main qmp command:\n+             |  x-colo-lost-heartbeat\n+             |  or\n+             |  some error happened\n+             v\n+    +--------+--------+\n+    |                 |  send qmp event:\n+    |  COLO failover  |  COLO_EXIT\n+    |                 |\n+    +-----------------+\n+\n+\n+COLO use the qmp command to switch and report operation status.\n+The diagram just shows the main qmp command, you can get the detail\n+in test procedure.\n+\n+Test procedure\n+--------------\n+Note: Here we are running both instances on the same host for testing,\n+change the IP Addresses if you want to run it on two hosts. Initially\n+``127.0.0.1`` is the Primary Host and ``127.0.0.2`` is the Secondary Host.\n+\n+Startup qemu\n+^^^^^^^^^^^^\n+**1. Primary**:\n+Note: Initially, ``$imagefolder/primary.qcow2`` needs to be copied to all hosts.\n+You don't need to change any IP's here, because ``0.0.0.0`` listens on any\n+interface. The chardev's with ``127.0.0.1`` IP's loopback to the local qemu\n+instance::\n+\n+    # imagefolder=\"/mnt/vms/colo-test-primary\"\n+\n+    # qemu-system-x86_64 -enable-kvm -cpu qemu64,kvmclock=on -m 512 -smp 1 -qmp stdio \\\n+       -device piix3-usb-uhci -device usb-tablet -name primary \\\n+       -netdev tap,id=hn0,vhost=off,helper=/usr/lib/qemu/qemu-bridge-helper \\\n+       -device rtl8139,id=e0,netdev=hn0 \\\n+       -chardev socket,id=mirror0,host=0.0.0.0,port=9003,server=on,wait=off \\\n+       -chardev socket,id=compare1,host=0.0.0.0,port=9004,server=on,wait=on \\\n+       -chardev socket,id=compare0,host=127.0.0.1,port=9001,server=on,wait=off \\\n+       -chardev socket,id=compare0-0,host=127.0.0.1,port=9001 \\\n+       -chardev socket,id=compare_out,host=127.0.0.1,port=9005,server=on,wait=off \\\n+       -chardev socket,id=compare_out0,host=127.0.0.1,port=9005 \\\n+       -object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0 \\\n+       -object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out \\\n+       -object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0 \\\n+       -object iothread,id=iothread1 \\\n+       -object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,\\\n+    outdev=compare_out0,iothread=iothread1 \\\n+       -drive if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\\\n+    children.0.file.filename=$imagefolder/primary.qcow2,children.0.driver=qcow2 -S\n+\n+\n+**2. Secondary**:\n+Note: Active and hidden images need to be created only once and the\n+size should be the same as ``primary.qcow2``. Again, you don't need to change\n+any IP's here, except for the ``$primary_ip`` variable::\n+\n+    # imagefolder=\"/mnt/vms/colo-test-secondary\"\n+    # primary_ip=127.0.0.1\n+\n+    # qemu-img create -f qcow2 $imagefolder/secondary-active.qcow2 10G\n+\n+    # qemu-img create -f qcow2 $imagefolder/secondary-hidden.qcow2 10G\n+\n+    # qemu-system-x86_64 -enable-kvm -cpu qemu64,kvmclock=on -m 512 -smp 1 -qmp stdio \\\n+       -device piix3-usb-uhci -device usb-tablet -name secondary \\\n+       -netdev tap,id=hn0,vhost=off,helper=/usr/lib/qemu/qemu-bridge-helper \\\n+       -device rtl8139,id=e0,netdev=hn0 \\\n+       -chardev socket,id=red0,host=$primary_ip,port=9003,reconnect-ms=1000 \\\n+       -chardev socket,id=red1,host=$primary_ip,port=9004,reconnect-ms=1000 \\\n+       -object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0 \\\n+       -object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1 \\\n+       -object filter-rewriter,id=rew0,netdev=hn0,queue=all \\\n+       -drive if=none,id=parent0,file.filename=$imagefolder/primary.qcow2,driver=qcow2 \\\n+       -drive if=none,id=childs0,driver=replication,mode=secondary,file.driver=qcow2,\\\n+    top-id=colo-disk0,file.file.filename=$imagefolder/secondary-active.qcow2,\\\n+    file.backing.driver=qcow2,file.backing.file.filename=$imagefolder/secondary-hidden.qcow2,\\\n+    file.backing.backing=parent0 \\\n+       -drive if=ide,id=colo-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\\\n+    children.0=childs0 \\\n+       -incoming tcp:0.0.0.0:9998\n+\n+\n+**3.** On Secondary VM's QEMU monitor, issue command::\n+\n+    {\"execute\":\"qmp_capabilities\"}\n+    {\"execute\": \"migrate-set-capabilities\", \"arguments\": {\"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n+    {\"execute\": \"nbd-server-start\", \"arguments\": {\"addr\": {\"type\": \"inet\", \"data\": {\"host\": \"0.0.0.0\", \"port\": \"9999\"} } } }\n+    {\"execute\": \"nbd-server-add\", \"arguments\": {\"device\": \"parent0\", \"writable\": true } }\n+\n+Note:\n+  a. The qmp command ``nbd-server-start`` and ``nbd-server-add`` must be run\n+     before running the qmp command migrate on primary QEMU\n+  b. Active disk, hidden disk and nbd target's length should be the\n+     same.\n+  c. It is better to put active disk and hidden disk in ramdisk. They\n+     will be merged into the parent disk on failover.\n+\n+**4.** On Primary VM's QEMU monitor, issue command::\n+\n+    {\"execute\":\"qmp_capabilities\"}\n+    {\"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\"}}\n+    {\"execute\": \"x-blockdev-change\", \"arguments\":{\"parent\": \"colo-disk0\", \"node\": \"replication0\" } }\n+    {\"execute\": \"migrate-set-capabilities\", \"arguments\": {\"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n+    {\"execute\": \"migrate\", \"arguments\": {\"uri\": \"tcp:127.0.0.2:9998\" } }\n+\n+Note:\n+  a. There should be only one NBD Client for each primary disk.\n+  b. The qmp command line must be run after running qmp command line in\n+     secondary qemu.\n+\n+**5.** After the above steps, you will see, whenever you make changes to PVM, SVM will be synced.\n+You can issue command ``{ \"execute\": \"migrate-set-parameters\" , \"arguments\":{ \"x-checkpoint-delay\": 2000 } }``\n+to change the idle checkpoint period time\n+\n+Failover test\n+^^^^^^^^^^^^^\n+You can kill one of the VMs and Failover on the surviving VM:\n+\n+If you killed the Secondary, then follow \"Primary Failover\".\n+After that, if you want to resume the replication, follow \"Primary resume replication\"\n+\n+If you killed the Primary, then follow \"Secondary Failover\".\n+After that, if you want to resume the replication, follow \"Secondary resume replication\"\n+\n+Primary Failover\n+~~~~~~~~~~~~~~~~\n+The Secondary died, resume on the Primary::\n+\n+    {\"execute\": \"x-blockdev-change\", \"arguments\":{ \"parent\": \"colo-disk0\", \"child\": \"children.1\"} }\n+    {\"execute\": \"human-monitor-command\", \"arguments\":{ \"command-line\": \"drive_del replication0\" } }\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"comp0\" } }\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"iothread1\" } }\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"m0\" } }\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"redire0\" } }\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"redire1\" } }\n+    {\"execute\": \"x-colo-lost-heartbeat\" }\n+\n+Secondary Failover\n+~~~~~~~~~~~~~~~~~~\n+The Primary died, resume on the Secondary and prepare to become the new Primary::\n+\n+    {\"execute\": \"nbd-server-stop\"}\n+    {\"execute\": \"x-colo-lost-heartbeat\"}\n+\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"f2\" } }\n+    {\"execute\": \"object-del\", \"arguments\":{ \"id\": \"f1\" } }\n+    {\"execute\": \"chardev-remove\", \"arguments\":{ \"id\": \"red1\" } }\n+    {\"execute\": \"chardev-remove\", \"arguments\":{ \"id\": \"red0\" } }\n+\n+    {\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"mirror0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"0.0.0.0\", \"port\": \"9003\" } }, \"server\": true } } } }\n+    {\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare1\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"0.0.0.0\", \"port\": \"9004\" } }, \"server\": true } } } }\n+    {\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9001\" } }, \"server\": true } } } }\n+    {\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare0-0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9001\" } }, \"server\": false } } } }\n+    {\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare_out\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9005\" } }, \"server\": true } } } }\n+    {\"execute\": \"chardev-add\", \"arguments\":{ \"id\": \"compare_out0\", \"backend\": {\"type\": \"socket\", \"data\": {\"addr\": { \"type\": \"inet\", \"data\": { \"host\": \"127.0.0.1\", \"port\": \"9005\" } }, \"server\": false } } } }\n+\n+Primary resume replication\n+~~~~~~~~~~~~~~~~~~~~~~~~~~\n+Resume replication after new Secondary is up.\n+\n+Start the new Secondary (Steps 2 and 3 above), then on the Primary::\n+\n+    {\"execute\": \"drive-mirror\", \"arguments\":{ \"device\": \"colo-disk0\", \"job-id\": \"resync\", \"target\": \"nbd://127.0.0.2:9999/parent0\", \"mode\": \"existing\", \"format\": \"raw\", \"sync\": \"full\"} }\n+\n+Wait until disk is synced, then::\n+\n+    {\"execute\": \"stop\"}\n+    {\"execute\": \"block-job-cancel\", \"arguments\":{ \"device\": \"resync\"} }\n+\n+    {\"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\"}}\n+    {\"execute\": \"x-blockdev-change\", \"arguments\":{ \"parent\": \"colo-disk0\", \"node\": \"replication0\" } }\n+\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-mirror\", \"id\": \"m0\", \"netdev\": \"hn0\", \"queue\": \"tx\", \"outdev\": \"mirror0\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire0\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"indev\": \"compare_out\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire1\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"outdev\": \"compare0\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"iothread\", \"id\": \"iothread1\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"colo-compare\", \"id\": \"comp0\", \"primary_in\": \"compare0-0\", \"secondary_in\": \"compare1\", \"outdev\": \"compare_out0\", \"iothread\": \"iothread1\" } }\n+\n+    {\"execute\": \"migrate-set-capabilities\", \"arguments\":{ \"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n+    {\"execute\": \"migrate\", \"arguments\":{ \"uri\": \"tcp:127.0.0.2:9998\" } }\n+\n+Note:\n+If this Primary previously was a Secondary, then we need to insert the\n+filters before the filter-rewriter by using the\n+\"\"insert\": \"before\", \"position\": \"id=rew0\"\" Options. See below.\n+\n+Secondary resume replication\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+Become Primary and resume replication after new Secondary is up. Note\n+that now 127.0.0.1 is the Secondary and 127.0.0.2 is the Primary.\n+\n+Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2),\n+then on the old Secondary::\n+\n+    {\"execute\": \"drive-mirror\", \"arguments\":{ \"device\": \"colo-disk0\", \"job-id\": \"resync\", \"target\": \"nbd://127.0.0.1:9999/parent0\", \"mode\": \"existing\", \"format\": \"raw\", \"sync\": \"full\"} }\n+\n+Wait until disk is synced, then::\n+\n+    {\"execute\": \"stop\"}\n+    {\"execute\": \"block-job-cancel\", \"arguments\":{ \"device\": \"resync\" } }\n+\n+    {\"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\"}}\n+    {\"execute\": \"x-blockdev-change\", \"arguments\":{ \"parent\": \"colo-disk0\", \"node\": \"replication0\" } }\n+\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-mirror\", \"id\": \"m0\", \"insert\": \"before\", \"position\": \"id=rew0\", \"netdev\": \"hn0\", \"queue\": \"tx\", \"outdev\": \"mirror0\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire0\", \"insert\": \"before\", \"position\": \"id=rew0\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"indev\": \"compare_out\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"filter-redirector\", \"id\": \"redire1\", \"insert\": \"before\", \"position\": \"id=rew0\", \"netdev\": \"hn0\", \"queue\": \"rx\", \"outdev\": \"compare0\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"iothread\", \"id\": \"iothread1\" } }\n+    {\"execute\": \"object-add\", \"arguments\":{ \"qom-type\": \"colo-compare\", \"id\": \"comp0\", \"primary_in\": \"compare0-0\", \"secondary_in\": \"compare1\", \"outdev\": \"compare_out0\", \"iothread\": \"iothread1\" } }\n+\n+    {\"execute\": \"migrate-set-capabilities\", \"arguments\":{ \"capabilities\": [ {\"capability\": \"x-colo\", \"state\": true } ] } }\n+    {\"execute\": \"migrate\", \"arguments\":{ \"uri\": \"tcp:127.0.0.1:9998\" } }\n+\n+TODO\n+----\n+1. Support shared storage.\n+2. Develop the heartbeat part.\n+3. Reduce checkpoint VM’s downtime while doing checkpoint.\n",
    "prefixes": [
        "v7",
        "15/18"
    ]
}