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