|  | /* | 
|  | * Replication filter | 
|  | * | 
|  | * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. | 
|  | * Copyright (c) 2016 Intel Corporation | 
|  | * Copyright (c) 2016 FUJITSU LIMITED | 
|  | * | 
|  | * Author: | 
|  | *   Changlong Xie <xiecl.fnst@cn.fujitsu.com> | 
|  | * | 
|  | * This work is licensed under the terms of the GNU GPL, version 2 or later. | 
|  | * See the COPYING file in the top-level directory. | 
|  | */ | 
|  |  | 
|  | #include "qemu/osdep.h" | 
|  | #include "qapi/error.h" | 
|  | #include "block/replication.h" | 
|  |  | 
|  | static QLIST_HEAD(, ReplicationState) replication_states; | 
|  |  | 
|  | ReplicationState *replication_new(void *opaque, ReplicationOps *ops) | 
|  | { | 
|  | ReplicationState *rs; | 
|  |  | 
|  | assert(ops != NULL); | 
|  | rs = g_new0(ReplicationState, 1); | 
|  | rs->opaque = opaque; | 
|  | rs->ops = ops; | 
|  | QLIST_INSERT_HEAD(&replication_states, rs, node); | 
|  |  | 
|  | return rs; | 
|  | } | 
|  |  | 
|  | void replication_remove(ReplicationState *rs) | 
|  | { | 
|  | if (rs) { | 
|  | QLIST_REMOVE(rs, node); | 
|  | g_free(rs); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* | 
|  | * The caller of the function MUST make sure vm stopped | 
|  | */ | 
|  | void replication_start_all(ReplicationMode mode, Error **errp) | 
|  | { | 
|  | ReplicationState *rs, *next; | 
|  | Error *local_err = NULL; | 
|  |  | 
|  | QLIST_FOREACH_SAFE(rs, &replication_states, node, next) { | 
|  | if (rs->ops && rs->ops->start) { | 
|  | rs->ops->start(rs, mode, &local_err); | 
|  | } | 
|  | if (local_err) { | 
|  | error_propagate(errp, local_err); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void replication_do_checkpoint_all(Error **errp) | 
|  | { | 
|  | ReplicationState *rs, *next; | 
|  | Error *local_err = NULL; | 
|  |  | 
|  | QLIST_FOREACH_SAFE(rs, &replication_states, node, next) { | 
|  | if (rs->ops && rs->ops->checkpoint) { | 
|  | rs->ops->checkpoint(rs, &local_err); | 
|  | } | 
|  | if (local_err) { | 
|  | error_propagate(errp, local_err); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void replication_get_error_all(Error **errp) | 
|  | { | 
|  | ReplicationState *rs, *next; | 
|  | Error *local_err = NULL; | 
|  |  | 
|  | QLIST_FOREACH_SAFE(rs, &replication_states, node, next) { | 
|  | if (rs->ops && rs->ops->get_error) { | 
|  | rs->ops->get_error(rs, &local_err); | 
|  | } | 
|  | if (local_err) { | 
|  | error_propagate(errp, local_err); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | void replication_stop_all(bool failover, Error **errp) | 
|  | { | 
|  | ReplicationState *rs, *next; | 
|  | Error *local_err = NULL; | 
|  |  | 
|  | QLIST_FOREACH_SAFE(rs, &replication_states, node, next) { | 
|  | if (rs->ops && rs->ops->stop) { | 
|  | rs->ops->stop(rs, failover, &local_err); | 
|  | } | 
|  | if (local_err) { | 
|  | error_propagate(errp, local_err); | 
|  | return; | 
|  | } | 
|  | } | 
|  | } |