All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case
@ 2017-04-12 14:05 zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 1/6] docs/block-replication: Add description for shared-disk case zhanghailiang
                   ` (7 more replies)
  0 siblings, 8 replies; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang,
	Dr . David Alan Gilbert, eddie.dong

COLO block replication doesn't support the shared disk case,
Here we try to implement it and this is the 4th version.

Please review and any commits are welcomed.

Cc: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
Cc: eddie.dong@intel.com

v4:
- Add proper comment for primary_disk in patch 2 (Stefan)
- Call bdrv_invalidate_cache() while do checkpoint for shared disk in patch 5

v3:
- Fix some comments from Stefan and Eric

v2:
- Drop the patch which add a blk_root() helper
- Fix some comments from Changlong

zhanghailiang (6):
  docs/block-replication: Add description for shared-disk case
  replication: add shared-disk and shared-disk-id options
  replication: Split out backup_do_checkpoint() from
    secondary_do_checkpoint()
  replication: fix code logic with the new shared_disk option
  replication: Implement block replication for shared disk case
  nbd/replication: implement .bdrv_get_info() for nbd and replication
    driver

 block/nbd.c                |  12 +++
 block/replication.c        | 198 ++++++++++++++++++++++++++++++++++-----------
 docs/block-replication.txt | 139 ++++++++++++++++++++++++++++++-
 qapi/block-core.json       |  10 ++-
 4 files changed, 306 insertions(+), 53 deletions(-)

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH v4 1/6] docs/block-replication: Add description for shared-disk case
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
@ 2017-04-12 14:05 ` zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options zhanghailiang
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang,
	Wen Congyang

Introuduce the scenario of shared-disk block replication
and how to use it.

Reviewed-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
---
 docs/block-replication.txt | 139 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 135 insertions(+), 4 deletions(-)

diff --git a/docs/block-replication.txt b/docs/block-replication.txt
index 6bde673..fbfe005 100644
--- a/docs/block-replication.txt
+++ b/docs/block-replication.txt
@@ -24,7 +24,7 @@ only dropped at next checkpoint time. To reduce the network transportation
 effort during a vmstate checkpoint, the disk modification operations of
 the Primary disk are asynchronously forwarded to the Secondary node.
 
-== Workflow ==
+== Non-shared disk workflow ==
 The following is the image of block replication workflow:
 
         +----------------------+            +------------------------+
@@ -57,7 +57,7 @@ The following is the image of block replication workflow:
     4) Secondary write requests will be buffered in the Disk buffer and it
        will overwrite the existing sector content in the buffer.
 
-== Architecture ==
+== Non-shared disk architecture ==
 We are going to implement block replication from many basic
 blocks that are already in QEMU.
 
@@ -106,6 +106,74 @@ 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.
 
+== Shared Disk Mode Workflow ==
+The following is the image of block replication workflow:
+
+        +----------------------+            +------------------------+
+        |Primary Write Requests|            |Secondary Write Requests|
+        +----------------------+            +------------------------+
+                  |                                       |
+                  |                                      (4)
+                  |                                       V
+                  |                              /-------------\
+                  | (2)Forward and write through |             |
+                  | +--------------------------> | Disk Buffer |
+                  | |                            |             |
+                  | |                            \-------------/
+                  | |(1)read                           |
+                  | |                                  |
+       (3)write   | |                                  | backing file
+                  V |                                  |
+                 +-----------------------------+       |
+                 | Shared Disk                 | <-----+
+                 +-----------------------------+
+
+    1) Primary writes will read original data and forward it to Secondary
+       QEMU.
+    2) Before Primary write requests are written to Shared disk, the
+       original sector content will be read from Shared disk and
+       forwarded and buffered in the Disk buffer on the secondary site,
+       but it will not overwrite the existing sector content (it could be
+       from either "Secondary Write Requests" or previous COW of "Primary
+       Write Requests") in the Disk buffer.
+    3) Primary write requests will be written to Shared disk.
+    4) Secondary write requests will be buffered in the Disk buffer and it
+       will overwrite the existing sector content in the buffer.
+
+== Shared Disk Mode Architecture ==
+We are going to implement block replication from many basic
+blocks that are already in QEMU.
+         virtio-blk                     ||                               .----------
+             /                          ||                               | Secondary
+            /                           ||                               '----------
+           /                            ||                                 virtio-blk
+          /                             ||                                      |
+          |                             ||                               replication(5)
+          |                    NBD  -------->   NBD   (2)                       |
+          |                  client     ||    server ---> hidden disk <-- active disk(4)
+          |                     ^       ||                      |
+          |              replication(1) ||                      |
+          |                     |       ||                      |
+          |   +-----------------'       ||                      |
+         (3)  |drive-backup sync=none   ||                      |
+--------. |   +-----------------+       ||                      |
+Primary | |                     |       ||           backing    |
+--------' |                     |       ||                      |
+          V                     |                               |
+       +-------------------------------------------+            |
+       |               shared disk                 | <----------+
+       +-------------------------------------------+
+
+
+    1) Primary writes will read original data and forward it to Secondary
+       QEMU.
+    2) The hidden-disk buffers the original content that is modified by the
+       primary VM. It should also be an empty disk, and the driver supports
+       bdrv_make_empty() and backing file.
+    3) Primary write requests will be written to Shared disk.
+    4) Secondary write requests will be buffered in the active disk and it
+       will overwrite the existing sector content in the buffer.
+
 == Failure Handling ==
 There are 7 internal errors when block replication is running:
 1. I/O error on primary disk
@@ -145,7 +213,7 @@ d. replication_stop_all()
    things except failover. The caller must hold the I/O mutex lock if it is
    in migration/checkpoint thread.
 
-== Usage ==
+== Non-shared disk usage ==
 Primary:
   -drive if=xxx,driver=quorum,read-pattern=fifo,id=colo1,vote-threshold=1,\
          children.0.file.filename=1.raw,\
@@ -234,6 +302,69 @@ Secondary:
   The primary host is down, so we should do the following thing:
   { 'execute': 'nbd-server-stop' }
 
+== Shared disk usage ==
+Primary:
+ -drive if=virtio,id=primary_disk0,file.filename=1.raw,driver=raw
+
+Issue qmp command:
+  { 'execute': 'blockdev-add',
+    'arguments': {
+        'driver': 'replication',
+        'node-name': 'rep',
+        'mode': 'primary',
+        'shared-disk-id': 'primary_disk0',
+        'shared-disk': true,
+        'file': {
+            'driver': 'nbd',
+            'export': 'hidden_disk0',
+            'server': {
+                'type': 'inet',
+                'data': {
+                    'host': 'xxx.xxx.xxx.xxx',
+                    'port': 'yyy'
+                }
+            }
+        }
+     }
+  }
+
+Secondary:
+ -drive if=none,driver=qcow2,file.filename=/mnt/ramfs/hidden_disk.img,id=hidden_disk0,\
+        backing.driver=raw,backing.file.filename=1.raw \
+ -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=hidden_disk0,shared-disk=on
+
+Issue qmp command:
+1. { 'execute': 'nbd-server-start',
+     'arguments': {
+        'addr': {
+            'type': 'inet',
+            'data': {
+                'host': '0',
+                'port': 'yyy'
+            }
+        }
+     }
+   }
+2. { 'execute': 'nbd-server-add',
+     'arguments': {
+        'device': 'hidden_disk0',
+        'writable': true
+    }
+  }
+
+After Failover:
+Primary:
+  { 'execute': 'x-blockdev-del',
+    'arguments': {
+        'node-name': 'rep'
+    }
+  }
+
+Secondary:
+  {'execute': 'nbd-server-stop' }
+
 TODO:
 1. Continuous block replication
