Message ID | 1480926904-17596-3-git-send-email-zhang.zhanghailiang@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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 >
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 > --
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.
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.
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 --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