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 WSREP_DBUG_ENTER(w);
47 if (WSREP_DUMMY(w)->options) {
48 free(WSREP_DUMMY(w)->options);
49 WSREP_DUMMY(w)->options = NULL;
50 }
51 free(w->ctx);
52 w->ctx = NULL;
53 }
54
dummy_init(wsrep_t * w,const struct wsrep_init_args * args)55 static wsrep_status_t dummy_init (wsrep_t* w,
56 const struct wsrep_init_args* args)
57 {
58 WSREP_DUMMY(w)->log_fn = args->logger_cb;
59 WSREP_DBUG_ENTER(w);
60 if (args->options) {
61 WSREP_DUMMY(w)->options = strdup(args->options);
62 }
63 return WSREP_OK;
64 }
65
dummy_capabilities(wsrep_t * w)66 static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused)))
67 {
68 return 0;
69 }
70
dummy_options_set(wsrep_t * w,const char * conf)71 static wsrep_status_t dummy_options_set(
72 wsrep_t* w,
73 const char* conf)
74 {
75 WSREP_DBUG_ENTER(w);
76 if (WSREP_DUMMY(w)->options) {
77 free(WSREP_DUMMY(w)->options);
78 WSREP_DUMMY(w)->options = NULL;
79 }
80 if (conf) {
81 WSREP_DUMMY(w)->options = strdup(conf);
82 }
83 return WSREP_OK;
84 }
85
dummy_options_get(wsrep_t * w)86 static char* dummy_options_get (wsrep_t* w)
87 {
88 WSREP_DBUG_ENTER(w);
89 return strdup(WSREP_DUMMY(w)->options);
90 }
91
dummy_connect(wsrep_t * w,const char * name,const char * url,const char * donor,wsrep_bool_t bootstrap)92 static wsrep_status_t dummy_connect(
93 wsrep_t* w,
94 const char* name __attribute__((unused)),
95 const char* url __attribute__((unused)),
96 const char* donor __attribute__((unused)),
97 wsrep_bool_t bootstrap __attribute__((unused)))
98 {
99 WSREP_DBUG_ENTER(w);
100 return WSREP_OK;
101 }
102
dummy_disconnect(wsrep_t * w)103 static wsrep_status_t dummy_disconnect(wsrep_t* w)
104 {
105 WSREP_DBUG_ENTER(w);
106 return WSREP_OK;
107 }
108
dummy_recv(wsrep_t * w,void * recv_ctx)109 static wsrep_status_t dummy_recv(wsrep_t* w,
110 void* recv_ctx __attribute__((unused)))
111 {
112 WSREP_DBUG_ENTER(w);
113 return WSREP_OK;
114 }
115
dummy_pre_commit(wsrep_t * w,const wsrep_conn_id_t conn_id,wsrep_ws_handle_t * ws_handle,uint32_t flags,wsrep_trx_meta_t * meta)116 static wsrep_status_t dummy_pre_commit(
117 wsrep_t* w,
118 const wsrep_conn_id_t conn_id __attribute__((unused)),
119 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
120 uint32_t flags __attribute__((unused)),
121 wsrep_trx_meta_t* meta __attribute__((unused)))
122 {
123 WSREP_DBUG_ENTER(w);
124 return WSREP_OK;
125 }
126
dummy_post_commit(wsrep_t * w,wsrep_ws_handle_t * ws_handle)127 static wsrep_status_t dummy_post_commit(
128 wsrep_t* w,
129 wsrep_ws_handle_t* ws_handle __attribute__((unused)))
130 {
131 WSREP_DBUG_ENTER(w);
132 return WSREP_OK;
133 }
134
dummy_post_rollback(wsrep_t * w,wsrep_ws_handle_t * ws_handle)135 static wsrep_status_t dummy_post_rollback(
136 wsrep_t* w,
137 wsrep_ws_handle_t* ws_handle __attribute__((unused)))
138 {
139 WSREP_DBUG_ENTER(w);
140 return WSREP_OK;
141 }
142
dummy_replay_trx(wsrep_t * w,wsrep_ws_handle_t * ws_handle,void * trx_ctx)143 static wsrep_status_t dummy_replay_trx(
144 wsrep_t* w,
145 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
146 void* trx_ctx __attribute__((unused)))
147 {
148 WSREP_DBUG_ENTER(w);
149 return WSREP_OK;
150 }
151
dummy_abort_pre_commit(wsrep_t * w,const wsrep_seqno_t bf_seqno,const wsrep_trx_id_t trx_id)152 static wsrep_status_t dummy_abort_pre_commit(
153 wsrep_t* w,
154 const wsrep_seqno_t bf_seqno __attribute__((unused)),
155 const wsrep_trx_id_t trx_id __attribute__((unused)))
156 {
157 WSREP_DBUG_ENTER(w);
158 return WSREP_OK;
159 }
160
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)161 static wsrep_status_t dummy_append_key(
162 wsrep_t* w,
163 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
164 const wsrep_key_t* key __attribute__((unused)),
165 const size_t key_num __attribute__((unused)),
166 const wsrep_key_type_t key_type __attribute__((unused)),
167 const bool copy __attribute__((unused)))
168 {
169 WSREP_DBUG_ENTER(w);
170 return WSREP_OK;
171 }
172
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)173 static wsrep_status_t dummy_append_data(
174 wsrep_t* w,
175 wsrep_ws_handle_t* ws_handle __attribute__((unused)),
176 const struct wsrep_buf* data __attribute__((unused)),
177 const size_t count __attribute__((unused)),
178 const wsrep_data_type_t type __attribute__((unused)),
179 const bool copy __attribute__((unused)))
180 {
181 WSREP_DBUG_ENTER(w);
182 return WSREP_OK;
183 }
184
dummy_causal_read(wsrep_t * w,wsrep_gtid_t * gtid)185 static wsrep_status_t dummy_causal_read(
186 wsrep_t* w,
187 wsrep_gtid_t* gtid __attribute__((unused)))
188 {
189 WSREP_DBUG_ENTER(w);
190 return WSREP_OK;
191 }
192
dummy_free_connection(wsrep_t * w,const wsrep_conn_id_t conn_id)193 static wsrep_status_t dummy_free_connection(
194 wsrep_t* w,
195 const wsrep_conn_id_t conn_id __attribute__((unused)))
196 {
197 WSREP_DBUG_ENTER(w);
198 return WSREP_OK;
199 }
200
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,wsrep_trx_meta_t * meta)201 static wsrep_status_t dummy_to_execute_start(
202 wsrep_t* w,
203 const wsrep_conn_id_t conn_id __attribute__((unused)),
204 const wsrep_key_t* key __attribute__((unused)),
205 const size_t key_num __attribute__((unused)),
206 const struct wsrep_buf* data __attribute__((unused)),
207 const size_t count __attribute__((unused)),
208 wsrep_trx_meta_t* meta __attribute__((unused)))
209 {
210 WSREP_DBUG_ENTER(w);
211 return WSREP_OK;
212 }
213
dummy_to_execute_end(wsrep_t * w,const wsrep_conn_id_t conn_id)214 static wsrep_status_t dummy_to_execute_end(
215 wsrep_t* w,
216 const wsrep_conn_id_t conn_id __attribute__((unused)))
217 {
218 WSREP_DBUG_ENTER(w);
219 return WSREP_OK;
220 }
221
dummy_preordered_collect(wsrep_t * w,wsrep_po_handle_t * handle,const struct wsrep_buf * data,size_t count,wsrep_bool_t copy)222 static wsrep_status_t dummy_preordered_collect(
223 wsrep_t* w,
224 wsrep_po_handle_t* handle __attribute__((unused)),
225 const struct wsrep_buf* data __attribute__((unused)),
226 size_t count __attribute__((unused)),
227 wsrep_bool_t copy __attribute__((unused)))
228 {
229 WSREP_DBUG_ENTER(w);
230 return WSREP_OK;
231 }
232
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)233 static wsrep_status_t dummy_preordered_commit(
234 wsrep_t* w,
235 wsrep_po_handle_t* handle __attribute__((unused)),
236 const wsrep_uuid_t* source_id __attribute__((unused)),
237 uint32_t flags __attribute__((unused)),
238 int pa_range __attribute__((unused)),
239 wsrep_bool_t commit __attribute__((unused)))
240 {
241 WSREP_DBUG_ENTER(w);
242 return WSREP_OK;
243 }
244
dummy_sst_sent(wsrep_t * w,const wsrep_gtid_t * state_id,const int rcode)245 static wsrep_status_t dummy_sst_sent(
246 wsrep_t* w,
247 const wsrep_gtid_t* state_id __attribute__((unused)),
248 const int rcode __attribute__((unused)))
249 {
250 WSREP_DBUG_ENTER(w);
251 return WSREP_OK;
252 }
253
dummy_sst_received(wsrep_t * w,const wsrep_gtid_t * state_id,const void * state,const size_t state_len,const int rcode)254 static wsrep_status_t dummy_sst_received(
255 wsrep_t* w,
256 const wsrep_gtid_t* state_id __attribute__((unused)),
257 const void* state __attribute__((unused)),
258 const size_t state_len __attribute__((unused)),
259 const int rcode __attribute__((unused)))
260 {
261 WSREP_DBUG_ENTER(w);
262 return WSREP_OK;
263 }
264
dummy_snapshot(wsrep_t * w,const void * msg,const size_t msg_len,const char * donor_spec)265 static wsrep_status_t dummy_snapshot(
266 wsrep_t* w,
267 const void* msg __attribute__((unused)),
268 const size_t msg_len __attribute__((unused)),
269 const char* donor_spec __attribute__((unused)))
270 {
271 WSREP_DBUG_ENTER(w);
272 return WSREP_OK;
273 }
274
275 static struct wsrep_stats_var dummy_stats[] = {
276 { NULL, WSREP_VAR_STRING, { 0 } }
277 };
278
dummy_stats_get(wsrep_t * w)279 static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w)
280 {
281 WSREP_DBUG_ENTER(w);
282 return dummy_stats;
283 }
284
dummy_stats_free(wsrep_t * w,struct wsrep_stats_var * stats)285 static void dummy_stats_free (
286 wsrep_t* w,
287 struct wsrep_stats_var* stats __attribute__((unused)))
288 {
289 WSREP_DBUG_ENTER(w);
290 }
291
dummy_stats_reset(wsrep_t * w)292 static void dummy_stats_reset (wsrep_t* w)
293 {
294 WSREP_DBUG_ENTER(w);
295 }
296
dummy_pause(wsrep_t * w)297 static wsrep_seqno_t dummy_pause (wsrep_t* w)
298 {
299 WSREP_DBUG_ENTER(w);
300 return -ENOSYS;
301 }
302
dummy_resume(wsrep_t * w)303 static wsrep_status_t dummy_resume (wsrep_t* w)
304 {
305 WSREP_DBUG_ENTER(w);
306 return WSREP_OK;
307 }
308
dummy_desync(wsrep_t * w)309 static wsrep_status_t dummy_desync (wsrep_t* w)
310 {
311 WSREP_DBUG_ENTER(w);
312 return WSREP_NOT_IMPLEMENTED;
313 }
314
dummy_resync(wsrep_t * w)315 static wsrep_status_t dummy_resync (wsrep_t* w)
316 {
317 WSREP_DBUG_ENTER(w);
318 return WSREP_OK;
319 }
320
dummy_lock(wsrep_t * w,const char * s,bool r,uint64_t o,int64_t t)321 static wsrep_status_t dummy_lock (wsrep_t* w,
322 const char* s __attribute__((unused)),
323 bool r __attribute__((unused)),
324 uint64_t o __attribute__((unused)),
325 int64_t t __attribute__((unused)))
326 {
327 WSREP_DBUG_ENTER(w);
328 return WSREP_NOT_IMPLEMENTED;
329 }
330
dummy_unlock(wsrep_t * w,const char * s,uint64_t o)331 static wsrep_status_t dummy_unlock (wsrep_t* w,
332 const char* s __attribute__((unused)),
333 uint64_t o __attribute__((unused)))
334 {
335 WSREP_DBUG_ENTER(w);
336 return WSREP_OK;
337 }
338
dummy_is_locked(wsrep_t * w,const char * s,uint64_t * o,wsrep_uuid_t * t)339 static bool dummy_is_locked (wsrep_t* w,
340 const char* s __attribute__((unused)),
341 uint64_t* o __attribute__((unused)),
342 wsrep_uuid_t* t __attribute__((unused)))
343 {
344 WSREP_DBUG_ENTER(w);
345 return false;
346 }
347
348 static wsrep_t dummy_iface = {
349 WSREP_INTERFACE_VERSION,
350 &dummy_init,
351 &dummy_capabilities,
352 &dummy_options_set,
353 &dummy_options_get,
354 &dummy_connect,
355 &dummy_disconnect,
356 &dummy_recv,
357 &dummy_pre_commit,
358 &dummy_post_commit,
359 &dummy_post_rollback,
360 &dummy_replay_trx,
361 &dummy_abort_pre_commit,
362 &dummy_append_key,
363 &dummy_append_data,
364 &dummy_causal_read,
365 &dummy_free_connection,
366 &dummy_to_execute_start,
367 &dummy_to_execute_end,
368 &dummy_preordered_collect,
369 &dummy_preordered_commit,
370 &dummy_sst_sent,
371 &dummy_sst_received,
372 &dummy_snapshot,
373 &dummy_stats_get,
374 &dummy_stats_free,
375 &dummy_stats_reset,
376 &dummy_pause,
377 &dummy_resume,
378 &dummy_desync,
379 &dummy_resync,
380 &dummy_lock,
381 &dummy_unlock,
382 &dummy_is_locked,
383 WSREP_NONE,
384 WSREP_INTERFACE_VERSION,
385 "Codership Oy <info@codership.com>",
386 &dummy_free,
387 NULL,
388 NULL
389 };
390
wsrep_dummy_loader(wsrep_t * w)391 int wsrep_dummy_loader(wsrep_t* w)
392 {
393 if (!w)
394 return EINVAL;
395
396 *w = dummy_iface;
397
398 // allocate private context
399 if (!(w->ctx = malloc(sizeof(wsrep_dummy_t))))
400 return ENOMEM;
401
402 // initialize private context
403 WSREP_DUMMY(w)->log_fn = NULL;
404 WSREP_DUMMY(w)->options = NULL;
405
406 return 0;
407 }
408