-2. Shared disk
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 1/6] docs/block-replication: Add description for shared-disk case zhanghailiang
@ 2017-04-12 14:05 ` zhanghailiang
  2017-04-12 14:28   ` Eric Blake
                     ` (2 more replies)
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 3/6] replication: Split out backup_do_checkpoint() from secondary_do_checkpoint() zhanghailiang
                   ` (5 subsequent siblings)
  7 siblings, 3 replies; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang,
	Wen Congyang

We use these two options to identify which disk is
shared

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
---
v4:
- Add proper comment for primary_disk (Stefan)
v2:
- Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
- Fix comments for these two options
---
 block/replication.c  | 43 +++++++++++++++++++++++++++++++++++++++++--
 qapi/block-core.json | 10 +++++++++-
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/block/replication.c b/block/replication.c
index bf3c395..418b81b 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -25,9 +25,12 @@
 typedef struct BDRVReplicationState {
     ReplicationMode mode;
     int replication_state;
+    bool is_shared_disk;
+    char *shared_disk_id;
     BdrvChild *active_disk;
     BdrvChild *hidden_disk;
     BdrvChild *secondary_disk;
+    BdrvChild *primary_disk;
     char *top_id;
     ReplicationState *rs;
     Error *blocker;
@@ -53,6 +56,9 @@ static void replication_stop(ReplicationState *rs, bool failover,
 
 #define REPLICATION_MODE        "mode"
 #define REPLICATION_TOP_ID      "top-id"
+#define REPLICATION_SHARED_DISK "shared-disk"
+#define REPLICATION_SHARED_DISK_ID "shared-disk-id"
+
 static QemuOptsList replication_runtime_opts = {
     .name = "replication",
     .head = QTAILQ_HEAD_INITIALIZER(replication_runtime_opts.head),
@@ -65,6 +71,14 @@ static QemuOptsList replication_runtime_opts = {
             .name = REPLICATION_TOP_ID,
             .type = QEMU_OPT_STRING,
         },
+        {
+            .name = REPLICATION_SHARED_DISK_ID,
+            .type = QEMU_OPT_STRING,
+        },
+        {
+            .name = REPLICATION_SHARED_DISK,
+            .type = QEMU_OPT_BOOL,
+        },
         { /* end of list */ }
     },
 };
@@ -85,6 +99,9 @@ static int replication_open(BlockDriverState *bs, QDict *options,
     QemuOpts *opts = NULL;
     const char *mode;
     const char *top_id;
+    const char *shared_disk_id;
+    BlockBackend *blk;
+    BlockDriverState *tmp_bs;
 
     bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
                                false, errp);
@@ -125,12 +142,33 @@ static int replication_open(BlockDriverState *bs, QDict *options,
                    "The option mode's value should be primary or secondary");
         goto fail;
     }
+    s->is_shared_disk = qemu_opt_get_bool(opts, REPLICATION_SHARED_DISK,
+                                          false);
+    if (s->is_shared_disk && (s->mode == REPLICATION_MODE_PRIMARY)) {
+        shared_disk_id = qemu_opt_get(opts, REPLICATION_SHARED_DISK_ID);
+        if (!shared_disk_id) {
+            error_setg(&local_err, "Missing shared disk blk option");
+            goto fail;
+        }
+        s->shared_disk_id = g_strdup(shared_disk_id);
+        blk = blk_by_name(s->shared_disk_id);
+        if (!blk) {
+            error_setg(&local_err, "There is no %s block", s->shared_disk_id);
+            goto fail;
+        }
+        /* We have a BlockBackend for the primary disk but use BdrvChild for
+         * consistency - active_disk, secondary_disk, etc are also BdrvChild.
+         */
+        tmp_bs = blk_bs(blk);
+        s->primary_disk = QLIST_FIRST(&tmp_bs->parents);
+    }
 
     s->rs = replication_new(bs, &replication_ops);
 
-    ret = 0;
-
+    qemu_opts_del(opts);
+    return 0;
 fail:
+    g_free(s->shared_disk_id);
     qemu_opts_del(opts);
     error_propagate(errp, local_err);
 
