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
22typedef struct ReplicationOps ReplicationOps;
23typedef struct ReplicationState ReplicationState;
24
25/**
26 * SECTION: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 "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 */
97struct 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 */
110struct 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 */
127ReplicationState *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 */
136void 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 */
147void 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 */
155void 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 */
163void 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 */
173void replication_stop_all(bool failover, Error **errp);
174
175#endif /* REPLICATION_H */
176