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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 */
16
17 /*! @file Dummy wsrep API implementation. */
18
19 #include "wsrep_api.h"
20
21 #include <errno.h>
22 #include <stdbool.h>
23 #include <string.h>
24
25 /*! Dummy backend context. */
26 typedef struct wsrep_dummy
27 {
28 wsrep_log_cb_t log_fn;
29 char* options;
30 } wsrep_dummy_t;
31
32 /* Get pointer to wsrep_dummy context from wsrep_t pointer */
33 #define WSREP_DUMMY(_p) ((wsrep_dummy_t *) (_p)->ctx)
34
35 /* Trace function usage a-la DBUG */
36 #define WSREP_DBUG_ENTER(_w) do { \
37 if (WSREP_DUMMY(_w)) { \
38 if (WSREP_DUMMY(_w)->log_fn) \
39 WSREP_DUMMY(_w)->log_fn(WSREP_LOG_DEBUG, __FUNCTION__); \
40 } \
41 } while (0)
42
43
dummy_free(wsrep_t * w)44 static void dummy_free(wsrep_t *w)
45 {
46 if (!w->ctx) return;
47
48 WSREP_DBUG_ENTER(w);
49 if (WSREP_DUMMY(w)->options) {
50 free(WSREP_DUMMY(w)->options);
51 WSREP_DUMMY(w)->options = NULL;
52 }
53 free(w->ctx);
54 w->ctx = NULL;
55 }
56
dummy_init(wsrep_t * w,const struct wsrep_init_args * args)57 static wsrep_status_t dummy_init (wsrep_t* w,
58 const struct wsrep_init_args* args)
59 {
60 WSREP_DUMMY(w)->log_fn = args->logger_cb;
61 WSREP_DBUG_ENTER(w);
62 if (args->options) {
63 WSREP_DUMMY(w)->options = strdup(args->options);
64 }
65 return WSREP_OK;
66 }
67
dummy_capabilities(wsrep_t * w)68 static wsrep_cap_t dummy_capabilities (wsrep_t* w __attribute__((unused)))
69 {
70 return 0;
71 }
72
dummy_options_set(wsrep_t * w,const char * conf)73 static wsrep_status_t dummy_options_set(
74 wsrep_t* w,
75 const char* conf)
76 {
77 WSREP_DBUG_ENTER(w);
78 if (WSREP_DUMMY(w)->options) {
79 free(WSREP_DUMMY(w)->options);
80 WSREP_DUMMY(w)->options = NULL;
81 }
82 if (conf) {
83 WSREP_DUMMY(w)->options = strdup(conf);
84 }
85 return WSREP_OK;
86 }
87
dummy_options_get(wsrep_t * w)88 static char* dummy_options_get (wsrep_t* w)
89 {
90 WSREP_DBUG_ENTER(w);
91 return strdup(WSREP_DUMMY(w)->options);
92 }
93
dummy_enc_set_key(wsrep_t * w,const wsrep_enc_key_t * key)94 static wsrep_status_t dummy_enc_set_key(
95 wsrep_t* w,
96 const wsrep_enc_key_t* key __attribute__((unused)))
97 {
98 WSREP_DBUG_ENTER(w);
99 return WSREP_OK;
100 }
101
dummy_connect(wsrep_t * w,const char * name,const char * url,const char * donor,wsrep_bool_t bootstrap)102 static wsrep_status_t dummy_connect(
103 wsrep_t* w,
104 const char* name __attribute__((unused)),
105 const char* url __attribute__((unused)),
106 const char* donor __attribute__((unused)),
107 wsrep_bool_t bootstrap __attribute__((unused)))
108 {
109 WSREP_DBUG_ENTER(w);
110 return WSREP_OK;
111 }
112
dummy_disconnect(wsrep_t * w)113 static wsrep_status_t dummy_disconnect(wsrep_t* w)
114 {
115 WSREP_DBUG_ENTER(w);
116 return WSREP_OK;
117 }
118
dummy_recv(wsrep_t * w,void * recv_ctx)119 static wsrep_status_t dummy_recv(wsrep_t* w,
120 void* recv_ctx __attribute__((unused)))
121 {
122 WSREP_DBUG_ENTER(w);
123 return WSREP_OK;
124 }
125
dummy_assign_read_view(wsrep_t * w,wsrep_ws_handle_t * ws_handle,const wsrep_gtid_t * rv)126 static wsrep_status_t dummy_assign_read_view(
127 wsrep_t* w,
128 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
129 const wsrep_gtid_t* rv __attribute__((unused)))
130 {
131 WSREP_DBUG_ENTER(w);
132 return WSREP_OK;
133 }
134
dummy_certify(wsrep_t * w,const wsrep_conn_id_t conn_id,wsrep_ws_handle_t * ws_handle,uint32_t flags,wsrep_trx_meta_t * meta)135 static wsrep_status_t dummy_certify(
136 wsrep_t* w,
137 const wsrep_conn_id_t conn_id __attribute__((unused)),
138 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
139 uint32_t flags __attribute__((unused)),
140 wsrep_trx_meta_t* meta __attribute__((unused)))
141 {
142 WSREP_DBUG_ENTER(w);
143 return WSREP_OK;
144 }
145
dummy_commit_order_enter(wsrep_t * w,const wsrep_ws_handle_t * ws_handle,const wsrep_trx_meta_t * meta)146 static wsrep_status_t dummy_commit_order_enter(
147 wsrep_t* w,
148 const wsrep_ws_handle_t* ws_handle __attribute__((unused)),
149 const wsrep_trx_meta_t* meta __attribute__((unused)))
150 {
151 WSREP_DBUG_ENTER(w);
152 return WSREP_OK;
153 }
154
dummy_commit_order_leave(wsrep_t * w,const wsrep_ws_handle_t * ws_handle,const wsrep_trx_meta_t * meta,const wsrep_buf_t * error)155 static wsrep_status_t dummy_commit_order_leave(
156 wsrep_t* w,
157 const wsrep_ws_handle_t* ws_handle __attribute__((unused)),
158 const wsrep_trx_meta_t* meta __attribute__((unused)),
159 const wsrep_buf_t* error __attribute__((unused)))
160 {
161 WSREP_DBUG_ENTER(w);
162 return WSREP_OK;
163 }
164
dummy_release(wsrep_t * w,wsrep_ws_handle_t * ws_handle)165 static wsrep_status_t dummy_release(
166 wsrep_t* w,
167 wsrep_ws_handle_t* ws_handle __attribute__((unused)))
168 {
169 WSREP_DBUG_ENTER(w);
170 return WSREP_OK;
171 }
172
dummy_replay_trx(wsrep_t * w,const wsrep_ws_handle_t * ws_handle,void * trx_ctx)173 static wsrep_status_t dummy_replay_trx(
174 wsrep_t* w,
175 const wsrep_ws_handle_t* ws_handle __attribute__((unused)),
176 void* trx_ctx __attribute__((unused)))
177 {
178 WSREP_DBUG_ENTER(w);
179 return WSREP_OK;
180 }
181
dummy_abort_certification(wsrep_t * w,const wsrep_seqno_t bf_seqno,const wsrep_trx_id_t trx_id,wsrep_seqno_t * victim_seqno)182 static wsrep_status_t dummy_abort_certification(
183 wsrep_t* w,
184 const wsrep_seqno_t bf_seqno __attribute__((unused)),
185 const wsrep_trx_id_t trx_id __attribute__((unused)),
186 wsrep_seqno_t *victim_seqno __attribute__((unused)))
187 {
188 WSREP_DBUG_ENTER(w);
189 return WSREP_OK;
190 }
191
dummy_rollback(wsrep_t * w,const wsrep_trx_id_t trx,const wsrep_buf_t * data)192 static wsrep_status_t dummy_rollback(
193 wsrep_t* w,
194 const wsrep_trx_id_t trx __attribute__((unused)),
195 const wsrep_buf_t* data __attribute__((unused)))
196 {
197 WSREP_DBUG_ENTER(w);
198 return WSREP_OK;
199 }
200
dummy_append_key(wsrep_t * w,wsrep_ws_handle_t * ws_handle,const wsrep_key_t * key,const size_t key_num,const wsrep_key_type_t key_type,const bool copy)201 static wsrep_status_t dummy_append_key(
202 wsrep_t* w,
203 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
204 const wsrep_key_t* key __attribute__((unused)),
205 const size_t key_num __attribute__((unused)),
206 const wsrep_key_type_t key_type __attribute__((unused)),
207 const bool copy __attribute__((unused)))
208 {
209 WSREP_DBUG_ENTER(w);
210 return WSREP_OK;
211 }
212
dummy_append_data(wsrep_t * w,wsrep_ws_handle_t * ws_handle,const struct wsrep_buf * data,const size_t count,const wsrep_data_type_t type,const bool copy)213 static wsrep_status_t dummy_append_data(
214 wsrep_t* w,
215 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
216 const struct wsrep_buf* data __attribute__((unused)),
217 const size_t count __attribute__((unused)),
218 const wsrep_data_type_t type __attribute__((unused)),
219 const bool copy __attribute__((unused)))
220 {
221 WSREP_DBUG_ENTER(w);
222 return WSREP_OK;
223 }
224
dummy_sync_wait(wsrep_t * w,wsrep_gtid_t * upto,int tout,wsrep_gtid_t * gtid)225 static wsrep_status_t dummy_sync_wait(
226 wsrep_t* w,
227 wsrep_gtid_t* upto __attribute__((unused)),
228 int tout __attribute__((unused)),
229 wsrep_gtid_t* gtid __attribute__((unused)))
230 {
231 WSREP_DBUG_ENTER(w);
232 return WSREP_OK;
233 }
234
dummy_last_committed_id(wsrep_t * w,wsrep_gtid_t * gtid)235 static wsrep_status_t dummy_last_committed_id(
236 wsrep_t* w,
237 wsrep_gtid_t* gtid __attribute__((unused)))
238 {
239 WSREP_DBUG_ENTER(w);
240 return WSREP_OK;
241 }
242
dummy_free_connection(wsrep_t * w,const wsrep_conn_id_t conn_id)243 static wsrep_status_t dummy_free_connection(
244 wsrep_t* w,
245 const wsrep_conn_id_t conn_id __attribute__((unused)))
246 {
247 WSREP_DBUG_ENTER(w);
248 return WSREP_OK;
249 }
250
dummy_to_execute_start(wsrep_t * w,const wsrep_conn_id_t conn_id,const wsrep_key_t * key,const size_t key_num,const struct wsrep_buf * data,const size_t count,const uint32_t flags,wsrep_trx_meta_t * meta)251 static wsrep_status_t dummy_to_execute_start(
252 wsrep_t* w,
253 const wsrep_conn_id_t conn_id __attribute__((unused)),
254 const wsrep_key_t* key __attribute__((unused)),
255 const size_t key_num __attribute__((unused)),
256 const struct wsrep_buf* data __attribute__((unused)),
257 const size_t count __attribute__((unused)),
258 const uint32_t flags __attribute__((unused)),
259 wsrep_trx_meta_t* meta __attribute__((unused)))
260 {
261 WSREP_DBUG_ENTER(w);
262 return WSREP_OK;
263 }
264
dummy_to_execute_end(wsrep_t * w,const wsrep_conn_id_t conn_id,const wsrep_buf_t * err)265 static wsrep_status_t dummy_to_execute_end(
266 wsrep_t* w,
267 const wsrep_conn_id_t conn_id __attribute__((unused)),
268 const wsrep_buf_t* err __attribute__((unused)))
269 {
270 WSREP_DBUG_ENTER(w);
271 return WSREP_OK;
272 }
273
dummy_preordered_collect(wsrep_t * w,wsrep_po_handle_t * handle,const struct wsrep_buf * data,size_t count,wsrep_bool_t copy)274 static wsrep_status_t dummy_preordered_collect(
275 wsrep_t* w,
276 wsrep_po_handle_t* handle __attribute__((unused)),
277 const struct wsrep_buf* data __attribute__((unused)),
278 size_t count __attribute__((unused)),
279 wsrep_bool_t copy __attribute__((unused)))
280 {
281 WSREP_DBUG_ENTER(w);
282 return WSREP_OK;
283 }
284
dummy_preordered_commit(wsrep_t * w,wsrep_po_handle_t * handle,const wsrep_uuid_t * source_id,uint32_t flags,int pa_range,wsrep_bool_t commit)285 static wsrep_status_t dummy_preordered_commit(
286 wsrep_t* w,
287 wsrep_po_handle_t* handle __attribute__((unused)),
288 const wsrep_uuid_t* source_id __attribute__((unused)),
289 uint32_t flags __attribute__((unused)),
290 int pa_range __attribute__((unused)),
291 wsrep_bool_t commit __attribute__((unused)))
292 {
293 WSREP_DBUG_ENTER(w);
294 return WSREP_OK;
295 }
296
dummy_sst_sent(wsrep_t * w,const wsrep_gtid_t * state_id,const int rcode)297 static wsrep_status_t dummy_sst_sent(
298 wsrep_t* w,
299 const wsrep_gtid_t* state_id __attribute__((unused)),
300 const int rcode __attribute__((unused)))
301 {
302 WSREP_DBUG_ENTER(w);
303 return WSREP_OK;
304 }
305
dummy_sst_received(wsrep_t * w,const wsrep_gtid_t * state_id,const wsrep_buf_t * state,const int rcode)306 static wsrep_status_t dummy_sst_received(
307 wsrep_t* w,
308 const wsrep_gtid_t* state_id __attribute__((unused)),
309 const wsrep_buf_t* state __attribute__((unused)),
310 const int rcode __attribute__((unused)))
311 {
312 WSREP_DBUG_ENTER(w);
313 return WSREP_OK;
314 }
315
dummy_snapshot(wsrep_t * w,const wsrep_buf_t * msg,const char * donor_spec)316 static wsrep_status_t dummy_snapshot(
317 wsrep_t* w,
318 const wsrep_buf_t* msg __attribute__((unused)),
319 const char* donor_spec __attribute__((unused)))
320 {
321 WSREP_DBUG_ENTER(w);
322 return WSREP_OK;
323 }
324
325 static struct wsrep_stats_var dummy_stats[] = {
326 { NULL, WSREP_VAR_STRING, { 0 } }
327 };
328
dummy_stats_get(wsrep_t * w)329 static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w)
330 {
331 WSREP_DBUG_ENTER(w);
332 return dummy_stats;
333 }
334
dummy_stats_free(wsrep_t * w,struct wsrep_stats_var * stats)335 static void dummy_stats_free (
336 wsrep_t* w,
337 struct wsrep_stats_var* stats __attribute__((unused)))
338 {
339 WSREP_DBUG_ENTER(w);
340 }
341
dummy_stats_reset(wsrep_t * w)342 static void dummy_stats_reset (wsrep_t* w)
343 {
344 WSREP_DBUG_ENTER(w);
345 }
346
dummy_pause(wsrep_t * w)347 static wsrep_seqno_t dummy_pause (wsrep_t* w)
348 {
349 WSREP_DBUG_ENTER(w);
350 return -ENOSYS;
351 }
352
dummy_resume(wsrep_t * w)353 static wsrep_status_t dummy_resume (wsrep_t* w)
354 {
355 WSREP_DBUG_ENTER(w);
356 return WSREP_OK;
357 }
358
dummy_desync(wsrep_t * w)359 static wsrep_status_t dummy_desync (wsrep_t* w)
360 {
361 WSREP_DBUG_ENTER(w);
362 return WSREP_NOT_IMPLEMENTED;
363 }
364
dummy_resync(wsrep_t * w)365 static wsrep_status_t dummy_resync (wsrep_t* w)
366 {
367 WSREP_DBUG_ENTER(w);
368 return WSREP_OK;
369 }
370
dummy_lock(wsrep_t * w,const char * s,bool r,uint64_t o,int64_t t)371 static wsrep_status_t dummy_lock (wsrep_t* w,
372 const char* s __attribute__((unused)),
373 bool r __attribute__((unused)),
374 uint64_t o __attribute__((unused)),
375 int64_t t __attribute__((unused)))
376 {
377 WSREP_DBUG_ENTER(w);
378 return WSREP_NOT_IMPLEMENTED;
379 }
380
dummy_unlock(wsrep_t * w,const char * s,uint64_t o)381 static wsrep_status_t dummy_unlock (wsrep_t* w,
382 const char* s __attribute__((unused)),
383 uint64_t o __attribute__((unused)))
384 {
385 WSREP_DBUG_ENTER(w);
386 return WSREP_OK;
387 }
388
dummy_is_locked(wsrep_t * w,const char * s,uint64_t * o,wsrep_uuid_t * t)389 static bool dummy_is_locked (wsrep_t* w,
390 const char* s __attribute__((unused)),
391 uint64_t* o __attribute__((unused)),
392 wsrep_uuid_t* t __attribute__((unused)))
393 {
394 WSREP_DBUG_ENTER(w);
395 return false;
396 }
397
398 static wsrep_t dummy_iface = {
399 WSREP_INTERFACE_VERSION,
400 &dummy_init,
401 &dummy_capabilities,
402 &dummy_options_set,
403 &dummy_options_get,
404 &dummy_enc_set_key,
405 &dummy_connect,
406 &dummy_disconnect,
407 &dummy_recv,
408 &dummy_assign_read_view,
409 &dummy_certify,
410 &dummy_commit_order_enter,
411 &dummy_commit_order_leave,
412 &dummy_release,
413 &dummy_replay_trx,
414 &dummy_abort_certification,
415 &dummy_rollback,
416 &dummy_append_key,
417 &dummy_append_data,
418 &dummy_sync_wait,
419 &dummy_last_committed_id,
420 &dummy_free_connection,
421 &dummy_to_execute_start,
422 &dummy_to_execute_end,
423 &dummy_preordered_collect,
424 &dummy_preordered_commit,
425 &dummy_sst_sent,
426 &dummy_sst_received,
427 &dummy_snapshot,
428 &dummy_stats_get,
429 &dummy_stats_free,
430 &dummy_stats_reset,
431 &dummy_pause,
432 &dummy_resume,
433 &dummy_desync,
434 &dummy_resync,
435 &dummy_lock,
436 &dummy_unlock,
437 &dummy_is_locked,
438 WSREP_NONE,
439 WSREP_INTERFACE_VERSION,
440 "Codership Oy <info@codership.com>",
441 &dummy_free,
442 NULL,
443 NULL
444 };
445
wsrep_dummy_loader(wsrep_t * w)446 int wsrep_dummy_loader(wsrep_t* w)
447 {
448 if (!w)
449 return EINVAL;
450
451 *w = dummy_iface;
452
453 // allocate private context
454 if (!(w->ctx = malloc(sizeof(wsrep_dummy_t))))
455 return ENOMEM;
456
457 // initialize private context
458 WSREP_DUMMY(w)->log_fn = NULL;
459 WSREP_DUMMY(w)->options = NULL;
460
461 return 0;
462 }
463