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 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 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 65 static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused))) 66 { 67 return 0; 68 } 69 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 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 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 109 static wsrep_status_t dummy_disconnect(wsrep_t* w) 110 { 111 WSREP_DBUG_ENTER(w); 112 return WSREP_OK; 113 } 114 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 285 static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w) 286 { 287 WSREP_DBUG_ENTER(w); 288 return dummy_stats; 289 } 290 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 298 static void dummy_stats_reset (wsrep_t* w) 299 { 300 WSREP_DBUG_ENTER(w); 301 } 302 303 static wsrep_seqno_t dummy_pause (wsrep_t* w) 304 { 305 WSREP_DBUG_ENTER(w); 306 return -ENOSYS; 307 } 308 309 static wsrep_status_t dummy_resume (wsrep_t* w) 310 { 311 WSREP_DBUG_ENTER(w); 312 return WSREP_OK; 313 } 314 315 static wsrep_status_t dummy_desync (wsrep_t* w) 316 { 317 WSREP_DBUG_ENTER(w); 318 return WSREP_NOT_IMPLEMENTED; 319 } 320 321 static wsrep_status_t dummy_resync (wsrep_t* w) 322 { 323 WSREP_DBUG_ENTER(w); 324 return WSREP_OK; 325 } 326 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 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 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 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