@@ -141,6 +179,7 @@ static void replication_close(BlockDriverState *bs)
 {
     BDRVReplicationState *s = bs->opaque;
 
+    g_free(s->shared_disk_id);
     if (s->replication_state == BLOCK_REPLICATION_RUNNING) {
         replication_stop(s->rs, false, NULL);
     }
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 033457c..361c932 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2661,12 +2661,20 @@
 #          node who owns the replication node chain. Must not be given in
 #          primary mode.
 #
+# @shared-disk-id: Id of shared disk while is replication mode, if @shared-disk
+#                  is true, this option is required (Since: 2.10)
+#
+# @shared-disk: To indicate whether or not a disk is shared by primary VM
+#               and secondary VM. (The default is false) (Since: 2.10)
+#
 # Since: 2.9
 ##
 { 'struct': 'BlockdevOptionsReplication',
   'base': 'BlockdevOptionsGenericFormat',
   'data': { 'mode': 'ReplicationMode',
-            '*top-id': 'str' } }
+            '*top-id': 'str',
+            '*shared-disk-id': 'str',
+            '*shared-disk': 'bool' } }
 
 ##
 # @NFSTransport:
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH v4 3/6] replication: Split out backup_do_checkpoint() from secondary_do_checkpoint()
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 1/6] docs/block-replication: Add description for shared-disk case zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options zhanghailiang
@ 2017-04-12 14:05 ` zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 4/6] replication: fix code logic with the new shared_disk option zhanghailiang
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang

The helper backup_do_checkpoint() will be used for primary related
codes. Here we split it out from secondary_do_checkpoint().

Besides, it is unnecessary to call backup_do_checkpoint() in
replication starting and normally stop replication path.
We only need call it while do real checkpointing.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 block/replication.c | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)

diff --git a/block/replication.c b/block/replication.c
index 418b81b..b021215 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -352,20 +352,8 @@ static bool replication_recurse_is_first_non_filter(BlockDriverState *bs,
 
 static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp)
 {
-    Error *local_err = NULL;
     int ret;
 
-    if (!s->secondary_disk->bs->job) {
-        error_setg(errp, "Backup job was cancelled unexpectedly");
-        return;
-    }
-
-    backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
-    if (local_err) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
     ret = s->active_disk->bs->drv->bdrv_make_empty(s->active_disk->bs);
     if (ret < 0) {
         error_setg(errp, "Cannot make active disk empty");
@@ -578,6 +566,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
             return;
         }
         block_job_start(job);
+
+        secondary_do_checkpoint(s, errp);
         break;
     default:
         aio_context_release(aio_context);
@@ -586,10 +576,6 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
 
     s->replication_state = BLOCK_REPLICATION_RUNNING;
 
-    if (s->mode == REPLICATION_MODE_SECONDARY) {
-        secondary_do_checkpoint(s, errp);
-    }
-
     s->error = 0;
     aio_context_release(aio_context);
 }
@@ -599,13 +585,29 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
     BlockDriverState *bs = rs->opaque;
     BDRVReplicationState *s;
     AioContext *aio_context;
+    Error *local_err = NULL;
 
     aio_context = bdrv_get_aio_context(bs);
     aio_context_acquire(aio_context);
     s = bs->opaque;
 
-    if (s->mode == REPLICATION_MODE_SECONDARY) {
+    switch (s->mode) {
+    case REPLICATION_MODE_PRIMARY:
+        break;
+    case REPLICATION_MODE_SECONDARY:
+        if (!s->secondary_disk->bs->job) {
+            error_setg(errp, "Backup job was cancelled unexpectedly");
+            break;
+        }
+        backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            break;
+        }
         secondary_do_checkpoint(s, errp);
+        break;
+    default:
+        abort();
     }
     aio_context_release(aio_context);
 }
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH v4 4/6] replication: fix code logic with the new shared_disk option
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
                   ` (2 preceding siblings ...)
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 3/6] replication: Split out backup_do_checkpoint() from secondary_do_checkpoint() zhanghailiang
@ 2017-04-12 14:05 ` zhanghailiang
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case zhanghailiang
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang

Some code logic only be needed in non-shared disk, here
we adjust these codes to prepare for shared disk scenario.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
---
 block/replication.c | 73 ++++++++++++++++++++++++++++++-----------------------
 1 file changed, 41 insertions(+), 32 deletions(-)

diff --git a/block/replication.c b/block/replication.c
index b021215..3a35471 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -539,33 +539,40 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
             return;
         }
 
-        /* start backup job now */
-        error_setg(&s->blocker,
-                   "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)) {
-            error_setg(errp, "No top_bs or it is invalid");
-            reopen_backing_file(bs, false, NULL);
-            aio_context_release(aio_context);
-            return;
-        }
-        bdrv_op_block_all(top_bs, s->blocker);
-        bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
-
-        job = backup_job_create(NULL, s->secondary_disk->bs, s->hidden_disk->bs,
-                                0, MIRROR_SYNC_MODE_NONE, NULL, false,
+        /*
+         * Only in the case of non-shared disk,
+         * the backup job is in the secondary side
+         */
+        if (!s->is_shared_disk) {
+            /* start backup job now */
+            error_setg(&s->blocker,
+                    "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)) {
+                error_setg(errp, "No top_bs or it is invalid");
+                reopen_backing_file(bs, false, NULL);
+                aio_context_release(aio_context);
+                return;
+            }
+
+            bdrv_op_block_all(top_bs, s->blocker);
+            bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
+            job = backup_job_create(NULL, s->secondary_disk->bs,
+                                s->hidden_disk->bs, 0,
+                                MIRROR_SYNC_MODE_NONE, NULL, false,
                                 BLOCKDEV_ON_ERROR_REPORT,
                                 BLOCKDEV_ON_ERROR_REPORT, BLOCK_JOB_INTERNAL,
                                 backup_job_completed, bs, NULL, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            backup_job_cleanup(bs);
-            aio_context_release(aio_context);
-            return;
+            if (local_err) {
+                error_propagate(errp, local_err);
+                backup_job_cleanup(bs);
+                aio_context_release(aio_context);
+                return;
+            }
+            block_job_start(job);
         }
-        block_job_start(job);
 
         secondary_do_checkpoint(s, errp);
         break;
@@ -595,14 +602,16 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
     case REPLICATION_MODE_PRIMARY:
         break;
     case REPLICATION_MODE_SECONDARY:
-        if (!s->secondary_disk->bs->job) {
-            error_setg(errp, "Backup job was cancelled unexpectedly");
-            break;
-        }
-        backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
-        if (local_err) {
-            error_propagate(errp, local_err);
-            break;
+        if (!s->is_shared_disk) {
+            if (!s->secondary_disk->bs->job) {
+                error_setg(errp, "Backup job was cancelled unexpectedly");
+                break;
+            }
+            backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+                break;
+            }
         }
         secondary_do_checkpoint(s, errp);
         break;
@@ -683,7 +692,7 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
          * before the BDS is closed, because we will access hidden
          * disk, secondary disk in backup_job_completed().
          */
-        if (s->secondary_disk->bs->job) {
+        if (!s->is_shared_disk && s->secondary_disk->bs->job) {
             block_job_cancel_sync(s->secondary_disk->bs->job);
         }
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
                   ` (3 preceding siblings ...)
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 4/6] replication: fix code logic with the new shared_disk option zhanghailiang
@ 2017-04-12 14:05 ` zhanghailiang
  2017-05-11 19:15   ` Stefan Hajnoczi
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 6/6] nbd/replication: implement .bdrv_get_info() for nbd and replication driver zhanghailiang
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang,
	Wen Congyang

Just as the scenario of non-shared disk block replication,
we are going to implement block replication from many basic
blocks that are already in QEMU.
The architecture is:

         virtio-blk                     ||                               .----------
             /                          ||                               | Secondary
            /                           ||                               '----------
           /                            ||                                 virtio-blk
          /                             ||                                      |
          |                             ||                               replication(5)
          |                    NBD  -------->   NBD   (2)                       |
          |                  client     ||    server ---> hidden disk <-- active disk(4)
          |                     ^       ||                      |
          |              replication(1) ||                      |
          |                     |       ||                      |
          |   +-----------------'       ||                      |
         (3)  |drive-backup sync=none   ||                      |
--------. |   +-----------------+       ||                      |
Primary | |                     |       ||           backing    |
--------' |                     |       ||                      |
          V                     |                               |
       +-------------------------------------------+            |
       |               shared disk                 | <----------+
       +-------------------------------------------+

    1) Primary writes will read original data and forward it to Secondary
       QEMU.
    2) The hidden-disk is created automatically. It buffers the original content
       that is modified by the primary VM. It should also be an empty disk, and
       the driver supports bdrv_make_empty() and backing file.
    3) Primary write requests will be written to Shared disk.
    4) Secondary write requests will be buffered in the active disk and it
       will overwrite the existing sector content in the buffer.

Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
---
v4:
 - Call bdrv_invalidate_cache() while do checkpoint for shared disk
---
 block/replication.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 52 insertions(+), 6 deletions(-)

diff --git a/block/replication.c b/block/replication.c
index 3a35471..fb604e5 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -253,7 +253,7 @@ static coroutine_fn int replication_co_readv(BlockDriverState *bs,
                                              QEMUIOVector *qiov)
 {
     BDRVReplicationState *s = bs->opaque;
-    BdrvChild *child = s->secondary_disk;
+    BdrvChild *child = s->is_shared_disk ? s->primary_disk : s->secondary_disk;
     BlockJob *job = NULL;
     CowRequest req;
     int ret;
@@ -435,7 +435,12 @@ static void backup_job_completed(void *opaque, int ret)
         s->error = -EIO;
     }
 
-    backup_job_cleanup(bs);
+    if (s->mode == REPLICATION_MODE_PRIMARY) {
+        s->replication_state = BLOCK_REPLICATION_DONE;
+        s->error = 0;
+    } else {
+        backup_job_cleanup(bs);
+    }
 }
 
 static bool check_top_bs(BlockDriverState *top_bs, BlockDriverState *bs)
