xref: /openbmc/qemu/include/block/replication.h (revision 2e1cacfb)
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 #ifndef REPLICATION_H
16 #define REPLICATION_H
17 
18 #include "qapi/qapi-types-block-core.h"
19 #include "qemu/module.h"
20 #include "qemu/queue.h"
21 
22 typedef struct ReplicationOps ReplicationOps;
23 typedef struct ReplicationState ReplicationState;
24 
25 /**
26  * SECTION:block/replication.h
27  * @title:Base Replication System
28  * @short_description: interfaces for handling replication
29  *
30  * The Replication Model provides a framework for handling Replication
31  *
32  * <example>
33  *   <title>How to use replication interfaces</title>
34  *   <programlisting>
35  * #include "block/replication.h"
36  *
37  * typedef struct BDRVReplicationState {
38  *     ReplicationState *rs;
39  * } BDRVReplicationState;
40  *
41  * static void replication_start(ReplicationState *rs, ReplicationMode mode,
42  *                               Error **errp);
43  * static void replication_do_checkpoint(ReplicationState *rs, Error **errp);
44  * static void replication_get_error(ReplicationState *rs, Error **errp);
45  * static void replication_stop(ReplicationState *rs, bool failover,
46  *                              Error **errp);
47  *
48  * static ReplicationOps replication_ops = {
49  *     .start = replication_start,
50  *     .checkpoint = replication_do_checkpoint,
51  *     .get_error = replication_get_error,
52  *     .stop = replication_stop,
53  * }
54  *
55  * static int replication_open(BlockDriverState *bs, QDict *options,
56  *                             int flags, Error **errp)
57  * {
58  *     BDRVReplicationState *s = bs->opaque;
59  *     s->rs = replication_new(bs, &replication_ops);
60  *     return 0;
61  * }
62  *
63  * static void replication_close(BlockDriverState *bs)
64  * {
65  *     BDRVReplicationState *s = bs->opaque;
66  *     replication_remove(s->rs);
67  * }
68  *
69  * BlockDriver bdrv_replication = {
70  *     .format_name                = "replication",
71  *     .instance_size              = sizeof(BDRVReplicationState),
72  *
73  *     .bdrv_open                  = replication_open,
74  *     .bdrv_close                 = replication_close,
75  * };
76  *
77  * static void bdrv_replication_init(void)
78  * {
79  *     bdrv_register(&bdrv_replication);
80  * }
81  *
82  * block_init(bdrv_replication_init);
83  *   </programlisting>
84  * </example>
85  *
86  * We create an example about how to use replication interfaces in above.
87  * Then in migration, we can use replication_(start/stop/do_checkpoint/
88  * get_error)_all to handle all replication operations.
89  */
90 
91 /**
92  * ReplicationState:
93  * @opaque: opaque pointer value passed to this ReplicationState
94  * @ops: replication operation of this ReplicationState
95  * @node: node that we will insert into @replication_states QLIST
96  */
97 struct ReplicationState {
98     void *opaque;
99     ReplicationOps *ops;
100     QLIST_ENTRY(ReplicationState) node;
101 };
102 
103 /**
104  * ReplicationOps:
105  * @start: callback to start replication
106  * @stop: callback to stop replication
107  * @checkpoint: callback to do checkpoint
108  * @get_error: callback to check if error occurred during replication
109  */
110 struct ReplicationOps {
111     void (*start)(ReplicationState *rs, ReplicationMode mode, Error **errp);
112     void (*stop)(ReplicationState *rs, bool failover, Error **errp);
113     void (*checkpoint)(ReplicationState *rs, Error **errp);
114     void (*get_error)(ReplicationState *rs, Error **errp);
115 };
116 
117 /**
118  * replication_new:
119  * @opaque: opaque pointer value passed to ReplicationState
120  * @ops: replication operation of the new relevant ReplicationState
121  *
122  * Called to create a new ReplicationState instance, and then insert it
123  * into @replication_states QLIST
124  *
125  * Returns: the new ReplicationState instance
126  */
127 ReplicationState *replication_new(void *opaque, ReplicationOps *ops);
128 
129 /**
130  * replication_remove:
131  * @rs: the ReplicationState instance to remove
132  *
133  * Called to remove a ReplicationState instance, and then delete it from
134  * @replication_states QLIST
135  */
136 void replication_remove(ReplicationState *rs);
137 
138 /**
139  * replication_start_all:
140  * @mode: replication mode that could be "primary" or "secondary"
141  * @errp: returns an error if this function fails
142  *
143  * Start replication, called in migration/checkpoint thread
144  *
145  * Note: the caller of the function MUST make sure vm stopped
146  */
147 void replication_start_all(ReplicationMode mode, Error **errp);
148 
149 /**
150  * replication_do_checkpoint_all:
151  * @errp: returns an error if this function fails
152  *
153  * This interface is called after all VM state is transferred to Secondary QEMU
154  */
155 void replication_do_checkpoint_all(Error **errp);
156 
157 /**
158  * replication_get_error_all:
159  * @errp: returns an error if this function fails
160  *
161  * This interface is called to check if error occurred during replication
162  */
163 void replication_get_error_all(Error **errp);
164 
165 /**
166  * replication_stop_all:
167  * @failover: boolean value that indicates if we need do failover or not
168  * @errp: returns an error if this function fails
169  *
170  * It is called on failover. The vm should be stopped before calling it, if you
171  * use this API to shutdown the guest, or other things except failover
172  */
173 void replication_stop_all(bool failover, Error **errp);
174 
175 #endif /* REPLICATION_H */
176