1 | /* Copyright (C) 2009-2010 Codership Oy <info@codersihp.com> |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA |
15 | */ |
16 | |
17 | /*! @file Dummy wsrep API implementation. */ |
18 | |
19 | #include "wsrep_api.h" |
20 | |
21 | #include <errno.h> |
22 | #include <string.h> |
23 | |
24 | /*! Dummy backend context. */ |
25 | typedef struct wsrep_dummy |
26 | { |
27 | wsrep_log_cb_t log_fn; |
28 | char* options; |
29 | } wsrep_dummy_t; |
30 | |
31 | /* Get pointer to wsrep_dummy context from wsrep_t pointer */ |
32 | #define WSREP_DUMMY(_p) ((wsrep_dummy_t *) (_p)->ctx) |
33 | |
34 | /* Trace function usage a-la DBUG */ |
35 | #define WSREP_DBUG_ENTER(_w) do { \ |
36 | if (WSREP_DUMMY(_w)) { \ |
37 | if (WSREP_DUMMY(_w)->log_fn) \ |
38 | WSREP_DUMMY(_w)->log_fn(WSREP_LOG_DEBUG, __FUNCTION__); \ |
39 | } \ |
40 | } while (0) |
41 | |
42 | |
43 | static void dummy_free(wsrep_t *w) |
44 | { |
45 | WSREP_DBUG_ENTER(w); |
46 | if (WSREP_DUMMY(w)->options) { |
47 | free(WSREP_DUMMY(w)->options); |
48 | WSREP_DUMMY(w)->options = NULL; |
49 | } |
50 | free(w->ctx); |
51 | w->ctx = NULL; |
52 | } |
53 | |
54 | static wsrep_status_t dummy_init (wsrep_t* w, |
55 | const struct wsrep_init_args* args) |
56 | { |
57 | WSREP_DUMMY(w)->log_fn = args->logger_cb; |
58 | WSREP_DBUG_ENTER(w); |
59 | if (args->options) { |
60 | WSREP_DUMMY(w)->options = strdup(args->options); |
61 | } |
62 | return WSREP_OK; |
63 | } |
64 | |
65 | static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused))) |
66 | { |
67 | return 0; |
68 | } |
69 | |
70 | static wsrep_status_t dummy_options_set( |
71 | wsrep_t* w, |
72 | const char* conf) |
73 | { |
74 | WSREP_DBUG_ENTER(w); |
75 | if (WSREP_DUMMY(w)->options) { |
76 | free(WSREP_DUMMY(w)->options); |
77 | WSREP_DUMMY(w)->options = NULL; |
78 | } |
79 | if (conf) { |
80 | WSREP_DUMMY(w)->options = strdup(conf); |
81 | } |
82 | return WSREP_OK; |
83 | } |
84 | |
85 | static char* dummy_options_get (wsrep_t* w) |
86 | { |
87 | char *options; |
88 | |
89 | WSREP_DBUG_ENTER(w); |
90 | options= WSREP_DUMMY(w)->options; |
91 | |
92 | if (options) |
93 | options= strdup(WSREP_DUMMY(w)->options); |
94 | |
95 | return options; |
96 | } |
97 | |
98 | static wsrep_status_t dummy_connect( |
99 | wsrep_t* w, |
100 | const char* name __attribute__((unused)), |
101 | const char* url __attribute__((unused)), |
102 | const char* donor __attribute__((unused)), |
103 | wsrep_bool_t bootstrap __attribute__((unused))) |
104 | { |
105 | WSREP_DBUG_ENTER(w); |
106 | return WSREP_OK; |
107 | } |
108 | |
109 | static wsrep_status_t dummy_disconnect(wsrep_t* w) |
110 | { |
111 | WSREP_DBUG_ENTER(w); |
112 | return WSREP_OK; |
113 | } |
114 | |
115 | static wsrep_status_t dummy_recv(wsrep_t* w, |
116 | void* recv_ctx __attribute__((unused))) |
117 | { |
118 | WSREP_DBUG_ENTER(w); |
119 | return WSREP_OK; |
120 | } |
121 | |
122 | static wsrep_status_t dummy_pre_commit( |
123 | wsrep_t* w, |
124 | const wsrep_conn_id_t conn_id __attribute__((unused)), |
125 | wsrep_ws_handle_t* ws_handle __attribute__((unused)), |
126 | uint32_t flags __attribute__((unused)), |
127 | wsrep_trx_meta_t* meta __attribute__((unused))) |
128 | { |
129 | WSREP_DBUG_ENTER(w); |
130 | return WSREP_OK; |
131 | } |
132 | |
133 | static wsrep_status_t dummy_post_commit( |
134 | wsrep_t* w, |
135 | wsrep_ws_handle_t* ws_handle __attribute__((unused))) |
136 | { |
137 | WSREP_DBUG_ENTER(w); |
138 | return WSREP_OK; |
139 | } |
140 | |
141 | static wsrep_status_t dummy_post_rollback( |
142 | wsrep_t* w, |
143 | wsrep_ws_handle_t* ws_handle __attribute__((unused))) |
144 | { |
145 | WSREP_DBUG_ENTER(w); |
146 | return WSREP_OK; |
147 | } |
148 | |
149 | static wsrep_status_t dummy_replay_trx( |
150 | wsrep_t* w, |
151 | wsrep_ws_handle_t* ws_handle __attribute__((unused)), |
152 | void* trx_ctx __attribute__((unused))) |
153 | { |
154 | WSREP_DBUG_ENTER(w); |
155 | return WSREP_OK; |
156 | } |
157 | |
158 | static wsrep_status_t dummy_abort_pre_commit( |
159 | wsrep_t* w, |
160 | const wsrep_seqno_t bf_seqno __attribute__((unused)), |
161 | const wsrep_trx_id_t trx_id __attribute__((unused))) |
162 | { |
163 | WSREP_DBUG_ENTER(w); |
164 | return WSREP_OK; |
165 | } |
166 | |
167 | static wsrep_status_t dummy_append_key( |
168 | wsrep_t* w, |
169 | wsrep_ws_handle_t* ws_handle __attribute__((unused)), |
170 | const wsrep_key_t* key __attribute__((unused)), |
171 | const size_t key_num __attribute__((unused)), |
172 | const wsrep_key_type_t key_type __attribute__((unused)), |
173 | const wsrep_bool_t copy __attribute__((unused))) |
174 | { |
175 | WSREP_DBUG_ENTER(w); |
176 | return WSREP_OK; |
177 | } |
178 | |
179 | static wsrep_status_t dummy_append_data( |
180 | wsrep_t* w, |
181 | wsrep_ws_handle_t* ws_handle __attribute__((unused)), |
182 | const struct wsrep_buf* data __attribute__((unused)), |
183 | const size_t count __attribute__((unused)), |
184 | const wsrep_data_type_t type __attribute__((unused)), |
185 | const wsrep_bool_t copy __attribute__((unused))) |
186 | { |
187 | WSREP_DBUG_ENTER(w); |
188 | return WSREP_OK; |
189 | } |
190 | |
191 | static wsrep_status_t dummy_causal_read( |
192 | wsrep_t* w, |
193 | wsrep_gtid_t* gtid __attribute__((unused))) |
194 | { |
195 | WSREP_DBUG_ENTER(w); |
196 | return WSREP_OK; |
197 | } |
198 | |
199 | static wsrep_status_t dummy_free_connection( |
200 | wsrep_t* w, |
201 | const wsrep_conn_id_t conn_id __attribute__((unused))) |
202 | { |
203 | WSREP_DBUG_ENTER(w); |
204 | return WSREP_OK; |
205 | } |
206 | |
207 | static wsrep_status_t dummy_to_execute_start( |
208 | wsrep_t* w, |
209 | const wsrep_conn_id_t conn_id __attribute__((unused)), |
210 | const wsrep_key_t* key __attribute__((unused)), |
211 | const size_t key_num __attribute__((unused)), |
212 | const struct wsrep_buf* data __attribute__((unused)), |
213 | const size_t count __attribute__((unused)), |
214 | wsrep_trx_meta_t* meta __attribute__((unused))) |
215 | { |
216 | WSREP_DBUG_ENTER(w); |
217 | return WSREP_OK; |
218 | } |
219 | |
220 | static wsrep_status_t dummy_to_execute_end( |
221 | wsrep_t* w, |
222 | const wsrep_conn_id_t conn_id __attribute__((unused))) |
223 | { |
224 | WSREP_DBUG_ENTER(w); |
225 | return WSREP_OK; |
226 | } |
227 | |
228 | static wsrep_status_t dummy_preordered_collect( |
229 | wsrep_t* w, |
230 | wsrep_po_handle_t* handle __attribute__((unused)), |
231 | const struct wsrep_buf* data __attribute__((unused)), |
232 | size_t count __attribute__((unused)), |
233 | wsrep_bool_t copy __attribute__((unused))) |
234 | { |
235 | WSREP_DBUG_ENTER(w); |
236 | return WSREP_OK; |
237 | } |
238 | |
239 | static wsrep_status_t dummy_preordered_commit( |
240 | wsrep_t* w, |
241 | wsrep_po_handle_t* handle __attribute__((unused)), |
242 | const wsrep_uuid_t* source_id __attribute__((unused)), |
243 | uint32_t flags __attribute__((unused)), |
244 | int pa_range __attribute__((unused)), |
245 | wsrep_bool_t commit __attribute__((unused))) |
246 | { |
247 | WSREP_DBUG_ENTER(w); |
248 | return WSREP_OK; |
249 | } |
250 | |
251 | static wsrep_status_t dummy_sst_sent( |
252 | wsrep_t* w, |
253 | const wsrep_gtid_t* state_id __attribute__((unused)), |
254 | const int rcode __attribute__((unused))) |
255 | { |
256 | WSREP_DBUG_ENTER(w); |
257 | return WSREP_OK; |
258 | } |
259 | |
260 | static wsrep_status_t dummy_sst_received( |
261 | wsrep_t* w, |
262 | const wsrep_gtid_t* state_id __attribute__((unused)), |
263 | const void* state __attribute__((unused)), |
264 | const size_t state_len __attribute__((unused)), |
265 | const int rcode __attribute__((unused))) |
266 | { |
267 | WSREP_DBUG_ENTER(w); |
268 | return WSREP_OK; |
269 | } |
270 | |
271 | static wsrep_status_t dummy_snapshot( |
272 | wsrep_t* w, |
273 | const void* msg __attribute__((unused)), |
274 | const size_t msg_len __attribute__((unused)), |
275 | const char* donor_spec __attribute__((unused))) |
276 | { |
277 | WSREP_DBUG_ENTER(w); |
278 | return WSREP_OK; |
279 | } |
280 | |
281 | static struct wsrep_stats_var dummy_stats[] = { |
282 | { NULL, WSREP_VAR_STRING, { 0 } } |
283 | }; |
284 | |
285 | static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w) |
286 | { |
287 | WSREP_DBUG_ENTER(w); |
288 | return dummy_stats; |
289 | } |
290 | |
291 | static void dummy_stats_free ( |
292 | wsrep_t* w, |
293 | struct wsrep_stats_var* stats __attribute__((unused))) |
294 | { |
295 | WSREP_DBUG_ENTER(w); |
296 | } |
297 | |
298 | static void dummy_stats_reset (wsrep_t* w) |
299 | { |
300 | WSREP_DBUG_ENTER(w); |
301 | } |
302 | |
303 | static wsrep_seqno_t dummy_pause (wsrep_t* w) |
304 | { |
305 | WSREP_DBUG_ENTER(w); |
306 | return -ENOSYS; |
307 | } |
308 | |
309 | static wsrep_status_t dummy_resume (wsrep_t* w) |
310 | { |
311 | WSREP_DBUG_ENTER(w); |
312 | return WSREP_OK; |
313 | } |
314 | |
315 | static wsrep_status_t dummy_desync (wsrep_t* w) |
316 | { |
317 | WSREP_DBUG_ENTER(w); |
318 | return WSREP_NOT_IMPLEMENTED; |
319 | } |
320 | |
321 | static wsrep_status_t dummy_resync (wsrep_t* w) |
322 | { |
323 | WSREP_DBUG_ENTER(w); |
324 | return WSREP_OK; |
325 | } |
326 | |
327 | static wsrep_status_t dummy_lock (wsrep_t* w, |
328 | const char* s __attribute__((unused)), |
329 | wsrep_bool_t r __attribute__((unused)), |
330 | uint64_t o __attribute__((unused)), |
331 | int64_t t __attribute__((unused))) |
332 | { |
333 | WSREP_DBUG_ENTER(w); |
334 | return WSREP_NOT_IMPLEMENTED; |
335 | } |
336 | |
337 | static wsrep_status_t dummy_unlock (wsrep_t* w, |
338 | const char* s __attribute__((unused)), |
339 | uint64_t o __attribute__((unused))) |
340 | { |
341 | WSREP_DBUG_ENTER(w); |
342 | return WSREP_OK; |
343 | } |
344 | |
345 | static wsrep_bool_t dummy_is_locked (wsrep_t* w, |
346 | const char* s __attribute__((unused)), |
347 | uint64_t* o __attribute__((unused)), |
348 | wsrep_uuid_t* t __attribute__((unused))) |
349 | { |
350 | WSREP_DBUG_ENTER(w); |
351 | return 0; |
352 | } |
353 | |
354 | static wsrep_t dummy_iface = { |
355 | WSREP_INTERFACE_VERSION, |
356 | &dummy_init, |
357 | &dummy_capabilities, |
358 | &dummy_options_set, |
359 | &dummy_options_get, |
360 | &dummy_connect, |
361 | &dummy_disconnect, |
362 | &dummy_recv, |
363 | &dummy_pre_commit, |
364 | &dummy_post_commit, |
365 | &dummy_post_rollback, |
366 | &dummy_replay_trx, |
367 | &dummy_abort_pre_commit, |
368 | &dummy_append_key, |
369 | &dummy_append_data, |
370 | &dummy_causal_read, |
371 | &dummy_free_connection, |
372 | &dummy_to_execute_start, |
373 | &dummy_to_execute_end, |
374 | &dummy_preordered_collect, |
375 | &dummy_preordered_commit, |
376 | &dummy_sst_sent, |
377 | &dummy_sst_received, |
378 | &dummy_snapshot, |
379 | &dummy_stats_get, |
380 | &dummy_stats_free, |
381 | &dummy_stats_reset, |
382 | &dummy_pause, |
383 | &dummy_resume, |
384 | &dummy_desync, |
385 | &dummy_resync, |
386 | &dummy_lock, |
387 | &dummy_unlock, |
388 | &dummy_is_locked, |
389 | WSREP_NONE, |
390 | WSREP_INTERFACE_VERSION, |
391 | "Codership Oy <info@codership.com>" , |
392 | &dummy_free, |
393 | NULL, |
394 | NULL |
395 | }; |
396 | |
397 | int wsrep_dummy_loader(wsrep_t* w) |
398 | { |
399 | if (!w) |
400 | return EINVAL; |
401 | |
402 | *w = dummy_iface; |
403 | |
404 | // allocate private context |
405 | if (!(w->ctx = malloc(sizeof(wsrep_dummy_t)))) |
406 | return ENOMEM; |
407 | |
408 | // initialize private context |
409 | WSREP_DUMMY(w)->log_fn = NULL; |
410 | WSREP_DUMMY(w)->options = NULL; |
411 | |
412 | return 0; |
413 | } |
414 | |