On 25/03/2015 10:36, Wen Congyang wrote: > Signed-off-by: Wen Congyang <we...@cn.fujitsu.com> > Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> > Signed-off-by: Gonglei <arei.gong...@huawei.com> > --- > block/quorum.c | 79 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 79 insertions(+) > > diff --git a/block/quorum.c b/block/quorum.c > index d087135..eee829d 100644 > --- a/block/quorum.c > +++ b/block/quorum.c > @@ -84,6 +84,8 @@ typedef struct BDRVQuorumState { > */ > > QuorumReadPattern read_pattern; > + > + int colo_index; /* store which child supports block replication */ > } BDRVQuorumState; > > typedef struct QuorumAIOCB QuorumAIOCB; > @@ -1024,6 +1026,7 @@ static int quorum_open(BlockDriverState *bs, QDict > *options, int flags, > } > > g_free(opened); > + s->colo_index = -1; > goto exit; > > close_exit: > @@ -1114,6 +1117,78 @@ static void quorum_refresh_filename(BlockDriverState > *bs) > bs->full_open_options = opts; > } > > +static void quorum_stop_replication(BlockDriverState *bs, Error **errp); > +static void quorum_start_replication(BlockDriverState *bs, COLOMode mode, > + Error **errp) > +{ > + BDRVQuorumState *s = bs->opaque; > + int count = 0, i, index; > + Error *local_err = NULL; > + > + /* > + * TODO: support COLO_SECONDARY_MODE if we allow secondary > + * QEMU becoming primary QEMU. > + */ > + if (mode != COLO_MODE_PRIMARY) { > + error_set(errp, QERR_INVALID_PARAMETER, "mode"); > + return; > + } > + > + if (s->read_pattern != QUORUM_READ_PATTERN_FIFO) { > + error_set(errp, QERR_INVALID_PARAMETER, "read pattern"); > + return; > + } > + > + for (i = 0; i < s->num_children; i++) { > + bdrv_start_replication(s->bs[i], mode, &local_err); > + if (local_err) { > + error_free(local_err); > + local_err = NULL; > + } else { > + count++; > + index = i; > + } > + } > + > + if (count == 0) { > + /* No child supports block replication */ > + error_set(errp, QERR_UNSUPPORTED); > + } else if (count > 1) { > + quorum_stop_replication(bs, NULL); > + error_setg(errp, "too many children support block replication"); > + } else { > + s->colo_index = index; > + } > +} > + > +static void quorum_do_checkpoint(BlockDriverState *bs, Error **errp) > +{ > + BDRVQuorumState *s = bs->opaque; > + > + if (s->colo_index < 0) { > + error_setg(errp, "Block replication is not started"); > + return; > + } > + > + bdrv_do_checkpoint(s->bs[s->colo_index], errp); > +} > + > +static void quorum_stop_replication(BlockDriverState *bs, Error **errp) > +{ > + BDRVQuorumState *s = bs->opaque; > + int i; > + > + if (s->colo_index >= 0) { > + bdrv_stop_replication(s->bs[s->colo_index], errp); > + s->colo_index = -1; > + return; > + } > + > + for (i = 0; i < s->num_children; i++) { > + bdrv_stop_replication(s->bs[i], NULL); > + }
Why do anything at all if s->colo_index < 0? So, with the for loop removed (and possibly the if condition changed to "s->colo_index < 0", similar to quorum_do_checkpoint: Reviewed-by: Paolo Bonzini <pbonz...@redhat.com> Paolo > +} > + > static BlockDriver bdrv_quorum = { > .format_name = "quorum", > .protocol_name = "quorum", > @@ -1137,6 +1212,10 @@ static BlockDriver bdrv_quorum = { > > .is_filter = true, > .bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter, > + > + .bdrv_start_replication = quorum_start_replication, > + .bdrv_do_checkpoint = quorum_do_checkpoint, > + .bdrv_stop_replication = quorum_stop_replication, > }; > > static void bdrv_quorum_init(void) >