@@ -487,6 +492,19 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
 
     switch (s->mode) {
     case REPLICATION_MODE_PRIMARY:
+        if (s->is_shared_disk) {
+            job = backup_job_create(NULL, s->primary_disk->bs, bs, 0,
+                MIRROR_SYNC_MODE_NONE, NULL, false, BLOCKDEV_ON_ERROR_REPORT,
+                BLOCKDEV_ON_ERROR_REPORT, BLOCK_JOB_INTERNAL,
+                backup_job_completed, bs, NULL, &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+                backup_job_cleanup(bs);
+                aio_context_release(aio_context);
+                return;
+            }
+            block_job_start(job);
+        }
         break;
     case REPLICATION_MODE_SECONDARY:
         s->active_disk = bs->file;
@@ -505,7 +523,8 @@ static void replication_start(ReplicationState *rs, ReplicationMode mode,
         }
 
         s->secondary_disk = s->hidden_disk->bs->backing;
-        if (!s->secondary_disk->bs || !bdrv_has_blk(s->secondary_disk->bs)) {
+        if (!s->secondary_disk->bs ||
+            (!s->is_shared_disk && !bdrv_has_blk(s->secondary_disk->bs))) {
             error_setg(errp, "The secondary disk doesn't have block backend");
             aio_context_release(aio_context);
             return;
@@ -600,11 +619,24 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
 
     switch (s->mode) {
     case REPLICATION_MODE_PRIMARY:
+        if (s->is_shared_disk) {
+            if (!s->primary_disk->bs->job) {
+                error_setg(errp, "Primary backup job was cancelled"
+                           " unexpectedly");
+                break;
+            }
+
+            backup_do_checkpoint(s->primary_disk->bs->job, &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+            }
+        }
         break;
     case REPLICATION_MODE_SECONDARY:
         if (!s->is_shared_disk) {
             if (!s->secondary_disk->bs->job) {
-                error_setg(errp, "Backup job was cancelled unexpectedly");
+                error_setg(errp, "Secondary backup job was cancelled"
+                           " unexpectedly");
                 break;
             }
             backup_do_checkpoint(s->secondary_disk->bs->job, &local_err);
@@ -612,6 +644,16 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
                 error_propagate(errp, local_err);
                 break;
             }
+        } else {
+            /*
+             * For shared disk, we need to force SVM to re-read metadata
+             * that is loaded in memory, or there will be inconsistent.
+             */
+            bdrv_invalidate_cache(s->secondary_disk->bs, &local_err);
+            if (local_err) {
+                error_propagate(errp, local_err);
+                break;
+            }
         }
         secondary_do_checkpoint(s, errp);
         break;
@@ -683,8 +725,12 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
 
     switch (s->mode) {
     case REPLICATION_MODE_PRIMARY:
-        s->replication_state = BLOCK_REPLICATION_DONE;
-        s->error = 0;
+        if (s->is_shared_disk && s->primary_disk->bs->job) {
+            block_job_cancel(s->primary_disk->bs->job);
+        } else {
+            s->replication_state = BLOCK_REPLICATION_DONE;
+            s->error = 0;
+        }
         break;
     case REPLICATION_MODE_SECONDARY:
         /*
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [Qemu-devel] [PATCH v4 6/6] nbd/replication: implement .bdrv_get_info() for nbd and replication driver
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
                   ` (4 preceding siblings ...)
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case zhanghailiang
@ 2017-04-12 14:05 ` zhanghailiang
  2017-05-11 19:17 ` [Qemu-devel] [Qemu-block] [PATCH v4 0/6] COLO block replication supports shared disk case Stefan Hajnoczi
  2017-05-16 10:41 ` [Qemu-devel] " 吴志勇
  7 siblings, 0 replies; 18+ messages in thread
From: zhanghailiang @ 2017-04-12 14:05 UTC (permalink / raw)
  To: stefanha, qemu-devel
  Cc: qemu-block, kwolf, xiecl.fnst, zhangchen.fnst, zhanghailiang,
	Eric Blake, Wen Congyang

Without this callback, there will be an error reports in the primary side:
"qemu-system-x86_64: Couldn't determine the cluster size of the target image,
which has no backing file: Operation not supported
Aborting, since this may create an unusable destination image"

For nbd driver, it doesn't have cluster size, so here we return
a fake value for it.

This patch should be dropped if Eric's nbd patch be merged.
https://lists.gnu.org/archive/html/qemu-block/2017-02/msg00825.html
'[PATCH v4 7/8] nbd: Implement NBD_INFO_BLOCK_SIZE on server'.

Cc: Eric Blake <eblake@redhat.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
---
 block/nbd.c         | 12 ++++++++++++
 block/replication.c |  6 ++++++
 2 files changed, 18 insertions(+)

diff --git a/block/nbd.c b/block/nbd.c
index 814ab26d..fceb14b 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -43,6 +43,8 @@
 
 #define EN_OPTSTR ":exportname="
 
+#define NBD_FAKE_CLUSTER_SIZE 512
+
 typedef struct BDRVNBDState {
     NBDClientSession client;
 
@@ -561,6 +563,13 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
     bs->full_open_options = opts;
 }
 
+static int nbd_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+    bdi->cluster_size  = NBD_FAKE_CLUSTER_SIZE;
+
+    return 0;
+}
+
 static BlockDriver bdrv_nbd = {
     .format_name                = "nbd",
     .protocol_name              = "nbd",
@@ -578,6 +587,7 @@ static BlockDriver bdrv_nbd = {
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
     .bdrv_attach_aio_context    = nbd_attach_aio_context,
     .bdrv_refresh_filename      = nbd_refresh_filename,
+    .bdrv_get_info              = nbd_get_info,
 };
 
 static BlockDriver bdrv_nbd_tcp = {
@@ -597,6 +607,7 @@ static BlockDriver bdrv_nbd_tcp = {
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
     .bdrv_attach_aio_context    = nbd_attach_aio_context,
     .bdrv_refresh_filename      = nbd_refresh_filename,
+    .bdrv_get_info              = nbd_get_info,
 };
 
 static BlockDriver bdrv_nbd_unix = {
@@ -616,6 +627,7 @@ static BlockDriver bdrv_nbd_unix = {
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
     .bdrv_attach_aio_context    = nbd_attach_aio_context,
     .bdrv_refresh_filename      = nbd_refresh_filename,
+    .bdrv_get_info              = nbd_get_info,
 };
 
 static void bdrv_nbd_init(void)
diff --git a/block/replication.c b/block/replication.c
index fb604e5..7371caa 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -761,6 +761,11 @@ static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
     aio_context_release(aio_context);
 }
 
+static int replication_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+    return bdrv_get_info(bs->file->bs, bdi);
+}
+
 BlockDriver bdrv_replication = {
     .format_name                = "replication",
     .protocol_name              = "replication",
@@ -774,6 +779,7 @@ BlockDriver bdrv_replication = {
     .bdrv_co_readv              = replication_co_readv,
     .bdrv_co_writev             = replication_co_writev,
 
+    .bdrv_get_info              = replication_get_info,
     .is_filter                  = true,
     .bdrv_recurse_is_first_non_filter = replication_recurse_is_first_non_filter,
 
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options zhanghailiang
@ 2017-04-12 14:28   ` Eric Blake
  2017-04-17  6:31     ` Hailiang Zhang
  2017-04-18  5:59   ` Xie Changlong
  2017-05-11 19:08   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  2 siblings, 1 reply; 18+ messages in thread
From: Eric Blake @ 2017-04-12 14:28 UTC (permalink / raw)
  To: zhanghailiang, stefanha, qemu-devel
  Cc: kwolf, xiecl.fnst, zhangchen.fnst, Wen Congyang, qemu-block

[-- Attachment #1: Type: text/plain, Size: 1657 bytes --]

On 04/12/2017 09:05 AM, zhanghailiang wrote:
> We use these two options to identify which disk is
> shared
> 
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> ---
> v4:
> - Add proper comment for primary_disk (Stefan)
> v2:
> - Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
> - Fix comments for these two options
> ---

> +++ b/qapi/block-core.json
> @@ -2661,12 +2661,20 @@
>  #          node who owns the replication node chain. Must not be given in
>  #          primary mode.
>  #
> +# @shared-disk-id: Id of shared disk while is replication mode, if @shared-disk
> +#                  is true, this option is required (Since: 2.10)
> +#
> +# @shared-disk: To indicate whether or not a disk is shared by primary VM
> +#               and secondary VM. (The default is false) (Since: 2.10)
> +#
>  # Since: 2.9
>  ##
>  { 'struct': 'BlockdevOptionsReplication',
>    'base': 'BlockdevOptionsGenericFormat',
>    'data': { 'mode': 'ReplicationMode',
> -            '*top-id': 'str' } }
> +            '*top-id': 'str',
> +            '*shared-disk-id': 'str',
> +            '*shared-disk': 'bool' } }

Do we need a separate bool and string? Or is it sufficient to say that
if shared-disk is omitted, we are not sharing, and that if a shared-disk
string is present, then we are sharing and it names the id of the shared
disk.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-04-12 14:28   ` Eric Blake
@ 2017-04-17  6:31     ` Hailiang Zhang
  0 siblings, 0 replies; 18+ messages in thread
From: Hailiang Zhang @ 2017-04-17  6:31 UTC (permalink / raw)
  To: Eric Blake, stefanha, qemu-devel
  Cc: xuquan8, kwolf, xiecl.fnst, zhangchen.fnst, Wen Congyang, qemu-block

On 2017/4/12 22:28, Eric Blake wrote:
> On 04/12/2017 09:05 AM, zhanghailiang wrote:
>> We use these two options to identify which disk is
>> shared
>>
>> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>> ---
>> v4:
>> - Add proper comment for primary_disk (Stefan)
>> v2:
>> - Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
>> - Fix comments for these two options
>> ---
>> +++ b/qapi/block-core.json
>> @@ -2661,12 +2661,20 @@
>>   #          node who owns the replication node chain. Must not be given in
>>   #          primary mode.
>>   #
>> +# @shared-disk-id: Id of shared disk while is replication mode, if @shared-disk
>> +#                  is true, this option is required (Since: 2.10)
>> +#
>> +# @shared-disk: To indicate whether or not a disk is shared by primary VM
>> +#               and secondary VM. (The default is false) (Since: 2.10)
>> +#
>>   # Since: 2.9
>>   ##
>>   { 'struct': 'BlockdevOptionsReplication',
>>     'base': 'BlockdevOptionsGenericFormat',
>>     'data': { 'mode': 'ReplicationMode',
>> -            '*top-id': 'str' } }
>> +            '*top-id': 'str',
>> +            '*shared-disk-id': 'str',
>> +            '*shared-disk': 'bool' } }
> Do we need a separate bool and string? Or is it sufficient to say that
> if shared-disk is omitted, we are not sharing, and that if a shared-disk
> string is present, then we are sharing and it names the id of the shared
> disk.

Er,  Yes, We need both of them, the command line of secondary sides is like:

  -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=hidden_disk0,shared-disk=on
We only need the bool shared-disk to indicate whether disk is sharing or not, but
for primary side, we need to the blockdev-add command to tell primary which disk is shared.
   { 'execute': 'blockdev-add',
     'arguments': {
         'driver': 'replication',
         'node-name': 'rep',
         'mode': 'primary',
         'shared-disk-id': 'primary_disk0',
         'shared-disk': true,
         'file': {
             'driver': 'nbd',
             'export': 'hidden_disk0',
             'server': {
                 'type': 'inet',
                 'data': {
                     'host': 'xxx.xxx.xxx.xxx',
                     'port': 'yyy'
                 }
             }
         }
      }
   }

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options zhanghailiang
  2017-04-12 14:28   ` Eric Blake
@ 2017-04-18  5:59   ` Xie Changlong
  2017-05-12  6:25     ` Hailiang Zhang
  2017-05-11 19:08   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  2 siblings, 1 reply; 18+ messages in thread
From: Xie Changlong @ 2017-04-18  5:59 UTC (permalink / raw)
  To: zhanghailiang, stefanha, qemu-devel
  Cc: qemu-block, kwolf, zhangchen.fnst, Wen Congyang



On 04/12/2017 10:05 PM, zhanghailiang wrote:
> We use these two options to identify which disk is
> shared
>
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> ---
> v4:
> - Add proper comment for primary_disk (Stefan)
> v2:
> - Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
> - Fix comments for these two options
> ---
>   block/replication.c  | 43 +++++++++++++++++++++++++++++++++++++++++--
>   qapi/block-core.json | 10 +++++++++-
>   2 files changed, 50 insertions(+), 3 deletions(-)
>
> diff --git a/block/replication.c b/block/replication.c
> index bf3c395..418b81b 100644
> --- a/block/replication.c
> +++ b/block/replication.c
> @@ -25,9 +25,12 @@
>   typedef struct BDRVReplicationState {
>       ReplicationMode mode;
>       int replication_state;
> +    bool is_shared_disk;
> +    char *shared_disk_id;
>       BdrvChild *active_disk;
>       BdrvChild *hidden_disk;
>       BdrvChild *secondary_disk;
> +    BdrvChild *primary_disk;
>       char *top_id;
>       ReplicationState *rs;
>       Error *blocker;
> @@ -53,6 +56,9 @@ static void replication_stop(ReplicationState *rs, bool failover,
>   
>   #define REPLICATION_MODE        "mode"
>   #define REPLICATION_TOP_ID      "top-id"
> +#define REPLICATION_SHARED_DISK "shared-disk"
> +#define REPLICATION_SHARED_DISK_ID "shared-disk-id"
> +
>   static QemuOptsList replication_runtime_opts = {
>       .name = "replication",
>       .head = QTAILQ_HEAD_INITIALIZER(replication_runtime_opts.head),
> @@ -65,6 +71,14 @@ static QemuOptsList replication_runtime_opts = {
>               .name = REPLICATION_TOP_ID,
>               .type = QEMU_OPT_STRING,
>           },
> +        {
> +            .name = REPLICATION_SHARED_DISK_ID,
> +            .type = QEMU_OPT_STRING,
> +        },
> +        {
> +            .name = REPLICATION_SHARED_DISK,
> +            .type = QEMU_OPT_BOOL,
> +        },
>           { /* end of list */ }
>       },
>   };
> @@ -85,6 +99,9 @@ static int replication_open(BlockDriverState *bs, QDict *options,
>       QemuOpts *opts = NULL;
>       const char *mode;
>       const char *top_id;
> +    const char *shared_disk_id;
> +    BlockBackend *blk;
> +    BlockDriverState *tmp_bs;
>   
>       bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
>                                  false, errp);
> @@ -125,12 +142,33 @@ static int replication_open(BlockDriverState *bs, QDict *options,
>                      "The option mode's value should be primary or secondary");
>           goto fail;
>       }
> +    s->is_shared_disk = qemu_opt_get_bool(opts, REPLICATION_SHARED_DISK,
> +

What If secondary side is supplied with 'REPLICATION_SHARED_DISK_ID'? 
Pls refer f4f2539bc to pefect the logical.
>                                          false);
> +    if (s->is_shared_disk && (s->mode == REPLICATION_MODE_PRIMARY)) {
> +        shared_disk_id = qemu_opt_get(opts, REPLICATION_SHARED_DISK_ID);
> +        if (!shared_disk_id) {
> +            error_setg(&local_err, "Missing shared disk blk option");
> +            goto fail;
> +        }
> +        s->shared_disk_id = g_strdup(shared_disk_id);
> +        blk = blk_by_name(s->shared_disk_id);
> +        if (!blk) {
> +            error_setg(&local_err, "There is no %s block", s->shared_disk_id);
> +            goto fail;
> +        }
> +        /* We have a BlockBackend for the primary disk but use BdrvChild for
> +         * consistency - active_disk, secondary_disk, etc are also BdrvChild.
> +         */
> +        tmp_bs = blk_bs(blk);
> +        s->primary_disk = QLIST_FIRST(&tmp_bs->parents);
> +    }
>   
>       s->rs = replication_new(bs, &replication_ops);
>   
> -    ret = 0;
> -
> +    qemu_opts_del(opts);
> +    return 0;
>   fail:
> +    g_free(s->shared_disk_id);
>       qemu_opts_del(opts);
>       error_propagate(errp, local_err);
>   
> @@ -141,6 +179,7 @@ static void replication_close(BlockDriverState *bs)
>   {
>       BDRVReplicationState *s = bs->opaque;
>   
> +    g_free(s->shared_disk_id);
>       if (s->replication_state == BLOCK_REPLICATION_RUNNING) {
>           replication_stop(s->rs, false, NULL);
>       }
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index 033457c..361c932 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -2661,12 +2661,20 @@
>   #          node who owns the replication node chain. Must not be given in
>   #          primary mode.
>   #
> +# @shared-disk-id: Id of shared disk while is replication mode, if @shared-disk
> +#                  is true, this option is required (Since: 2.10)
> +#
Further explanations:

For @shared-disk-id, it must/only be given when @shared-disk enable on
Primary side.

> +# @shared-disk: To indicate whether or not a disk is shared by primary VM
> +#               and secondary VM. (The default is false) (Since: 2.10)
> +#
Further explanations:

For @shared-disk, it must be given or not-given on both side at the same 
time.

>   # Since: 2.9
>   ##
>   { 'struct': 'BlockdevOptionsReplication',
>     'base': 'BlockdevOptionsGenericFormat',
>     'data': { 'mode': 'ReplicationMode',
> -            '*top-id': 'str' } }
> +            '*top-id': 'str',
> +            '*shared-disk-id': 'str',
> +            '*shared-disk': 'bool' } }
>   
>   ##
>   # @NFSTransport:

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options zhanghailiang
  2017-04-12 14:28   ` Eric Blake
  2017-04-18  5:59   ` Xie Changlong
