Merge commit
This commit is contained in:
commit
748230a7bb
@ -1 +1,2 @@
|
||||
core/tags
|
||||
gateway
|
||||
|
@ -13,14 +13,21 @@
|
||||
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Copyright SkySQL Ab 2013
|
||||
#
|
||||
# Revision History
|
||||
# Date Who Description
|
||||
# 13/06/13 Mark Riddoch Addition of -rdynamic to allow libraries
|
||||
# to resolve symbols in the main executable
|
||||
|
||||
CC=cc
|
||||
CFLAGS=-c -I/usr/include -I../include
|
||||
LDFLAGS=-rdynamic
|
||||
SRCS= atomic.c buffer.c spinlock.c gateway.c gateway_mysql_protocol.c gw_utils.c \
|
||||
utils.c dcb.c
|
||||
utils.c dcb.c load_utils.c
|
||||
HDRS= ../include/atomic.h ../include/buffer.h ../include/dcb.h \
|
||||
../include/gateway_mysql.h ../include/gw.h ../include/mysql_protocol.h \
|
||||
../include/session.h ../include/spinlock.h ../include/thread.h
|
||||
../include/session.h ../include/spinlock.h ../include/thread.h \
|
||||
../include/modules.h
|
||||
OBJ=$(SRCS:.c=.o)
|
||||
LIBS=-lssl
|
||||
|
||||
|
237
core/load_utils.c
Normal file
237
core/load_utils.c
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2013
|
||||
*/
|
||||
|
||||
/*
|
||||
* load_utils.c Utility functions to aid the loading of dynamic modules
|
||||
* into the gateway
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 13/06/13 Mark Riddoch Initial implementation
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <modules.h>
|
||||
|
||||
static MODULES *registered = NULL;
|
||||
|
||||
static MODULES *find_module(const char *module);
|
||||
static void register_module(const char *module, const char *type, void *dlhandle, char *version, void *modobj);
|
||||
static void unregister_module(const char *module);
|
||||
|
||||
/*
|
||||
* Load the dynamic library related to a gateway module. The routine
|
||||
* will look for library files in the current directory,
|
||||
* $GATEWAY_HOME/modules and /usr/local/skysql/gateway/modules.
|
||||
*
|
||||
* @param module Name of the module to load
|
||||
* @param type Type of module, used purely for registration
|
||||
* @param entry Routine to call to extract entry points
|
||||
* @return The module specific entry point structure or NULL
|
||||
*/
|
||||
void *
|
||||
load_module(const char *module, const char *type, const char *entry)
|
||||
{
|
||||
char *home, *version;
|
||||
char fname[MAXPATHLEN];
|
||||
void *dlhandle, *sym;
|
||||
char *(*ver)();
|
||||
void *(*ep)(), *modobj;
|
||||
MODULES *mod;
|
||||
|
||||
if ((mod = find_module(module)) == NULL)
|
||||
{
|
||||
/*
|
||||
* The module is not already loaded
|
||||
*
|
||||
* Search of the shared object.
|
||||
*/
|
||||
sprintf(fname, "lib%s.so", module);
|
||||
if (access(fname, F_OK) == -1)
|
||||
{
|
||||
if ((home = getenv("GATEWAY_HOME")) == NULL)
|
||||
home = "/usr/local/skysql/gateway";
|
||||
sprintf(fname, "%s/modules/lib%s.so", home, module);
|
||||
if (access(fname, F_OK) == -1)
|
||||
{
|
||||
fprintf(stderr, "Unable to find library for module: %s\n", module);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ((dlhandle = dlopen(fname, RTLD_NOW|RTLD_LOCAL)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to load library for module: %s, %s\n", module, dlerror());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((sym = dlsym(dlhandle, "version")) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Version interface not supported by module: %s, %s\n", module, dlerror());
|
||||
dlclose(dlhandle);
|
||||
return NULL;
|
||||
}
|
||||
ver = sym;
|
||||
version = ver();
|
||||
|
||||
if ((sym = dlsym(dlhandle, entry)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Expected entry point interface missing from module: %s, %s\n", module, dlerror());
|
||||
dlclose(dlhandle);
|
||||
return NULL;
|
||||
}
|
||||
ep = sym;
|
||||
modobj = ep();
|
||||
|
||||
fprintf(stderr, "Loaded module %s: %s\n", module, version);
|
||||
register_module(module, type, dlhandle, version, modobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The module is already loaded, get the entry points again and
|
||||
* return a reference to the already loaded module.
|
||||
*/
|
||||
modobj = mod->modobj;
|
||||
}
|
||||
|
||||
return modobj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unload a module.
|
||||
*
|
||||
* No errors are returned since it is not clear that much can be done
|
||||
* to fix issues relating to unloading modules.
|
||||
*
|
||||
* @param module The name of the module
|
||||
*/
|
||||
void
|
||||
unload_module(const char *module)
|
||||
{
|
||||
MODULES *mod = find_module(module);
|
||||
void *handle;
|
||||
|
||||
if (!mod)
|
||||
return;
|
||||
handle = mod->handle;
|
||||
unregister_module(module);
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a module that has been previously loaded and return the handle for that
|
||||
* library
|
||||
*
|
||||
* @param module The name of the module
|
||||
* @return The module handle or NULL if it was not found
|
||||
*/
|
||||
static MODULES *
|
||||
find_module(const char *module)
|
||||
{
|
||||
MODULES *ptr = registered;
|
||||
|
||||
while (registered)
|
||||
if (strcmp(registered->module, module))
|
||||
return registered;
|
||||
else
|
||||
registered = registered->next;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register a newly loaded module. The registration allows for single copies
|
||||
* to be loaded and cached entry point information to be return.
|
||||
*
|
||||
* @param module The name of the module loaded
|
||||
* @param type The type of the module loaded
|
||||
* @param dlhandle The handle returned by dlopen
|
||||
* @param version The version string returned by the module
|
||||
* @param modobj The module object
|
||||
*/
|
||||
static void
|
||||
register_module(const char *module, const char *type, void *dlhandle, char *version, void *modobj)
|
||||
{
|
||||
MODULES *mod;
|
||||
|
||||
if ((mod = malloc(sizeof(MODULES))) == NULL)
|
||||
return;
|
||||
mod->module = strdup(module);
|
||||
mod->type = strdup(type);
|
||||
mod->handle = dlhandle;
|
||||
mod->version = strdup(version);
|
||||
mod->modobj = modobj;
|
||||
mod->next = registered;
|
||||
registered = mod;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unregister a module
|
||||
*
|
||||
* @param module The name of the module to remove
|
||||
*/
|
||||
static void
|
||||
unregister_module(const char *module)
|
||||
{
|
||||
MODULES *mod = find_module(module);
|
||||
MODULES *ptr;
|
||||
|
||||
if (!mod)
|
||||
return; // Module not found
|
||||
if (registered == mod)
|
||||
registered = mod->next;
|
||||
else
|
||||
{
|
||||
ptr = registered;
|
||||
while (ptr && ptr->next != mod)
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* The module is now not in the linked list and all
|
||||
* memory related to it can be freed
|
||||
*/
|
||||
free(mod->module);
|
||||
free(mod->type);
|
||||
free(mod->version);
|
||||
free(mod);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print Modules
|
||||
*
|
||||
* Diagnostic routine to display all the loaded modules
|
||||
*/
|
||||
void
|
||||
printModules()
|
||||
{
|
||||
MODULES *ptr = registered;
|
||||
|
||||
printf("%-15s | %-10s | Version\n", "Module Name", "Module Type");
|
||||
printf("-----------------------------------------------------\n");
|
||||
while (ptr)
|
||||
{
|
||||
printf("%-15s | %-10s | %s\n", ptr->module, ptr->type, ptr->version);
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
@ -55,7 +55,7 @@ int handle_event_errors(DCB *dcb, int event);
|
||||
int handle_event_errors_backend(DCB *dcb, int event);
|
||||
void MySQLListener(int epfd, char *config_bind);
|
||||
int MySQLAccept(DCB *listener, int efd);
|
||||
int gw_mysql_do_authentication(DCB *dcb);
|
||||
int gw_mysql_do_authentication(DCB *dcb, GWBUF *);
|
||||
void gw_mysql_close(MySQLProtocol **ptr);
|
||||
char *gw_strend(register const char *s);
|
||||
int do_read_dcb(DCB *dcb);
|
||||
|
44
include/modules.h
Normal file
44
include/modules.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef _MODULES_H
|
||||
#define _MODULES_H
|
||||
/*
|
||||
* This file is distributed as part of the SkySQL Gateway. It 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.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright SkySQL Ab 2013
|
||||
*/
|
||||
|
||||
/*
|
||||
* The module interface used within the gateway
|
||||
*
|
||||
* Revision History
|
||||
*
|
||||
* Date Who Description
|
||||
* 13/06/13 Mark Riddoch Initial implementation
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct modules {
|
||||
char *module; /* The name of the module */
|
||||
char *type; /* The module type */
|
||||
char *version; /* Module version */
|
||||
void *handle; /* The handle returned by dlopen */
|
||||
void *modobj; /* The module "object" this is the set of entry points */
|
||||
struct modules
|
||||
*next; /* Next module in the linked list */
|
||||
} MODULES;
|
||||
|
||||
extern void *load_module(const char *module, const char *type, const char *entry);
|
||||
extern void unload_module(const char *module);
|
||||
extern void printModules();
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user