diff mbox

[RFC,v2,2/6] replication: add shared-disk and shared-disk-id options

Message ID 1480926904-17596-3-git-send-email-zhang.zhanghailiang@huawei.com
State New
Headers show

Commit Message

Zhanghailiang Dec. 5, 2016, 8:35 a.m. UTC
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>
---
v2:
- add these two options for BlockdevOptionsReplication to support
  qmp blockdev-add command.
- fix a memory leak found by Changlong
---
 block/replication.c  | 37 +++++++++++++++++++++++++++++++++++++
 qapi/block-core.json |  9 ++++++++-
 2 files changed, 45 insertions(+), 1 deletion(-)

Comments

Eric Blake Dec. 5, 2016, 4:22 p.m. UTC | #1
On 12/05/2016 02:35 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>
> ---
> v2:
> - add these two options for BlockdevOptionsReplication to support
>   qmp blockdev-add command.
> - fix a memory leak found by Changlong
> ---

> +++ b/qapi/block-core.json
> @@ -2232,12 +2232,19 @@
>  #          node who owns the replication node chain. Must not be given in
>  #          primary mode.
>  #
> +# @shared-disk-id: #optional The id of shared disk while in replication mode.
> +#
> +# @shared-disk: #optional To indicate whether or not a disk is shared by
> +#               primary VM and secondary VM.

Both of these need a '(since 2.9)' designation since they've missed 2.8,
and could probably also use documentation on the default value assumed
when the parameter is omitted.

> +#
>  # Since: 2.8
>  ##
>  { 'struct': 'BlockdevOptionsReplication',
>    'base': 'BlockdevOptionsGenericFormat',
>    'data': { 'mode': 'ReplicationMode',
> -            '*top-id': 'str' } }
> +            '*top-id': 'str',
> +            '*shared-disk-id': 'str',
> +            '*shared-disk': 'bool' } }
>  
>  ##
>  # @NFSTransport
>
Changlong Xie Dec. 20, 2016, 11:34 a.m. UTC | #2
On 12/05/2016 04:35 PM, zhanghailiang wrote:
> diff --git a/qapi/block-core.json b/qapi/block-core.json
> index c29bef7..52d7e0d 100644
> --- a/qapi/block-core.json
> +++ b/qapi/block-core.json
> @@ -2232,12 +2232,19 @@
>   #          node who owns the replication node chain. Must not be given in
>   #          primary mode.
>   #
> +# @shared-disk-id: #optional The id of shared disk while in replication mode.
> +#
> +# @shared-disk: #optional To indicate whether or not a disk is shared by
> +#               primary VM and secondary VM.
> +#

I think we need more detailed description here.

For @shared-disk, we can only both enable or disable it on both side.
For @shared-disk-id, it must/only be given when @shared-disk enable on 
Primary side.

More, you also need to perfect the replication_open() logic.

>   # Since: 2.8
>   ##
>   { 'struct': 'BlockdevOptionsReplication',
>     'base': 'BlockdevOptionsGenericFormat',
>     'data': { 'mode': 'ReplicationMode',
> -            '*top-id': 'str' } }
> +            '*top-id': 'str',
> +            '*shared-disk-id': 'str',
> +            '*shared-disk': 'bool' } }
>
>   ##
>   # @NFSTransport
> --
Stefan Hajnoczi Jan. 17, 2017, 11:25 a.m. UTC | #3
On Mon, Dec 05, 2016 at 04:35:00PM +0800, zhanghailiang wrote:
> @@ -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;
>  
>      ret = -EINVAL;
>      opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, &error_abort);
> @@ -119,6 +136,25 @@ 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");
> +            goto fail;
> +        }
> +        s->shared_disk_id = g_strdup(shared_disk_id);
> +        blk = blk_by_name(s->shared_disk_id);
> +        if (!blk) {
> +            g_free(s->shared_disk_id);
> +            error_setg(&local_err, "There is no %s block", s->shared_disk_id);
> +            goto fail;

Please move the g_free() to the fail label to prevent future code
changes from introducing a memory leak.
Zhanghailiang Jan. 18, 2017, 6:54 a.m. UTC | #4
On 2017/1/17 19:25, Stefan Hajnoczi wrote:
> On Mon, Dec 05, 2016 at 04:35:00PM +0800, zhanghailiang wrote:
>> @@ -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;
>>
>>       ret = -EINVAL;
>>       opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, &error_abort);
>> @@ -119,6 +136,25 @@ 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");
>> +            goto fail;
>> +        }
>> +        s->shared_disk_id = g_strdup(shared_disk_id);
>> +        blk = blk_by_name(s->shared_disk_id);
>> +        if (!blk) {
>> +            g_free(s->shared_disk_id);
>> +            error_setg(&local_err, "There is no %s block", s->shared_disk_id);
>> +            goto fail;
>
> Please move the g_free() to the fail label to prevent future code
> changes from introducing a memory leak.
>

OK, I will fix it in next version, thanks very much.
Zhanghailiang Jan. 18, 2017, 6:58 a.m. UTC | #5
On 2016/12/6 0:22, Eric Blake wrote:
> On 12/05/2016 02:35 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>
>> ---
>> v2:
>> - add these two options for BlockdevOptionsReplication to support
>>    qmp blockdev-add command.
>> - fix a memory leak found by Changlong
>> ---
>
>> +++ b/qapi/block-core.json
>> @@ -2232,12 +2232,19 @@
>>   #          node who owns the replication node chain. Must not be given in
>>   #          primary mode.
>>   #
>> +# @shared-disk-id: #optional The id of shared disk while in replication mode.
>> +#
>> +# @shared-disk: #optional To indicate whether or not a disk is shared by
>> +#               primary VM and secondary VM.
>
> Both of these need a '(since 2.9)' designation since they've missed 2.8,
> and could probably also use documentation on the default value assumed
> when the parameter is omitted.
>

OK, i will add it in next version, thanks.

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

Patch

diff --git a/block/replication.c b/block/replication.c
index 729dd12..e87ae87 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;
 
     ret = -EINVAL;
     opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, &error_abort);
@@ -119,6 +136,25 @@  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");
+            goto fail;
+        }
+        s->shared_disk_id = g_strdup(shared_disk_id);
+        blk = blk_by_name(s->shared_disk_id);
+        if (!blk) {
+            g_free(s->shared_disk_id);
+            error_setg(&local_err, "There is no %s block", s->shared_disk_id);
+            goto fail;
+        }
+        /* We can't access root member of BlockBackend directly */
+        tmp_bs = blk_bs(blk);
+        s->primary_disk = QLIST_FIRST(&tmp_bs->parents);
+    }
 
     s->rs = replication_new(bs, &replication_ops);
 
@@ -135,6 +171,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 c29bef7..52d7e0d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2232,12 +2232,19 @@ 
 #          node who owns the replication node chain. Must not be given in
 #          primary mode.
 #
+# @shared-disk-id: #optional The id of shared disk while in replication mode.
+#
+# @shared-disk: #optional To indicate whether or not a disk is shared by
+#               primary VM and secondary VM.
+#
 # Since: 2.8
 ##
 { 'struct': 'BlockdevOptionsReplication',
   'base': 'BlockdevOptionsGenericFormat',
   'data': { 'mode': 'ReplicationMode',
-            '*top-id': 'str' } }
+            '*top-id': 'str',
+            '*shared-disk-id': 'str',
+            '*shared-disk': 'bool' } }
 
 ##
 # @NFSTransport