Commit f2837a3b authored by Seppo Jaakola's avatar Seppo Jaakola

remerging wsrep files from lp:codership-mysql

parent e0c6a87b
# Copyright (c) 2012, Codership Oy. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
INCLUDE_DIRECTORIES( "." )
SET(WSREP_SOURCES wsrep_uuid.c wsrep_loader.c wsrep_dummy.c)
ADD_CONVENIENCE_LIBRARY(wsrep ${WSREP_SOURCES})
DTRACE_INSTRUMENT(wsrep)
#ADD_EXECUTABLE(listener wsrep_listener.c ${WSREP_SOURCES})
#TARGET_LINK_LIBRARIES(listener ${LIBDL})
noinst_LIBRARIES = libwsrep.a
libwsrep_a_SOURCES = wsrep_api.h wsrep_loader.c wsrep_dummy.c wsrep_uuid.c
This diff is collapsed.
/* Copyright (C) 2009-2010 Codership Oy <info@codersihp.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*! @file Dummy wsrep API implementation. */
#include <errno.h>
#include "wsrep_api.h"
/*! Dummy backend context. */
typedef struct wsrep_dummy
{
wsrep_log_cb_t log_fn;
} wsrep_dummy_t;
/* Get pointer to wsrep_dummy context from wsrep_t pointer */
#define WSREP_DUMMY(_p) ((wsrep_dummy_t *) (_p)->ctx)
/* Trace function usage a-la DBUG */
#define WSREP_DBUG_ENTER(_w) do { \
if (WSREP_DUMMY(_w)) { \
if (WSREP_DUMMY(_w)->log_fn) \
WSREP_DUMMY(_w)->log_fn(WSREP_LOG_DEBUG, __FUNCTION__); \
} \
} while (0)
static void dummy_free(wsrep_t *w)
{
WSREP_DBUG_ENTER(w);
free(w->ctx);
w->ctx = NULL;
}
static wsrep_status_t dummy_init (wsrep_t* w,
const struct wsrep_init_args* args)
{
WSREP_DUMMY(w)->log_fn = args->logger_cb;
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static uint64_t dummy_capabilities (wsrep_t* w __attribute__((unused)))
{
return 0;
}
static wsrep_status_t dummy_options_set(
wsrep_t* w,
const char* conf __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static char* dummy_options_get (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return NULL;
}
static wsrep_status_t dummy_connect(
wsrep_t* w,
const char* name __attribute__((unused)),
const char* url __attribute__((unused)),
const char* donor __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_disconnect(wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_recv(wsrep_t* w,
void* recv_ctx __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_pre_commit(
wsrep_t* w,
const wsrep_conn_id_t conn_id __attribute__((unused)),
wsrep_trx_handle_t* trx_handle __attribute__((unused)),
const void* query __attribute__((unused)),
const size_t query_len __attribute__((unused)),
uint64_t flags __attribute__((unused)),
wsrep_seqno_t* seqno __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_post_commit(
wsrep_t* w,
wsrep_trx_handle_t* trx_handle __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_post_rollback(
wsrep_t* w,
wsrep_trx_handle_t* trx_handle __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_replay_trx(
wsrep_t* w,
wsrep_trx_handle_t* trx_handle __attribute__((unused)),
void* trx_ctx __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_abort_pre_commit(
wsrep_t* w,
const wsrep_seqno_t bf_seqno __attribute__((unused)),
const wsrep_trx_id_t trx_id __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_append_query(
wsrep_t* w,
wsrep_trx_handle_t* trx_handle __attribute__((unused)),
const char* query __attribute__((unused)),
const time_t timeval __attribute__((unused)),
const uint32_t randseed __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_append_row_key(
wsrep_t* w,
wsrep_trx_handle_t* trx_handle __attribute__((unused)),
const wsrep_key_t* key __attribute__((unused)),
const size_t key_len __attribute__((unused)),
const bool shared __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_append_data(
wsrep_t* w,
wsrep_trx_handle_t* trx_handle __attribute__((unused)),
const void* data __attribute__((unused)),
size_t data_len __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_causal_read(
wsrep_t* w,
wsrep_seqno_t* seqno __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_free_connection(
wsrep_t* w,
const wsrep_conn_id_t conn_id __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_to_execute_start(
wsrep_t* w,
const wsrep_conn_id_t conn_id __attribute__((unused)),
const wsrep_key_t* key __attribute__((unused)),
const size_t key_len __attribute__((unused)),
const void* query __attribute__((unused)),
const size_t query_len __attribute__((unused)),
wsrep_seqno_t* seqno __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_to_execute_end(
wsrep_t* w,
const wsrep_conn_id_t conn_id __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_sst_sent(
wsrep_t* w,
const wsrep_uuid_t* uuid __attribute__((unused)),
wsrep_seqno_t seqno __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_sst_received(
wsrep_t* w,
const wsrep_uuid_t* uuid __attribute__((unused)),
const wsrep_seqno_t seqno __attribute__((unused)),
const char* state __attribute__((unused)),
const size_t state_len __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_snapshot(
wsrep_t* w,
const void* msg __attribute__((unused)),
const size_t msg_len __attribute__((unused)),
const char* donor_spec __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static struct wsrep_stats_var dummy_stats[] = {
{ NULL, WSREP_VAR_STRING, { 0 } }
};
static struct wsrep_stats_var* dummy_stats_get (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return dummy_stats;
}
static void dummy_stats_free (
wsrep_t* w,
struct wsrep_stats_var* stats __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
}
static wsrep_seqno_t dummy_pause (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return -ENOSYS;
}
static wsrep_status_t dummy_resume (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_desync (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return WSREP_NOT_IMPLEMENTED;
}
static wsrep_status_t dummy_resync (wsrep_t* w)
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static wsrep_status_t dummy_lock (wsrep_t* w,
const char* s __attribute__((unused)),
int64_t o __attribute__((unused)),
int64_t t __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_NOT_IMPLEMENTED;
}
static wsrep_status_t dummy_unlock (wsrep_t* w,
const char* s __attribute__((unused)),
int64_t o __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return WSREP_OK;
}
static bool dummy_is_locked (wsrep_t* w,
const char* s __attribute__((unused)),
int64_t* o __attribute__((unused)),
wsrep_uuid_t* t __attribute__((unused)))
{
WSREP_DBUG_ENTER(w);
return false;
}
static wsrep_t dummy_iface = {
WSREP_INTERFACE_VERSION,
&dummy_init,
&dummy_capabilities,
&dummy_options_set,
&dummy_options_get,
&dummy_connect,
&dummy_disconnect,
&dummy_recv,
&dummy_pre_commit,
&dummy_post_commit,
&dummy_post_rollback,
&dummy_replay_trx,
&dummy_abort_pre_commit,
&dummy_append_query,
&dummy_append_row_key,
&dummy_append_data,
&dummy_causal_read,
&dummy_free_connection,
&dummy_to_execute_start,
&dummy_to_execute_end,
&dummy_sst_sent,
&dummy_sst_received,
&dummy_snapshot,
&dummy_stats_get,
&dummy_stats_free,
&dummy_pause,
&dummy_resume,
&dummy_desync,
&dummy_resync,
&dummy_lock,
&dummy_unlock,
&dummy_is_locked,
WSREP_NONE,
WSREP_INTERFACE_VERSION,
"Codership Oy <info@codership.com>",
&dummy_free,
NULL,
NULL
};
int wsrep_dummy_loader(wsrep_t* w)
{
if (!w)
return EINVAL;
*w = dummy_iface;
// allocate private context
if (!(w->ctx = malloc(sizeof(wsrep_dummy_t))))
return ENOMEM;
// initialize private context
WSREP_DUMMY(w)->log_fn = NULL;
return 0;
}
/* Copyright (C) 2009-2011 Codership Oy <info@codersihp.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*! @file wsrep implementation loader */
#include <dlfcn.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "wsrep_api.h"
// Logging stuff for the loader
static const char* log_levels[] = {"FATAL", "ERROR", "WARN", "INFO", "DEBUG"};
static void default_logger (wsrep_log_level_t lvl, const char* msg)
{
fprintf (stderr, "wsrep loader: [%s] %s\n", log_levels[lvl], msg);
}
static wsrep_log_cb_t logger = default_logger;
/**************************************************************************
* Library loader
**************************************************************************/
static int verify(const wsrep_t *wh, const char *iface_ver)
{
const size_t msg_len = 128;
char msg[msg_len];
#define VERIFY(_p) if (!(_p)) { \
snprintf(msg, msg_len, "wsrep_load(): verify(): %s\n", # _p); \
logger (WSREP_LOG_ERROR, msg); \
return EINVAL; \
}
VERIFY(wh);
VERIFY(wh->version);
if (strcmp(wh->version, iface_ver)) {
snprintf (msg, msg_len,
"provider interface version mismatch: need '%s', found '%s'",
iface_ver, wh->version);
logger (WSREP_LOG_ERROR, msg);
return EINVAL;
}
VERIFY(wh->init);
VERIFY(wh->options_set);
VERIFY(wh->options_get);
VERIFY(wh->connect);
VERIFY(wh->disconnect);
VERIFY(wh->recv);
VERIFY(wh->pre_commit);
VERIFY(wh->post_commit);
VERIFY(wh->post_rollback);
VERIFY(wh->replay_trx);
VERIFY(wh->abort_pre_commit);
VERIFY(wh->append_query);
VERIFY(wh->append_key);
VERIFY(wh->free_connection);
VERIFY(wh->to_execute_start);
VERIFY(wh->to_execute_end);
VERIFY(wh->sst_sent);
VERIFY(wh->sst_received);
VERIFY(wh->stats_get);
VERIFY(wh->stats_free);
VERIFY(wh->pause);
VERIFY(wh->resume);
VERIFY(wh->desync);
VERIFY(wh->resync);
VERIFY(wh->lock);
VERIFY(wh->unlock);
VERIFY(wh->is_locked);
VERIFY(wh->provider_name);
VERIFY(wh->provider_version);
VERIFY(wh->provider_vendor);
VERIFY(wh->free);
return 0;
}
static wsrep_loader_fun wsrep_dlf(void *dlh, const char *sym)
{
union {
wsrep_loader_fun dlfun;
void *obj;
} alias;
alias.obj = dlsym(dlh, sym);
return alias.dlfun;
}
extern int wsrep_dummy_loader(wsrep_t *w);
int wsrep_load(const char *spec, wsrep_t **hptr, wsrep_log_cb_t log_cb)
{
int ret = 0;
void *dlh = NULL;
wsrep_loader_fun dlfun;
const size_t msg_len = 1024;
char msg[msg_len + 1];
msg[msg_len] = 0;
if (NULL != log_cb)
logger = log_cb;
if (!(spec && hptr))
return EINVAL;
snprintf (msg, msg_len,
"wsrep_load(): loading provider library '%s'", spec);
logger (WSREP_LOG_INFO, msg);
if (!(*hptr = malloc(sizeof(wsrep_t)))) {
logger (WSREP_LOG_FATAL, "wsrep_load(): out of memory");
return ENOMEM;
}
if (!spec || strcmp(spec, WSREP_NONE) == 0) {
if ((ret = wsrep_dummy_loader(*hptr)) != 0) {
free (*hptr);
*hptr = NULL;
}
return ret;
}
if (!(dlh = dlopen(spec, RTLD_NOW | RTLD_LOCAL))) {
snprintf(msg, msg_len, "wsrep_load(): dlopen(): %s", dlerror());
logger (WSREP_LOG_ERROR, msg);
ret = EINVAL;
goto out;
}
if (!(dlfun = wsrep_dlf(dlh, "wsrep_loader"))) {
ret = EINVAL;
goto out;
}
if ((ret = (*dlfun)(*hptr)) != 0) {
snprintf(msg, msg_len, "wsrep_load(): loader failed: %s",
strerror(ret));
logger (WSREP_LOG_ERROR, msg);
goto out;
}
if ((ret = verify(*hptr, WSREP_INTERFACE_VERSION)) != 0) {
snprintf (msg, msg_len,
"wsrep_load(): interface version mismatch: my version %s, "
"provider version %s", WSREP_INTERFACE_VERSION,
(*hptr)->version);
logger (WSREP_LOG_ERROR, msg);
goto out;
}
(*hptr)->dlh = dlh;
out:
if (ret != 0) {
if (dlh) dlclose(dlh);
free(*hptr);
*hptr = NULL;
} else {
snprintf (msg, msg_len,
"wsrep_load(): %s %s by %s loaded succesfully.",
(*hptr)->provider_name, (*hptr)->provider_version,
(*hptr)->provider_vendor);
logger (WSREP_LOG_INFO, msg);
}
return ret;
}
void wsrep_unload(wsrep_t *hptr)
{
if (!hptr) {
logger (WSREP_LOG_WARN, "wsrep_unload(): null pointer.");
} else {
if (hptr->free)
hptr->free(hptr);
if (hptr->dlh)
dlclose(hptr->dlh);
free(hptr);
}
}
/* Copyright (C) 2009 Codership Oy <info@codersihp.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*! @file Helper functions to deal with history UUID string representations */
#include <errno.h>
#include <ctype.h>
#include <stdio.h>
#include "wsrep_api.h"
/*!
* Read UUID from string
* @return length of UUID string representation or -EINVAL in case of error
*/
ssize_t
wsrep_uuid_scan (const char* str, size_t str_len, wsrep_uuid_t* uuid)
{
size_t uuid_len = 0;
size_t uuid_offt = 0;
while (uuid_len + 1 < str_len) {
if ((4 == uuid_offt || 6 == uuid_offt || 8 == uuid_offt ||
10 == uuid_offt) && str[uuid_len] == '-') {
// skip dashes after 4th, 6th, 8th and 10th positions
uuid_len += 1;
continue;
}
if (isxdigit(str[uuid_len]) && isxdigit(str[uuid_len + 1])) {
// got hex digit
sscanf (str + uuid_len, "%2hhx", uuid->uuid + uuid_offt);
uuid_len += 2;
uuid_offt += 1;
if (sizeof (uuid->uuid) == uuid_offt)
return uuid_len;
}
else {
break;
}
}
*uuid = WSREP_UUID_UNDEFINED;
return -EINVAL;
}
/*!
* Write UUID to string
* @return length of UUID string representation or -EMSGSIZE if string is too
* short
*/
ssize_t
wsrep_uuid_print (const wsrep_uuid_t* uuid, char* str, size_t str_len)
{
if (str_len > 36) {
const unsigned char* u = uuid->uuid;
return snprintf(str, str_len, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
"%02x%02x-%02x%02x%02x%02x%02x%02x",
u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15]);
}
else {
return -EMSGSIZE;
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment