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