Browse Source

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 <wency@cn.fujitsu.com>
Signed-off-by: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
Signed-off-by: Wang WeiWei <wangww.fnst@cn.fujitsu.com>
Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Message-id: 1469602913-20979-9-git-send-email-xiecl.fnst@cn.fujitsu.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
tags/v2.8.0-rc0
Changlong Xie 2 years ago
parent
commit
190b9a8b55
4 changed files with 295 additions and 0 deletions
  1. 1
    0
      Makefile.objs
  2. 13
    0
      qapi/block-core.json
  3. 107
    0
      replication.c
  4. 174
    0
      replication.h

+ 1
- 0
Makefile.objs View File

@@ -15,6 +15,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
15 15
 block-obj-$(CONFIG_WIN32) += aio-win32.o
16 16
 block-obj-y += block/
17 17
 block-obj-y += qemu-io-cmds.o
18
+block-obj-$(CONFIG_REPLICATION) += replication.o
18 19
 
19 20
 block-obj-m = block/
20 21
 

+ 13
- 0
qapi/block-core.json View File

@@ -2162,6 +2162,19 @@
2162 2162
             'server': ['GlusterServer'],
2163 2163
             '*debug-level': 'int' } }
2164 2164
 
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
+
2165 2178
 ##
2166 2179
 # @BlockdevOptions
2167 2180
 #

+ 107
- 0
replication.c View File

@@ -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 <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
+#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
+}

+ 174
- 0
replication.h View File

@@ -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 <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 */

Loading…
Cancel
Save