]> git.proxmox.com Git - mirror_ovs.git/blame - ovsdb/raft-rpc.h
stream: Allow timeout configuration for open_block.
[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;
226
227 /* Data. */
228 struct json *data;
229};
230
231struct raft_install_snapshot_reply {
232 struct raft_rpc_common common;
233
234 uint64_t term; /* For leader to update itself. */
235
236 /* Repeated from the install_snapshot request. */
237 uint64_t last_index;
238 uint64_t last_term;
239};
240
241struct raft_become_leader {
242 struct raft_rpc_common common;
243
244 uint64_t term; /* Leader's term. */
245};
246
247struct raft_execute_command_request {
248 struct raft_rpc_common common;
249
250 struct json *data;
251 struct uuid prereq;
252 struct uuid result;
253};
254
255struct raft_execute_command_reply {
256 struct raft_rpc_common common;
257
258 struct uuid result;
259 enum raft_command_status status;
260 uint64_t commit_index;
261};
262
263union raft_rpc {
264 enum raft_rpc_type type;
265 struct raft_rpc_common common;
266#define RAFT_RPC(ENUM, NAME) struct raft_##NAME NAME;
267 RAFT_RPC_TYPES
268#undef RAFT_RPC
269};
270
271#define RAFT_RPC(ENUM, NAME) \
272 static inline const struct raft_##NAME * \
273 raft_##NAME##_cast(const union raft_rpc *rpc) \
274 { \
275 ovs_assert(rpc->type == ENUM); \
276 return &rpc->NAME; \
277 }
278RAFT_RPC_TYPES
279#undef RAFT_RPC
280
281void raft_rpc_uninit(union raft_rpc *);
282union raft_rpc *raft_rpc_clone(const union raft_rpc *);
283
284struct jsonrpc_msg *raft_rpc_to_jsonrpc(const struct uuid *cid,
285 const struct uuid *sid,
286 const union raft_rpc *);
287struct ovsdb_error *raft_rpc_from_jsonrpc(struct uuid *cid,
288 const struct uuid *sid,
289 const struct jsonrpc_msg *,
290 union raft_rpc *)
291 OVS_WARN_UNUSED_RESULT;
292
293void raft_rpc_format(const union raft_rpc *, struct ds *);
294
295uint64_t raft_rpc_get_term(const union raft_rpc *);
296const struct uuid *raft_rpc_get_vote(const union raft_rpc *);
297uint64_t raft_rpc_get_min_sync_index(const union raft_rpc *);
298
299#endif /* lib/raft-rpc.h */