xref: /openbmc/qemu/replication.c (revision fc8c745d)
1 /*
2  * Replication filter
3  *
4  * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
5  * Copyright (c) 2016 Intel Corporation
6  * Copyright (c) 2016 FUJITSU LIMITED
7  *
8  * Author:
9  *   Changlong Xie <xiecl.fnst@cn.fujitsu.com>
10  *
11  * This work is licensed under the terms of the GNU GPL, version 2 or later.
12  * See the COPYING file in the top-level directory.
13  */
14 
15 #include "qemu/osdep.h"
16 #include "qapi/error.h"
17 #include "block/replication.h"
18 
19 static QLIST_HEAD(, ReplicationState) replication_states;
20 
21 ReplicationState *replication_new(void *opaque, ReplicationOps *ops)
22 {
23     ReplicationState *rs;
24 
25     assert(ops != NULL);
26     rs = g_new0(ReplicationState, 1);
27     rs->opaque = opaque;
28     rs->ops = ops;
29     QLIST_INSERT_HEAD(&replication_states, rs, node);
30 
31     return rs;
32 }
33 
34 void replication_remove(ReplicationState *rs)
35 {
36     if (rs) {
37         QLIST_REMOVE(rs, node);
38         g_free(rs);
39     }
40 }
41 
42 /*
43  * The caller of the function MUST make sure vm stopped
44  */
45 void replication_start_all(ReplicationMode mode, Error **errp)
46 {
47     ReplicationState *rs, *next;
48     Error *local_err = NULL;
49 
50     QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
51         if (rs->ops && rs->ops->start) {
52             rs->ops->start(rs, mode, &local_err);
53         }
54         if (local_err) {
55             error_propagate(errp, local_err);
56             return;
57         }
58     }
59 }
60 
61 void replication_do_checkpoint_all(Error **errp)
62 {
63     ReplicationState *rs, *next;
64     Error *local_err = NULL;
65 
66     QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
67         if (rs->ops && rs->ops->checkpoint) {
68             rs->ops->checkpoint(rs, &local_err);
69         }
70         if (local_err) {
71             error_propagate(errp, local_err);
72             return;
73         }
74     }
75 }
76 
77 void replication_get_error_all(Error **errp)
78 {
79     ReplicationState *rs, *next;
80     Error *local_err = NULL;
81 
82     QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
83         if (rs->ops && rs->ops->get_error) {
84             rs->ops->get_error(rs, &local_err);
85         }
86         if (local_err) {
87             error_propagate(errp, local_err);
88             return;
89         }
90     }
91 }
92 
93 void replication_stop_all(bool failover, Error **errp)
94 {
95     ReplicationState *rs, *next;
96     Error *local_err = NULL;
97 
98     QLIST_FOREACH_SAFE(rs, &replication_states, node, next) {
99         if (rs->ops && rs->ops->stop) {
100             rs->ops->stop(rs, failover, &local_err);
101         }
102         if (local_err) {
103             error_propagate(errp, local_err);
104             return;
105         }
106     }
107 }
108