@ 2017-05-11 19:08   ` Stefan Hajnoczi
  2017-05-12  6:28     ` Hailiang Zhang
  2 siblings, 1 reply; 18+ messages in thread
From: Stefan Hajnoczi @ 2017-05-11 19:08 UTC (permalink / raw)
  To: zhanghailiang
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, zhangchen.fnst,
	Wen Congyang, qemu-block

[-- Attachment #1: Type: text/plain, Size: 788 bytes --]

On Wed, Apr 12, 2017 at 10:05:17PM +0800, zhanghailiang wrote:
> We use these two options to identify which disk is
> shared
> 
> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
> ---
> v4:
> - Add proper comment for primary_disk (Stefan)
> v2:
> - Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
> - Fix comments for these two options
> ---
>  block/replication.c  | 43 +++++++++++++++++++++++++++++++++++++++++--
>  qapi/block-core.json | 10 +++++++++-
>  2 files changed, 50 insertions(+), 3 deletions(-)

Aside from the ongoing discussion about this patch...

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case zhanghailiang
@ 2017-05-11 19:15   ` Stefan Hajnoczi
  2017-05-12  7:03     ` Hailiang Zhang
  0 siblings, 1 reply; 18+ messages in thread
From: Stefan Hajnoczi @ 2017-05-11 19:15 UTC (permalink / raw)
  To: zhanghailiang
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, zhangchen.fnst,
	Wen Congyang, qemu-block

[-- Attachment #1: Type: text/plain, Size: 672 bytes --]

On Wed, Apr 12, 2017 at 10:05:20PM +0800, zhanghailiang wrote:
> @@ -612,6 +644,16 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
>                  error_propagate(errp, local_err);
>                  break;
>              }
> +        } else {
> +            /*
> +             * For shared disk, we need to force SVM to re-read metadata
> +             * that is loaded in memory, or there will be inconsistent.
> +             */
> +            bdrv_invalidate_cache(s->secondary_disk->bs, &local_err);

I'm not sure this call has any effect:

    if (!(bs->open_flags & BDRV_O_INACTIVE)) {
        return;
    }

Is BDRV_O_INACTIVE set?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v4 0/6] COLO block replication supports shared disk case
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
                   ` (5 preceding siblings ...)
  2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 6/6] nbd/replication: implement .bdrv_get_info() for nbd and replication driver zhanghailiang
@ 2017-05-11 19:17 ` Stefan Hajnoczi
  2017-05-12  7:26   ` Hailiang Zhang
  2017-05-16 10:41 ` [Qemu-devel] " 吴志勇
  7 siblings, 1 reply; 18+ messages in thread
