| /* |
| * 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; |
| } |
| } |
| } |