On Thu, Jun 18, 2015 at 04:49:18PM +0800, Wen Congyang wrote: CCing Alberto Garcia for the quorum block driver. > Signed-off-by: Wen Congyang > Signed-off-by: zhanghailiang > Signed-off-by: Gonglei > --- > block/quorum.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 78 insertions(+) > > diff --git a/block/quorum.c b/block/quorum.c > index 77e55b2..01cfac0 100644 > --- a/block/quorum.c > +++ b/block/quorum.c > @@ -82,6 +82,8 @@ typedef struct BDRVQuorumState { > */ > > QuorumReadPattern read_pattern; > + > + int replication_index; /* store which child supports block replication */ > } BDRVQuorumState; > > typedef struct QuorumAIOCB QuorumAIOCB; > @@ -945,6 +947,7 @@ static int quorum_open(BlockDriverState *bs, QDict *options, int flags, > } > > g_free(opened); > + s->replication_index = -1; > goto exit; > > close_exit: > @@ -1032,6 +1035,77 @@ static void quorum_refresh_filename(BlockDriverState *bs) > bs->full_open_options = opts; > } > > +static void quorum_start_replication(BlockDriverState *bs, ReplicationMode mode, > + Error **errp) > +{ > + BDRVQuorumState *s = bs->opaque; > + int count = 0, i, index; > + Error *local_err = NULL; > + > + /* > + * TODO: support REPLICATION_MODE_SECONDARY if we allow secondary > + * QEMU becoming primary QEMU. > + */ > + if (mode != REPLICATION_MODE_PRIMARY) { > + error_setg(errp, "Invalid parameter 'mode'"); > + return; > + } > + > + if (s->read_pattern != QUORUM_READ_PATTERN_FIFO) { > + error_setg(errp, "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_setg(errp, "this feature or command is not currently supported"); > + } else if (count > 1) { > + for (i = 0; i < s->num_children; i++) { > + bdrv_stop_replication(s->bs[i], false, NULL); > + } > + error_setg(errp, "too many children support block replication"); > + } else { > + s->replication_index = index; > + } > +} > + > +static void quorum_do_checkpoint(BlockDriverState *bs, Error **errp) > +{ > + BDRVQuorumState *s = bs->opaque; > + > + if (s->replication_index < 0) { > + error_setg(errp, "Block replication is not started"); > + return; > + } > + > + bdrv_do_checkpoint(s->bs[s->replication_index], errp); > +} > + > +static void quorum_stop_replication(BlockDriverState *bs, bool failover, > + Error **errp) > +{ > + BDRVQuorumState *s = bs->opaque; > + > + if (s->replication_index < 0) { > + error_setg(errp, "Block replication is not started"); > + return; > + } > + > + bdrv_stop_replication(s->bs[s->replication_index], failover, errp); > + s->replication_index = -1; > +} > + > static BlockDriver bdrv_quorum = { > .format_name = "quorum", > .protocol_name = "quorum", > @@ -1055,6 +1129,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) > -- > 2.4.3 > >