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 02110-1335 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 
dummy_free(wsrep_t * w)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 
dummy_init(wsrep_t * w,const struct wsrep_init_args * args)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 
dummy_capabilities(wsrep_t * w)65 static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused)))
66 {
67     return 0;
68 }
69 
dummy_options_set(wsrep_t * w,const char * conf)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 
dummy_options_get(wsrep_t * w)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 
dummy_connect(wsrep_t * w,const char * name,const char * url,const char * donor,wsrep_bool_t bootstrap)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 
dummy_disconnect(wsrep_t * w)109 static wsrep_status_t dummy_disconnect(wsrep_t* w)
110 {
111     WSREP_DBUG_ENTER(w);
112     return WSREP_OK;
113 }
114 
dummy_recv(wsrep_t * w,void * recv_ctx)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 
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)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 
dummy_post_commit(wsrep_t * w,wsrep_ws_handle_t * ws_handle)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 
dummy_post_rollback(wsrep_t * w,wsrep_ws_handle_t * ws_handle)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 
dummy_replay_trx(wsrep_t * w,wsrep_ws_handle_t * ws_handle,void * trx_ctx)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 
dummy_abort_pre_commit(wsrep_t * w,const wsrep_seqno_t bf_seqno,const wsrep_trx_id_t trx_id)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 
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 wsrep_bool_t copy)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 
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 wsrep_bool_t copy)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 
dummy_causal_read(wsrep_t * w,wsrep_gtid_t * gtid)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 
dummy_free_connection(wsrep_t * w,const wsrep_conn_id_t conn_id)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 
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)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 
dummy_to_execute_end(wsrep_t * w,const wsrep_conn_id_t conn_id)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 
dummy_preordered_collect(wsrep_t * w,wsrep_po_handle_t * handle,const struct wsrep_buf * data,size_t count,wsrep_bool_t copy)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 
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)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 
dummy_sst_sent(wsrep_t * w,const wsrep_gtid_t * state_id,const int rcode)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 
dummy_sst_received(wsrep_t * w,const wsrep_gtid_t * state_id,const void * state,const size_t state_len,const int rcode)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 
dummy_snapshot(wsrep_t * w,const void * msg,const size_t msg_len,const char * donor_spec)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 
dummy_stats_get(wsrep_t * w)285 static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w)
286 {
287     WSREP_DBUG_ENTER(w);
288     return dummy_stats;
289 }
290 
dummy_stats_free(wsrep_t * w,struct wsrep_stats_var * stats)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 
dummy_stats_reset(wsrep_t * w)298 static void dummy_stats_reset (wsrep_t* w)
299 {
300     WSREP_DBUG_ENTER(w);
301 }
302 
dummy_pause(wsrep_t * w)303 static wsrep_seqno_t dummy_pause (wsrep_t* w)
304 {
305     WSREP_DBUG_ENTER(w);
306     return -ENOSYS;
307 }
308 
dummy_resume(wsrep_t * w)309 static wsrep_status_t dummy_resume (wsrep_t* w)
310 {
311     WSREP_DBUG_ENTER(w);
312     return WSREP_OK;
313 }
314 
dummy_desync(wsrep_t * w)315 static wsrep_status_t dummy_desync (wsrep_t* w)
316 {
317     WSREP_DBUG_ENTER(w);
318     return WSREP_NOT_IMPLEMENTED;
319 }
320 
dummy_resync(wsrep_t * w)321 static wsrep_status_t dummy_resync (wsrep_t* w)
322 {
323     WSREP_DBUG_ENTER(w);
324     return WSREP_OK;
325 }
326 
dummy_lock(wsrep_t * w,const char * s,wsrep_bool_t r,uint64_t o,int64_t t)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 
dummy_unlock(wsrep_t * w,const char * s,uint64_t o)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 
dummy_is_locked(wsrep_t * w,const char * s,uint64_t * o,wsrep_uuid_t * t)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 
wsrep_dummy_loader(wsrep_t * w)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