From: Stefan Hajnoczi @ 2017-05-11 19:17 UTC (permalink / raw)
  To: zhanghailiang
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, qemu-block,
	zhangchen.fnst, eddie.dong, Dr . David Alan Gilbert

[-- Attachment #1: Type: text/plain, Size: 1529 bytes --]

On Wed, Apr 12, 2017 at 10:05:15PM +0800, zhanghailiang wrote:
> COLO block replication doesn't support the shared disk case,
> Here we try to implement it and this is the 4th version.
> 
> Please review and any commits are welcomed.
> 
> Cc: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
> Cc: eddie.dong@intel.com

Sorry for the delay.  Feel free to ping me if I don't review within a
few days when you post a patch.

> v4:
> - Add proper comment for primary_disk in patch 2 (Stefan)
> - Call bdrv_invalidate_cache() while do checkpoint for shared disk in patch 5
> 
> v3:
> - Fix some comments from Stefan and Eric
> 
> v2:
> - Drop the patch which add a blk_root() helper
> - Fix some comments from Changlong
> 
> zhanghailiang (6):
>   docs/block-replication: Add description for shared-disk case
>   replication: add shared-disk and shared-disk-id options
>   replication: Split out backup_do_checkpoint() from
>     secondary_do_checkpoint()
>   replication: fix code logic with the new shared_disk option
>   replication: Implement block replication for shared disk case
>   nbd/replication: implement .bdrv_get_info() for nbd and replication
>     driver
> 
>  block/nbd.c                |  12 +++
>  block/replication.c        | 198 ++++++++++++++++++++++++++++++++++-----------
>  docs/block-replication.txt | 139 ++++++++++++++++++++++++++++++-
>  qapi/block-core.json       |  10 ++-
>  4 files changed, 306 insertions(+), 53 deletions(-)
> 
> -- 
> 1.8.3.1
> 
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-04-18  5:59   ` Xie Changlong
@ 2017-05-12  6:25     ` Hailiang Zhang
  0 siblings, 0 replies; 18+ messages in thread
From: Hailiang Zhang @ 2017-05-12  6:25 UTC (permalink / raw)
  To: xiechanglong.d, stefanha, qemu-devel
  Cc: qemu-block, kwolf, zhangchen.fnst, Wen Congyang

On 2017/4/18 13:59, Xie Changlong wrote:
>
> On 04/12/2017 10:05 PM, zhanghailiang wrote:
>> We use these two options to identify which disk is
>> shared
>>
>> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>> ---
>> v4:
>> - Add proper comment for primary_disk (Stefan)
>> v2:
>> - Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
>> - Fix comments for these two options
>> ---
>>    block/replication.c  | 43 +++++++++++++++++++++++++++++++++++++++++--
>>    qapi/block-core.json | 10 +++++++++-
>>    2 files changed, 50 insertions(+), 3 deletions(-)
>>
>> diff --git a/block/replication.c b/block/replication.c
>> index bf3c395..418b81b 100644
>> --- a/block/replication.c
>> +++ b/block/replication.c
>> @@ -25,9 +25,12 @@
>>    typedef struct BDRVReplicationState {
>>        ReplicationMode mode;
>>        int replication_state;
>> +    bool is_shared_disk;
>> +    char *shared_disk_id;
>>        BdrvChild *active_disk;
>>        BdrvChild *hidden_disk;
>>        BdrvChild *secondary_disk;
>> +    BdrvChild *primary_disk;
>>        char *top_id;
>>        ReplicationState *rs;
>>        Error *blocker;
>> @@ -53,6 +56,9 @@ static void replication_stop(ReplicationState *rs, bool failover,
>>    
>>    #define REPLICATION_MODE        "mode"
>>    #define REPLICATION_TOP_ID      "top-id"
>> +#define REPLICATION_SHARED_DISK "shared-disk"
>> +#define REPLICATION_SHARED_DISK_ID "shared-disk-id"
>> +
>>    static QemuOptsList replication_runtime_opts = {
>>        .name = "replication",
>>        .head = QTAILQ_HEAD_INITIALIZER(replication_runtime_opts.head),
>> @@ -65,6 +71,14 @@ static QemuOptsList replication_runtime_opts = {
>>                .name = REPLICATION_TOP_ID,
>>                .type = QEMU_OPT_STRING,
>>            },
>> +        {
>> +            .name = REPLICATION_SHARED_DISK_ID,
>> +            .type = QEMU_OPT_STRING,
>> +        },
>> +        {
>> +            .name = REPLICATION_SHARED_DISK,
>> +            .type = QEMU_OPT_BOOL,
>> +        },
>>            { /* end of list */ }
>>        },
>>    };
>> @@ -85,6 +99,9 @@ static int replication_open(BlockDriverState *bs, QDict *options,
>>        QemuOpts *opts = NULL;
>>        const char *mode;
>>        const char *top_id;
>> +    const char *shared_disk_id;
>> +    BlockBackend *blk;
>> +    BlockDriverState *tmp_bs;
>>    
>>        bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
>>                                   false, errp);
>> @@ -125,12 +142,33 @@ static int replication_open(BlockDriverState *bs, QDict *options,
>>                       "The option mode's value should be primary or secondary");
>>            goto fail;
>>        }
>> +    s->is_shared_disk = qemu_opt_get_bool(opts, REPLICATION_SHARED_DISK,
>> +
> What If secondary side is supplied with 'REPLICATION_SHARED_DISK_ID'?
> Pls refer f4f2539bc to pefect the logical.

Hmm, we should not configure it for secondary side, i'll fix it in next version.


>>                                           false);
>> +    if (s->is_shared_disk && (s->mode == REPLICATION_MODE_PRIMARY)) {
>> +        shared_disk_id = qemu_opt_get(opts, REPLICATION_SHARED_DISK_ID);
>> +        if (!shared_disk_id) {
>> +            error_setg(&local_err, "Missing shared disk blk option");
>> +            goto fail;
>> +        }
>> +        s->shared_disk_id = g_strdup(shared_disk_id);
>> +        blk = blk_by_name(s->shared_disk_id);
>> +        if (!blk) {
>> +            error_setg(&local_err, "There is no %s block", s->shared_disk_id);
>> +            goto fail;
>> +        }
>> +        /* We have a BlockBackend for the primary disk but use BdrvChild for
>> +         * consistency - active_disk, secondary_disk, etc are also BdrvChild.
>> +         */
>> +        tmp_bs = blk_bs(blk);
>> +        s->primary_disk = QLIST_FIRST(&tmp_bs->parents);
>> +    }
>>    
>>        s->rs = replication_new(bs, &replication_ops);
>>    
>> -    ret = 0;
>> -
>> +    qemu_opts_del(opts);
>> +    return 0;
>>    fail:
>> +    g_free(s->shared_disk_id);
>>        qemu_opts_del(opts);
>>        error_propagate(errp, local_err);
>>    
>> @@ -141,6 +179,7 @@ static void replication_close(BlockDriverState *bs)
>>    {
>>        BDRVReplicationState *s = bs->opaque;
>>    
>> +    g_free(s->shared_disk_id);
>>        if (s->replication_state == BLOCK_REPLICATION_RUNNING) {
>>            replication_stop(s->rs, false, NULL);
>>        }
>> diff --git a/qapi/block-core.json b/qapi/block-core.json
>> index 033457c..361c932 100644
>> --- a/qapi/block-core.json
>> +++ b/qapi/block-core.json
>> @@ -2661,12 +2661,20 @@
>>    #          node who owns the replication node chain. Must not be given in
>>    #          primary mode.
>>    #
>> +# @shared-disk-id: Id of shared disk while is replication mode, if @shared-disk
>> +#                  is true, this option is required (Since: 2.10)
>> +#
> Further explanations:
>
> For @shared-disk-id, it must/only be given when @shared-disk enable on
> Primary side.

OK.
>> +# @shared-disk: To indicate whether or not a disk is shared by primary VM
>> +#               and secondary VM. (The default is false) (Since: 2.10)
>> +#
> Further explanations:
>
> For @shared-disk, it must be given or not-given on both side at the same
> time.

OK, will fix it, thanks.

>>    # Since: 2.9
>>    ##
>>    { 'struct': 'BlockdevOptionsReplication',
>>      'base': 'BlockdevOptionsGenericFormat',
>>      'data': { 'mode': 'ReplicationMode',
>> -            '*top-id': 'str' } }
>> +            '*top-id': 'str',
>> +            '*shared-disk-id': 'str',
>> +            '*shared-disk': 'bool' } }
>>    
>>    ##
>>    # @NFSTransport:
>
>
>
> .
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options
  2017-05-11 19:08   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
