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