Skip to content

Commit 190b9a8

Browse files
Changlong XiestefanhaRH
Changlong Xie
authored andcommitted
replication: Introduce new APIs to do replication operation
This commit introduces six replication interfaces(for block, network etc). Firstly we can use replication_(new/remove) to create/destroy replication instances, then in migration we can use replication_(start/stop/do_checkpoint /get_error)_all to handle all replication operations. More detail please refer to replication.h Signed-off-by: Wen Congyang <[email protected]> Signed-off-by: Changlong Xie <[email protected]> Signed-off-by: Wang WeiWei <[email protected]> Signed-off-by: zhanghailiang <[email protected]> Signed-off-by: Gonglei <[email protected]> Message-id: [email protected] Signed-off-by: Stefan Hajnoczi <[email protected]>
1 parent a6b1d4c commit 190b9a8

File tree

4 files changed

+295
-0
lines changed

4 files changed

+295
-0
lines changed

Makefile.objs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
1515
block-obj-$(CONFIG_WIN32) += aio-win32.o
1616
block-obj-y += block/
1717
block-obj-y += qemu-io-cmds.o
18+
block-obj-$(CONFIG_REPLICATION) += replication.o
1819

1920
block-obj-m = block/
2021

qapi/block-core.json

+13
Original file line numberDiff line numberDiff line change
@@ -2162,6 +2162,19 @@
21622162
'server': ['GlusterServer'],
21632163
'*debug-level': 'int' } }
21642164

2165+
##
2166+
# @ReplicationMode
2167+
#
2168+
# An enumeration of replication modes.
2169+
#
2170+
# @primary: Primary mode, the vm's state will be sent to secondary QEMU.
2171+
#
2172+
# @secondary: Secondary mode, receive the vm's state from primary QEMU.
2173+
#
2174+
# Since: 2.8
2175+
##
2176+
{ 'enum' : 'ReplicationMode', 'data' : [ 'primary', 'secondary' ] }
2177+
21652178
##
21662179
# @BlockdevOptions
21672180
#

replication.c

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
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 <[email protected]>
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 "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+
}

replication.h

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
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 <[email protected]>
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 */

0 commit comments

Comments
 (0)