@ 2017-05-12  6:28     ` Hailiang Zhang
  0 siblings, 0 replies; 18+ messages in thread
From: Hailiang Zhang @ 2017-05-12  6:28 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, zhangchen.fnst,
	Wen Congyang, qemu-block

On 2017/5/12 3:08, Stefan Hajnoczi wrote:
> On Wed, Apr 12, 2017 at 10:05:17PM +0800, zhanghailiang wrote:
>> We use these two options to identify which disk is
>> shared
>>
>> Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
>> ---
>> v4:
>> - Add proper comment for primary_disk (Stefan)
>> v2:
>> - Move g_free(s->shared_disk_id) to the common fail process place (Stefan)
>> - Fix comments for these two options
>> ---
>>   block/replication.c  | 43 +++++++++++++++++++++++++++++++++++++++++--
>>   qapi/block-core.json | 10 +++++++++-
>>   2 files changed, 50 insertions(+), 3 deletions(-)
> Aside from the ongoing discussion about this patch...
>
> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>

Thanks,  I'll fix the related problems found by changlong.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case
  2017-05-11 19:15   ` Stefan Hajnoczi
@ 2017-05-12  7:03     ` Hailiang Zhang
  0 siblings, 0 replies; 18+ messages in thread
From: Hailiang Zhang @ 2017-05-12  7:03 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, zhangchen.fnst,
	Wen Congyang, qemu-block

On 2017/5/12 3:15, Stefan Hajnoczi wrote:
> On Wed, Apr 12, 2017 at 10:05:20PM +0800, zhanghailiang wrote:
>> @@ -612,6 +644,16 @@ static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
>>                   error_propagate(errp, local_err);
>>                   break;
>>               }
>> +        } else {
>> +            /*
>> +             * For shared disk, we need to force SVM to re-read metadata
>> +             * that is loaded in memory, or there will be inconsistent.
>> +             */
>> +            bdrv_invalidate_cache(s->secondary_disk->bs, &local_err);
> I'm not sure this call has any effect:
>
>      if (!(bs->open_flags & BDRV_O_INACTIVE)) {
>          return;
>      }
>
> Is BDRV_O_INACTIVE set?

No, you are right, it does not take any effect. So should we set this flag for secondary_disk ?
Is it enough to set this flag only, or should we call bdrv_inactivate_recurse() ?
To be honest, i'm not quite familiar with this parts.

Thanks,
Hailiang

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v4 0/6] COLO block replication supports shared disk case
  2017-05-11 19:17 ` [Qemu-devel] [Qemu-block] [PATCH v4 0/6] COLO block replication supports shared disk case Stefan Hajnoczi
