]> git.proxmox.com Git - mirror_ovs.git/blame - ovsdb/raft-rpc.h
dist-docs: Include manpages generated from rST.
[mirror_ovs.git] / ovsdb / raft-rpc.h
CommitLineData
1b1d2e6d
BP
1/*
2 * Copyright (c) 2017, 2018 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef RAFT_RPC_H
18#define RAFT_RPC_H 1
19
20/* Data structures used internally by Raft implementation for JSON-RPC. */
21
22#include <stdbool.h>
23#include <stdint.h>
24#include "openvswitch/uuid.h"
25#include "raft.h"
26#include "raft-private.h"
27#include "sset.h"
28
29struct ds;
30
31#define RAFT_RPC_TYPES \
32 /* Hello RPC. */ \
33 RAFT_RPC(RAFT_RPC_HELLO_REQUEST, hello_request) \
34 \
35 /* AppendEntries RPC. */ \
36 RAFT_RPC(RAFT_RPC_APPEND_REQUEST, append_request) \
37 RAFT_RPC(RAFT_RPC_APPEND_REPLY, append_reply) \
38 \
39 /* RequestVote RPC. */ \
40 RAFT_RPC(RAFT_RPC_VOTE_REQUEST, vote_request) \
41 RAFT_RPC(RAFT_RPC_VOTE_REPLY, vote_reply) \
42 \
43 /* AddServer RPC. */ \
44 RAFT_RPC(RAFT_RPC_ADD_SERVER_REQUEST, add_server_request) \
45 RAFT_RPC(RAFT_RPC_ADD_SERVER_REPLY, add_server_reply) \
46 \
47 /* RemoveServer RPC. */ \
48 RAFT_RPC(RAFT_RPC_REMOVE_SERVER_REQUEST, remove_server_request) \
49 RAFT_RPC(RAFT_RPC_REMOVE_SERVER_REPLY, remove_server_reply) \
50 \
51 /* InstallSnapshot RPC. */ \
52 RAFT_RPC(RAFT_RPC_INSTALL_SNAPSHOT_REQUEST, install_snapshot_request) \
53 RAFT_RPC(RAFT_RPC_INSTALL_SNAPSHOT_REPLY, install_snapshot_reply) \
54 \
55 /* BecomeLeader RPC. */ \
56 RAFT_RPC(RAFT_RPC_BECOME_LEADER, become_leader) \
57 \
58 /* ExecuteCommand RPC. */ \
59 RAFT_RPC(RAFT_RPC_EXECUTE_COMMAND_REQUEST, execute_command_request) \
60 RAFT_RPC(RAFT_RPC_EXECUTE_COMMAND_REPLY, execute_command_reply)
61
62enum raft_rpc_type {
63#define RAFT_RPC(ENUM, NAME) ENUM,
64 RAFT_RPC_TYPES
65#undef RAFT_RPC
66};
67
68const char *raft_rpc_type_to_string(enum raft_rpc_type);
69bool raft_rpc_type_from_string(const char *, enum raft_rpc_type *);
70\f
71struct raft_rpc_common {
72 enum raft_rpc_type type; /* Message type. */
73 struct uuid sid; /* Peer server (source or destination). */
74 char *comment; /* Human-friendly additional text. */
75};
76
77struct raft_hello_request {
78 struct raft_rpc_common common;
79 char *address; /* Sender's address. */
80};
81
82struct raft_append_request {
83 struct raft_rpc_common common;
84 uint64_t term; /* Leader's term. */
85 uint64_t prev_log_index; /* Log entry just before new ones. */
86 uint64_t prev_log_term; /* Term of prev_log_index entry. */
87 uint64_t leader_commit; /* Leader's commit_index. */
88
89 /* The append request includes 0 or more log entries. entries[0] is for
90 * log entry 'prev_log_index + 1', and so on.
91 *
92 * A heartbeat append_request has no terms. */
93 struct raft_entry *entries;
94 unsigned int n_entries;
95};
96
97enum raft_append_result {
98 RAFT_APPEND_OK, /* Success. */
99 RAFT_APPEND_INCONSISTENCY, /* Failure due to log inconsistency. */
100 RAFT_APPEND_IO_ERROR, /* Failure due to I/O error. */
101};
102
103const char *raft_append_result_to_string(enum raft_append_result);
104bool raft_append_result_from_string(const char *, enum raft_append_result *);
105
106struct raft_append_reply {
107 struct raft_rpc_common common;
108
109 /* Copied from the state machine of the reply's sender. */
110 uint64_t term; /* Current term, for leader to update itself. */
111 uint64_t log_end; /* To allow capping next_index, see 4.2.1. */
112
113 /* Copied from request. */
114 uint64_t prev_log_index; /* Log entry just before new ones. */
115 uint64_t prev_log_term; /* Term of prev_log_index entry. */
116 unsigned int n_entries;
117
118 /* Result. */
119 enum raft_append_result result;
120};
121
122struct raft_vote_request {
123 struct raft_rpc_common common;
124 uint64_t term; /* Candidate's term. */
125 uint64_t last_log_index; /* Index of candidate's last log entry. */
126 uint64_t last_log_term; /* Term of candidate's last log entry. */
127 bool leadership_transfer; /* True to override minimum election timeout. */
128};
129
130struct raft_vote_reply {
131 struct raft_rpc_common common;
132 uint64_t term; /* Current term, for candidate to update itself. */
133 struct uuid vote; /* Server ID of vote. */
134};
135
136struct raft_add_server_request {
137 struct raft_rpc_common common;
138 char *address; /* Address of new server. */
139};
140
141struct raft_remove_server_request {
142 struct raft_rpc_common common;
143 struct uuid sid; /* Server to remove. */
144
145 /* Nonnull if request was received via unixctl. */
146 struct unixctl_conn *requester_conn;
147};
148
149/* The operation committed and is now complete. */
150#define RAFT_SERVER_COMPLETED "completed"
151
152/* The operation could not be initiated because this server is not the current
153 * leader. Only the leader can add or remove servers. */
154#define RAFT_SERVER_NOT_LEADER "not leader"
155
156/* An operation to add a server succeeded without any change because the server
157 * was already part of the cluster. */
158#define RAFT_SERVER_ALREADY_PRESENT "already in cluster"
159
160/* An operation to remove a server succeeded without any change because the
161 * server was not part of the cluster. */
162#define RAFT_SERVER_ALREADY_GONE "already not in cluster"
163
164/* The operation could not be initiated because an identical
165 * operation was already in progress. */
166#define RAFT_SERVER_IN_PROGRESS "in progress"
167
168/* Adding a server failed because of a timeout. This could mean that the
169 * server was entirely unreachable, or that it became unreachable partway
170 * through populating it with an initial copy of the log. In the latter case,
171 * retrying the operation should resume where it left off. */
172#define RAFT_SERVER_TIMEOUT "timeout"
173
174/* The operation was initiated but it later failed because this server lost
175 * cluster leadership. The operation may be retried against the new cluster
176 * leader. For adding a server, if the log was already partially copied to the
177 * new server, retrying the operation should resume where it left off. */
178#define RAFT_SERVER_LOST_LEADERSHIP "lost leadership"
179
180/* Adding a server was canceled by submission of an operation to remove the
181 * same server, or removing a server was canceled by submission of an operation
182 * to add the same server. */
183#define RAFT_SERVER_CANCELED "canceled"
184
185/* Adding or removing a server could not be initiated because the operation to
186 * remove or add the server, respectively, has been logged but not committed.
187 * The new operation may be retried once the former operation commits. */
188#define RAFT_SERVER_COMMITTING "committing"
189
190/* Adding or removing a server was canceled because the leader shut down. */
191#define RAFT_SERVER_SHUTDOWN "shutdown"
192
193/* Removing a server could not be initiated because, taken together with any
194 * other scheduled server removals, the cluster would be empty. (This
195 * calculation ignores scheduled or uncommitted add server operations because
196 * of the possibility that they could fail.) */
197#define RAFT_SERVER_EMPTY "empty"
198
199struct raft_add_server_reply {
200 struct raft_rpc_common common;
201 bool success;
202 struct sset remote_addresses;
203};
204
205struct raft_remove_server_reply {
206 struct raft_rpc_common common;
207 bool success;
17bd4149
BP
208
209 /* SID of the removed server, but all-zeros if it is the same as the
210 * destination of the RPC. (Older ovsdb-server did not have 'target_sid'
211 * and assumed that the destination was always the target, so by omitting
212 * 'target_sid' when this is the case we can preserve a small amount of
213 * inter-version compatibility.) */
214 struct uuid target_sid;
1b1d2e6d
BP
215};
216
217struct raft_install_snapshot_request {
218 struct raft_rpc_common common;
219
220 uint64_t term; /* Leader's term. */
221
222 uint64_t last_index; /* Covers everything up & including this. */
223 uint64_t last_term; /* Term of last_index. */
224 struct uuid last_eid; /* Last entry ID. */
225 struct json *last_servers;
8e354614 226 uint64_t election_timer;
1b1d2e6d
BP
227
228 /* Data. */
229 struct json *data;
230};
231
232struct raft_install_snapshot_reply {
233 struct raft_rpc_common common;
234
235 uint64_t term; /* For leader to update itself. */
236
237 /* Repeated from the install_snapshot request. */
238 uint64_t last_index;
239 uint64_t last_term;
240};
241
242struct raft_become_leader {
243 struct raft_rpc_common common;
244
245 uint64_t term; /* Leader's term. */
246};
247
248struct raft_execute_command_request {
249 struct raft_rpc_common common;
250
251 struct json *data;
252 struct uuid prereq;
253 struct uuid result;
254};
255
256struct raft_execute_command_reply {
257 struct raft_rpc_common common;
258
259 struct uuid result;
260 enum raft_command_status status;
261 uint64_t commit_index;
262};
263
264union raft_rpc {
265 enum raft_rpc_type type;
266 struct raft_rpc_common common;
267#define RAFT_RPC(ENUM, NAME) struct raft_##NAME NAME;
268 RAFT_RPC_TYPES
269#undef RAFT_RPC
270};
271
272#define RAFT_RPC(ENUM, NAME) \
273 static inline const struct raft_##NAME * \
274 raft_##NAME##_cast(const union raft_rpc *rpc) \
275 { \
276 ovs_assert(rpc->type == ENUM); \
277 return &rpc->NAME; \
278 }
279RAFT_RPC_TYPES
280#undef RAFT_RPC
281
282void raft_rpc_uninit(union raft_rpc *);
283union raft_rpc *raft_rpc_clone(const union raft_rpc *);
284
285struct jsonrpc_msg *raft_rpc_to_jsonrpc(const struct uuid *cid,
286 const struct uuid *sid,
287 const union raft_rpc *);
288struct ovsdb_error *raft_rpc_from_jsonrpc(struct uuid *cid,
289 const struct uuid *sid,
290 const struct jsonrpc_msg *,
291 union raft_rpc *)
292 OVS_WARN_UNUSED_RESULT;
293
294void raft_rpc_format(const union raft_rpc *, struct ds *);
295
296uint64_t raft_rpc_get_term(const union raft_rpc *);
297const struct uuid *raft_rpc_get_vote(const union raft_rpc *);
298uint64_t raft_rpc_get_min_sync_index(const union raft_rpc *);
299
300#endif /* lib/raft-rpc.h */