1190b9a8bSChanglong Xie /*
2190b9a8bSChanglong Xie * Replication filter
3190b9a8bSChanglong Xie *
4190b9a8bSChanglong Xie * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
5190b9a8bSChanglong Xie * Copyright (c) 2016 Intel Corporation
6190b9a8bSChanglong Xie * Copyright (c) 2016 FUJITSU LIMITED
7190b9a8bSChanglong Xie *
8190b9a8bSChanglong Xie * Author:
9190b9a8bSChanglong Xie * Changlong Xie <xiecl.fnst@cn.fujitsu.com>
10190b9a8bSChanglong Xie *
11190b9a8bSChanglong Xie * This work is licensed under the terms of the GNU GPL, version 2 or later.
12190b9a8bSChanglong Xie * See the COPYING file in the top-level directory.
13190b9a8bSChanglong Xie */
14190b9a8bSChanglong Xie
15190b9a8bSChanglong Xie #include "qemu/osdep.h"
16190b9a8bSChanglong Xie #include "qapi/error.h"
17*b0262955SPaolo Bonzini #include "block/replication.h"
18190b9a8bSChanglong Xie
19190b9a8bSChanglong Xie static QLIST_HEAD(, ReplicationState) replication_states;
20190b9a8bSChanglong Xie
replication_new(void * opaque,ReplicationOps * ops)21190b9a8bSChanglong Xie ReplicationState *replication_new(void *opaque, ReplicationOps *ops)
22190b9a8bSChanglong Xie {
23190b9a8bSChanglong Xie ReplicationState *rs;
24190b9a8bSChanglong Xie
25190b9a8bSChanglong Xie assert(ops != NULL);
26190b9a8bSChanglong Xie rs = g_new0(ReplicationState, 1);
27190b9a8bSChanglong Xie rs->opaque = opaque;
28190b9a8bSChanglong Xie rs->ops = ops;
29190b9a8bSChanglong Xie QLIST_INSERT_HEAD(&replication_states, rs, node);
30190b9a8bSChanglong Xie
31190b9a8bSChanglong Xie return rs;
32190b9a8bSChanglong Xie }
33190b9a8bSChanglong Xie
replication_remove(ReplicationState * rs)34190b9a8bSChanglong Xie void replication_remove(ReplicationState *rs)
35190b9a8bSChanglong Xie {
36190b9a8bSChanglong Xie if (rs) {
37190b9a8bSChanglong Xie QLIST_REMOVE(rs, node);
38190b9a8bSChanglong Xie g_free(rs);
39190b9a8bSChanglong Xie }
40190b9a8bSChanglong Xie }
41190b9a8bSChanglong Xie
42190b9a8bSChanglong Xie /*
43190b9a8bSChanglong Xie * The caller of the function MUST make sure vm stopped
44190b9a8bSChanglong Xie */
replication_start_all(ReplicationMode mode,Error ** errp)45190b9a8bSChanglong Xie void replication_start_all(ReplicationMode mode, Error **errp)
46190b9a8bSChanglong Xie {
47190b9a8bSChanglong Xie ReplicationState *rs, *next;
48190b9a8bSChanglong Xie Error *local_err = NULL;
49190b9a8bSChanglong Xie
50190b9a8bSChanglong Xie QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
51190b9a8bSChanglong Xie if (rs->ops && rs->ops->start) {
52190b9a8bSChanglong Xie rs->ops->start(rs, mode, &local_err);
53190b9a8bSChanglong Xie }
54190b9a8bSChanglong Xie if (local_err) {
55190b9a8bSChanglong Xie error_propagate(errp, local_err);
56190b9a8bSChanglong Xie return;
57190b9a8bSChanglong Xie }
58190b9a8bSChanglong Xie }
59190b9a8bSChanglong Xie }
60190b9a8bSChanglong Xie
replication_do_checkpoint_all(Error ** errp)61190b9a8bSChanglong Xie void replication_do_checkpoint_all(Error **errp)
62190b9a8bSChanglong Xie {
63190b9a8bSChanglong Xie ReplicationState *rs, *next;
64190b9a8bSChanglong Xie Error *local_err = NULL;
65190b9a8bSChanglong Xie
66190b9a8bSChanglong Xie QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
67190b9a8bSChanglong Xie if (rs->ops && rs->ops->checkpoint) {
68190b9a8bSChanglong Xie rs->ops->checkpoint(rs, &local_err);
69190b9a8bSChanglong Xie }
70190b9a8bSChanglong Xie if (local_err) {
71190b9a8bSChanglong Xie error_propagate(errp, local_err);
72190b9a8bSChanglong Xie return;
73190b9a8bSChanglong Xie }
74190b9a8bSChanglong Xie }
75190b9a8bSChanglong Xie }
76190b9a8bSChanglong Xie
replication_get_error_all(Error ** errp)77190b9a8bSChanglong Xie void replication_get_error_all(Error **errp)
78190b9a8bSChanglong Xie {
79190b9a8bSChanglong Xie ReplicationState *rs, *next;
80190b9a8bSChanglong Xie Error *local_err = NULL;
81190b9a8bSChanglong Xie
82190b9a8bSChanglong Xie QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
83190b9a8bSChanglong Xie if (rs->ops && rs->ops->get_error) {
84190b9a8bSChanglong Xie rs->ops->get_error(rs, &local_err);
85190b9a8bSChanglong Xie }
86190b9a8bSChanglong Xie if (local_err) {
87190b9a8bSChanglong Xie error_propagate(errp, local_err);
88190b9a8bSChanglong Xie return;
89190b9a8bSChanglong Xie }
90190b9a8bSChanglong Xie }
91190b9a8bSChanglong Xie }
92190b9a8bSChanglong Xie
replication_stop_all(bool failover,Error ** errp)93190b9a8bSChanglong Xie void replication_stop_all(bool failover, Error **errp)
94190b9a8bSChanglong Xie {
95190b9a8bSChanglong Xie ReplicationState *rs, *next;
96190b9a8bSChanglong Xie Error *local_err = NULL;
97190b9a8bSChanglong Xie
98190b9a8bSChanglong Xie QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
99190b9a8bSChanglong Xie if (rs->ops && rs->ops->stop) {
100190b9a8bSChanglong Xie rs->ops->stop(rs, failover, &local_err);
101190b9a8bSChanglong Xie }
102190b9a8bSChanglong Xie if (local_err) {
103190b9a8bSChanglong Xie error_propagate(errp, local_err);
104190b9a8bSChanglong Xie return;
105190b9a8bSChanglong Xie }
106190b9a8bSChanglong Xie }
107190b9a8bSChanglong Xie }
108