@ 2017-05-12  7:26   ` Hailiang Zhang
  0 siblings, 0 replies; 18+ messages in thread
From: Hailiang Zhang @ 2017-05-12  7:26 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, qemu-block,
	zhangchen.fnst, eddie.dong, Dr . David Alan Gilbert

On 2017/5/12 3:17, Stefan Hajnoczi wrote:
> On Wed, Apr 12, 2017 at 10:05:15PM +0800, zhanghailiang wrote:
>> COLO block replication doesn't support the shared disk case,
>> Here we try to implement it and this is the 4th version.
>>
>> Please review and any commits are welcomed.
>>
>> Cc: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
>> Cc: eddie.dong@intel.com
> Sorry for the delay.  Feel free to ping me if I don't review within a
> few days when you post a patch.

That is OK. :) , I was doing other things these days, and it is not quite urgent ... thanks.

>> v4:
>> - Add proper comment for primary_disk in patch 2 (Stefan)
>> - Call bdrv_invalidate_cache() while do checkpoint for shared disk in patch 5
>>
>> v3:
>> - Fix some comments from Stefan and Eric
>>
>> v2:
>> - Drop the patch which add a blk_root() helper
>> - Fix some comments from Changlong
>>
>> zhanghailiang (6):
>>    docs/block-replication: Add description for shared-disk case
>>    replication: add shared-disk and shared-disk-id options
>>    replication: Split out backup_do_checkpoint() from
>>      secondary_do_checkpoint()
>>    replication: fix code logic with the new shared_disk option
>>    replication: Implement block replication for shared disk case
>>    nbd/replication: implement .bdrv_get_info() for nbd and replication
>>      driver
>>
>>   block/nbd.c                |  12 +++
>>   block/replication.c        | 198 ++++++++++++++++++++++++++++++++++-----------
>>   docs/block-replication.txt | 139 ++++++++++++++++++++++++++++++-
>>   qapi/block-core.json       |  10 ++-
>>   4 files changed, 306 insertions(+), 53 deletions(-)
>>
>> -- 
>> 1.8.3.1
>>
>>
>>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case
  2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
                   ` (6 preceding siblings ...)
  2017-05-11 19:17 ` [Qemu-devel] [Qemu-block] [PATCH v4 0/6] COLO block replication supports shared disk case Stefan Hajnoczi
@ 2017-05-16 10:41 ` 吴志勇
  7 siblings, 0 replies; 18+ messages in thread
From: 吴志勇 @ 2017-05-16 10:41 UTC (permalink / raw)
  To: zhanghailiang
  Cc: stefanha, qemu-devel, kwolf, xiecl.fnst, qemu-block,
	zhangchen.fnst, eddie.dong, Dr . David Alan Gilbert

HI, Hai Liang


Is there recently any plan to post libvirt support for COLO feature?


Regards,


Zhi Yong Wu


At 2017-04-12 22:05:15, "zhanghailiang" <zhang.zhanghailiang@huawei.com> wrote:
>COLO block replication doesn't support the shared disk case,
>Here we try to implement it and this is the 4th version.
>
>Please review and any commits are welcomed.
>
>Cc: Dr. David Alan Gilbert (git) <dgilbert@redhat.com>
>Cc: eddie.dong@intel.com
>
>v4:
>- Add proper comment for primary_disk in patch 2 (Stefan)
>- Call bdrv_invalidate_cache() while do checkpoint for shared disk in patch 5
>
>v3:
>- Fix some comments from Stefan and Eric
>
>v2:
>- Drop the patch which add a blk_root() helper
>- Fix some comments from Changlong
>
>zhanghailiang (6):
>  docs/block-replication: Add description for shared-disk case
>  replication: add shared-disk and shared-disk-id options
>  replication: Split out backup_do_checkpoint() from
>    secondary_do_checkpoint()
>  replication: fix code logic with the new shared_disk option
>  replication: Implement block replication for shared disk case
>  nbd/replication: implement .bdrv_get_info() for nbd and replication
>    driver
>
> block/nbd.c                |  12 +++
> block/replication.c        | 198 ++++++++++++++++++++++++++++++++++-----------
> docs/block-replication.txt | 139 ++++++++++++++++++++++++++++++-
> qapi/block-core.json       |  10 ++-
> 4 files changed, 306 insertions(+), 53 deletions(-)
>
>-- 
>1.8.3.1
>
>
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-05-16 11:12 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-12 14:05 [Qemu-devel] [PATCH v4 0/6] COLO block replication supports shared disk case zhanghailiang
2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 1/6] docs/block-replication: Add description for shared-disk case zhanghailiang
2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 2/6] replication: add shared-disk and shared-disk-id options zhanghailiang
2017-04-12 14:28   ` Eric Blake
2017-04-17  6:31     ` Hailiang Zhang
2017-04-18  5:59   ` Xie Changlong
2017-05-12  6:25     ` Hailiang Zhang
2017-05-11 19:08   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-05-12  6:28     ` Hailiang Zhang
2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 3/6] replication: Split out backup_do_checkpoint() from secondary_do_checkpoint() zhanghailiang
2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 4/6] replication: fix code logic with the new shared_disk option zhanghailiang
2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 5/6] replication: Implement block replication for shared disk case zhanghailiang
2017-05-11 19:15   ` Stefan Hajnoczi
2017-05-12  7:03     ` Hailiang Zhang
2017-04-12 14:05 ` [Qemu-devel] [PATCH v4 6/6] nbd/replication: implement .bdrv_get_info() for nbd and replication driver zhanghailiang
2017-05-11 19:17 ` [Qemu-devel] [Qemu-block] [PATCH v4 0/6] COLO block replication supports shared disk case Stefan Hajnoczi
2017-05-12  7:26   ` Hailiang Zhang
2017-05-16 10:41 ` [Qemu-devel] " 吴志勇

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.