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