Name change to MaxScale rather than gateway
Addition of code for dynamic reconfiguration by editign the cnf file and sendign a SIGHUP Improvements to the make install rule
This commit is contained in:
@ -1,2 +1,3 @@
|
||||
core/tags
|
||||
gateway
|
||||
core/maxscale
|
||||
|
12
Makefile
12
Makefile
@ -22,6 +22,7 @@
|
||||
# 18/06/13 Mark Riddoch Addition of install target
|
||||
# 21/06/13 Mark Riddoch Addition of inih
|
||||
# 08/07/13 Mark Riddoch Addition of monitor modules
|
||||
# 16/07/13 Mark Riddoch Renamed things to match the new naming
|
||||
|
||||
DEST=/home/mriddoch/usr/local/skysql
|
||||
|
||||
@ -50,11 +51,12 @@ documentation:
|
||||
doxygen doxygate
|
||||
|
||||
install:
|
||||
@mkdir -p $(DEST)/gateway/modules
|
||||
@mkdir -p $(DEST)/gateway/log
|
||||
@mkdir -p $(DEST)/gateway/etc
|
||||
install gateway.cnf $(DEST)/gateway/etc
|
||||
@mkdir -p $(DEST)/MaxScale/modules
|
||||
@mkdir -p $(DEST)/MaxScale/log
|
||||
@mkdir -p $(DEST)/MaxScale/etc
|
||||
@mkdir -p $(DEST)/lib
|
||||
install MaxScale.cnf $(DEST)/MaxScale/etc
|
||||
(cd core; make DEST=$(DEST) install)
|
||||
(cd modules/routing; make DEST=$(DEST) install)
|
||||
(cd modules/protocol; make DEST=$(DEST) install)
|
||||
(cd modules/moinitor; make DEST=$(DEST) install)
|
||||
(cd modules/monitor; make DEST=$(DEST) install)
|
||||
|
@ -70,14 +70,14 @@ LIBS=-L../inih/extra -linih -lssl -lstdc++ \
|
||||
-lz -lm -lcrypto -ldl -pthread -llog_manager \
|
||||
-lmysqld
|
||||
|
||||
gateway: $(OBJ)
|
||||
maxscale: $(OBJ)
|
||||
$(CC) $(LDFLAGS) $(OBJ) $(UTILSPATH)/skygw_utils.o $(LIBS) -o $@
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) gateway
|
||||
rm -f $(OBJ) maxscale
|
||||
- rm *.so
|
||||
|
||||
tags:
|
||||
@ -87,7 +87,7 @@ depend:
|
||||
@rm -f depend.mk
|
||||
cc -M $(CFLAGS) $(SRCS) > depend.mk
|
||||
|
||||
install: gateway
|
||||
install: maxscale
|
||||
@mkdir -p $(DEST)/bin
|
||||
install -D $< $(DEST)/bin
|
||||
|
||||
|
170
core/config.c
170
core/config.c
@ -39,11 +39,13 @@
|
||||
#include <monitor.h>
|
||||
|
||||
static int process_config_context(CONFIG_CONTEXT *);
|
||||
static int process_config_update(CONFIG_CONTEXT *);
|
||||
static void free_config_context(CONFIG_CONTEXT *);
|
||||
static char *config_get_value(CONFIG_PARAMETER *, const char *);
|
||||
static int handle_global_item(const char *, const char *);
|
||||
static void global_defaults();
|
||||
|
||||
static char *config_file = NULL;
|
||||
static GATEWAY_CONF gateway;
|
||||
|
||||
/**
|
||||
@ -93,6 +95,7 @@ CONFIG_PARAMETER *param;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the configuration file for the gateway
|
||||
*
|
||||
* @param file The filename of the configuration file
|
||||
*/
|
||||
@ -110,12 +113,40 @@ int rval;
|
||||
if (ini_parse(file, handler, &config) < 0)
|
||||
return 0;
|
||||
|
||||
config_file = file;
|
||||
|
||||
rval = process_config_context(config.next);
|
||||
free_config_context(config.next);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Relooad the configuration file for the gateway
|
||||
*
|
||||
*/
|
||||
int
|
||||
config_reload()
|
||||
{
|
||||
CONFIG_CONTEXT config;
|
||||
int rval;
|
||||
|
||||
if (!config_file)
|
||||
return 0;
|
||||
global_defaults();
|
||||
|
||||
config.object = "";
|
||||
config.next = NULL;
|
||||
|
||||
if (ini_parse(config_file, handler, &config) < 0)
|
||||
return 0;
|
||||
|
||||
rval = process_config_update(config.next);
|
||||
free_config_context(config.next);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a configuration context and turn it into the set of object
|
||||
* we need.
|
||||
@ -336,3 +367,142 @@ global_defaults()
|
||||
{
|
||||
gateway.n_threads = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a configuration context update and turn it into the set of object
|
||||
* we need.
|
||||
*
|
||||
* @param context The configuration data
|
||||
*/
|
||||
static int
|
||||
process_config_update(CONFIG_CONTEXT *context)
|
||||
{
|
||||
CONFIG_CONTEXT *obj;
|
||||
SERVICE *service;
|
||||
SERVER *server;
|
||||
|
||||
/**
|
||||
* Process the data and create the services and servers defined
|
||||
* in the data.
|
||||
*/
|
||||
obj = context;
|
||||
while (obj)
|
||||
{
|
||||
char *type = config_get_value(obj->parameters, "type");
|
||||
if (type == NULL)
|
||||
fprintf(stderr, "Object %s has no type\n", obj->object);
|
||||
else if (!strcmp(type, "service"))
|
||||
{
|
||||
char *router = config_get_value(obj->parameters, "router");
|
||||
if (router)
|
||||
{
|
||||
if ((service = service_find(obj->object)) != NULL)
|
||||
{
|
||||
char *user = config_get_value(obj->parameters, "user");
|
||||
char *auth = config_get_value(obj->parameters, "auth");
|
||||
service_update(service, router, user, auth);
|
||||
obj->element = service;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->element = service_alloc(obj->object, router);
|
||||
char *user = config_get_value(obj->parameters, "user");
|
||||
char *auth = config_get_value(obj->parameters, "auth");
|
||||
if (obj->element && user && auth)
|
||||
serviceSetUser(obj->element, user, auth);
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "No router defined for service '%s'\n",
|
||||
obj->object);
|
||||
}
|
||||
else if (!strcmp(type, "server"))
|
||||
{
|
||||
char *address = config_get_value(obj->parameters, "address");
|
||||
char *port = config_get_value(obj->parameters, "port");
|
||||
char *protocol = config_get_value(obj->parameters, "protocol");
|
||||
char *monuser = config_get_value(obj->parameters, "monitoruser");
|
||||
char *monpw = config_get_value(obj->parameters, "monitorpw");
|
||||
if (address && port && protocol)
|
||||
{
|
||||
if ((server = server_find(address, atoi(port))) != NULL)
|
||||
{
|
||||
server_update(server, protocol, monuser, monpw);
|
||||
obj->element = server;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->element = server_alloc(address, protocol, atoi(port));
|
||||
if (obj->element && monuser && monpw)
|
||||
serverAddMonUser(obj->element, monuser, monpw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj = obj->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we have the services we can add the servers to the services
|
||||
* add the protocols to the services
|
||||
*/
|
||||
obj = context;
|
||||
while (obj)
|
||||
{
|
||||
char *type = config_get_value(obj->parameters, "type");
|
||||
if (type == NULL)
|
||||
;
|
||||
else if (!strcmp(type, "service"))
|
||||
{
|
||||
char *servers = config_get_value(obj->parameters, "servers");
|
||||
char *roptions = config_get_value(obj->parameters, "router_options");
|
||||
if (servers && obj->element)
|
||||
{
|
||||
char *s = strtok(servers, ",");
|
||||
while (s)
|
||||
{
|
||||
CONFIG_CONTEXT *obj1 = context;
|
||||
while (obj1)
|
||||
{
|
||||
if (strcmp(s, obj1->object) == 0 && obj->element && obj1->element)
|
||||
if (!serviceHasBackend(obj->element, obj1->element))
|
||||
serviceAddBackend(obj->element, obj1->element);
|
||||
obj1 = obj1->next;
|
||||
}
|
||||
s = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
if (roptions && obj->element)
|
||||
{
|
||||
char *s = strtok(roptions, ",");
|
||||
serviceClearRouterOptions(obj->element);
|
||||
while (s)
|
||||
{
|
||||
serviceAddRouterOption(obj->element, s);
|
||||
s = strtok(NULL, ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(type, "listener"))
|
||||
{
|
||||
char *service = config_get_value(obj->parameters, "service");
|
||||
char *port = config_get_value(obj->parameters, "port");
|
||||
char *protocol = config_get_value(obj->parameters, "protocol");
|
||||
if (service && port && protocol)
|
||||
{
|
||||
CONFIG_CONTEXT *ptr = context;
|
||||
while (ptr && strcmp(ptr->object, service) != 0)
|
||||
ptr = ptr->next;
|
||||
if (ptr && ptr->element && serviceHasProtocol(ptr->element, protocol, atoi(port)) == 0)
|
||||
{
|
||||
serviceAddProtocol(ptr->element, protocol, atoi(port));
|
||||
serviceStartProtocol(ptr->element, protocol, atoi(port));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj = obj->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -83,9 +83,14 @@ static char* server_groups[] = {
|
||||
/* The data directory we created for this gateway instance */
|
||||
static char datadir[1024] = "";
|
||||
|
||||
/* basic signal handling */
|
||||
static void sighup_handler (int i) {
|
||||
skygw_log_write(NULL, LOGFILE_ERROR, "Signal SIGHUP %i received ...\n", i);
|
||||
/**
|
||||
* Handler for SIGHUP signal. Reload the configuration for the
|
||||
* gateway.
|
||||
*/
|
||||
static void sighup_handler (int i)
|
||||
{
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "Refreshing configuration following SIGHUP\n");
|
||||
config_reload();
|
||||
}
|
||||
|
||||
static void sigterm_handler (int i) {
|
||||
@ -241,14 +246,14 @@ char ddopt[1024];
|
||||
#endif
|
||||
atexit(datadir_cleanup);
|
||||
|
||||
if ((home = getenv("GATEWAY_HOME")) != NULL)
|
||||
if ((home = getenv("MAXSCALE_HOME")) != NULL)
|
||||
{
|
||||
sprintf(buf, "%s/etc/gateway.cnf", home);
|
||||
sprintf(buf, "%s/etc/MaxScale.cnf", home);
|
||||
if (access(buf, R_OK) == 0)
|
||||
cnf_file = buf;
|
||||
}
|
||||
if (cnf_file == NULL && access("/etc/gateway.cnf", R_OK) == 0)
|
||||
cnf_file = "/etc/gateway.cnf";
|
||||
if (cnf_file == NULL && access("/etc/MaxScale.cnf", R_OK) == 0)
|
||||
cnf_file = "/etc/MaxScale.cnf";
|
||||
|
||||
/*
|
||||
* Set a data directory for the mysqld library, we use
|
||||
@ -263,13 +268,13 @@ char ddopt[1024];
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(datadir, "/tmp/gateway/data%d", getpid());
|
||||
mkdir("/tmp/gateway", 0777);
|
||||
sprintf(datadir, "/tmp/MaxScale/data%d", getpid());
|
||||
mkdir("/tmp/MaxScale", 0777);
|
||||
mkdir(datadir, 0777);
|
||||
}
|
||||
|
||||
/*
|
||||
* If $GATEWAY_HOME is set then write the logs into $GATEWAY_HOME/log.
|
||||
* If $MAXSCALE_HOME is set then write the logs into $MAXSCALE_HOME/log.
|
||||
* The skygw_logmanager_init expects to take arguments as passed to main
|
||||
* and proesses them with getopt, therefore we need to give it a dummy
|
||||
* argv[0]
|
||||
@ -281,7 +286,7 @@ char ddopt[1024];
|
||||
|
||||
sprintf(buf, "%s/log", home);
|
||||
mkdir(buf, 0777);
|
||||
argv[0] = "gateway";
|
||||
argv[0] = "MaxScale";
|
||||
argv[1] = "-g";
|
||||
argv[2] = buf;
|
||||
argv[3] = NULL;
|
||||
@ -307,8 +312,8 @@ char ddopt[1024];
|
||||
if (cnf_file == NULL) {
|
||||
skygw_log_write(
|
||||
NULL, LOGFILE_ERROR,
|
||||
"Fatal : Unable to find a gateway configuration file, either "
|
||||
"install one in /etc/gateway.cnf, $GATEWAY_HOME/etc/gateway.cnf "
|
||||
"Fatal : Unable to find a MaxScale configuration file, either "
|
||||
"install one in /etc/MaxScale.cnf, $MAXSCALE_HOME/etc/MaxScale.cnf "
|
||||
"or use the -c option. Exiting.\n");
|
||||
exit(1);
|
||||
}
|
||||
@ -328,7 +333,7 @@ char ddopt[1024];
|
||||
skygw_log_write_flush(
|
||||
NULL, LOGFILE_ERROR,
|
||||
"Fatal : mysql_library_init failed, %s. This is mandatory component, required "
|
||||
"by router services and the gateway core, the gateway can't continue without it. Exiting.\n"
|
||||
"by router services and the MaxScale core, the MaxScale can't continue without it. Exiting.\n"
|
||||
"%s : %d\n", mysql_error(NULL), __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
@ -337,7 +342,7 @@ char ddopt[1024];
|
||||
{
|
||||
skygw_log_write(NULL,
|
||||
LOGFILE_ERROR,
|
||||
"Failed to load gateway configuration file %s\n", cnf_file);
|
||||
"Failed to load MaxScale configuration file %s\n", cnf_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -368,7 +373,7 @@ char ddopt[1024];
|
||||
gw_daemonize();
|
||||
}
|
||||
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "GATEWAY is starting, PID %i\n", getpid());
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "MaxScale is starting, PID %i\n", getpid());
|
||||
|
||||
poll_init();
|
||||
|
||||
@ -390,7 +395,7 @@ char ddopt[1024];
|
||||
for (n = 0; n < n_threads - 1; n++)
|
||||
thread_wait(threads[n]);
|
||||
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "GATEWAY shutdown, PID %i\n", getpid());
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "MaxScale shutdown, PID %i\n", getpid());
|
||||
|
||||
return 0;
|
||||
} // End of main
|
||||
|
@ -184,10 +184,10 @@ unsigned char *ptr, *eptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the contents of one bitmap to another.
|
||||
*
|
||||
* @param bitmask Pointer the bitmask
|
||||
* @param value Value to be added
|
||||
* @return The value of *variable before the add occured
|
||||
* @param dest Bitmap tp update
|
||||
* @param src Bitmap to copy
|
||||
*/
|
||||
void
|
||||
bitmask_copy(GWBITMASK *dest, GWBITMASK *src)
|
||||
|
@ -48,7 +48,7 @@ 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.
|
||||
* $MAXSCALE_HOME/modules and /usr/local/skysql/MaxScale/modules.
|
||||
*
|
||||
* @param module Name of the module to load
|
||||
* @param type Type of module, used purely for registration
|
||||
@ -74,8 +74,8 @@ MODULES *mod;
|
||||
sprintf(fname, "./lib%s.so", module);
|
||||
if (access(fname, F_OK) == -1)
|
||||
{
|
||||
if ((home = getenv("GATEWAY_HOME")) == NULL)
|
||||
home = "/usr/local/skysql/gateway";
|
||||
if ((home = getenv("MAXSCALE_HOME")) == NULL)
|
||||
home = "/usr/local/skysql/MaxScale";
|
||||
sprintf(fname, "%s/modules/lib%s.so", home, module);
|
||||
if (access(fname, F_OK) == -1)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ static SPINLOCK monLock = SPINLOCK_INIT;
|
||||
* and start execution on the monitor.
|
||||
*
|
||||
* @param name The name of the monitor module to load
|
||||
* @param module The module to load
|
||||
* @return The newly created monitor
|
||||
*/
|
||||
MONITOR *
|
||||
@ -56,7 +57,6 @@ MONITOR *mon;
|
||||
}
|
||||
|
||||
mon->name = strdup(name);
|
||||
mon->module = strdup(module);
|
||||
if ((mon->module = load_module(module, MODULE_MONITOR)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "Unable to load monitor module '%s'\n", name);
|
||||
|
@ -132,7 +132,7 @@ struct epoll_event ev;
|
||||
* deschedule a process if a timeout is included, but will not do this if a 0 timeout
|
||||
* value is given. this improves performance when the gateway is under heavy load.
|
||||
*
|
||||
* @parm arg The thread ID passed as a void * to satisfy the threading package
|
||||
* @param arg The thread ID passed as a void * to satisfy the threading package
|
||||
*/
|
||||
void
|
||||
poll_waitevents(void *arg)
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <server.h>
|
||||
#include <spinlock.h>
|
||||
#include <dcb.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
static SPINLOCK server_spin = SPINLOCK_INIT;
|
||||
static SERVER *allServers = NULL;
|
||||
@ -107,6 +109,30 @@ SERVER *ptr;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an existing server
|
||||
*
|
||||
* @param servname The Server name or address
|
||||
* @param port The server port
|
||||
* @return The server or NULL if not found
|
||||
*/
|
||||
SERVER *
|
||||
server_find(char *servname, unsigned short port)
|
||||
{
|
||||
SERVER *server;
|
||||
|
||||
spinlock_acquire(&server_spin);
|
||||
server = allServers;
|
||||
while (server)
|
||||
{
|
||||
if (strcmp(server->name, servname) == 0 && server->port == port)
|
||||
break;
|
||||
server = server->next;
|
||||
}
|
||||
spinlock_release(&server_spin);
|
||||
return server;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print details of an individual server
|
||||
*
|
||||
@ -253,3 +279,38 @@ serverAddMonUser(SERVER *server, char *user, char *passwd)
|
||||
server->monuser = strdup(user);
|
||||
server->monpw = strdup(passwd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and update a server definition following a configuration
|
||||
* update. Changes will not affect any current connections to this
|
||||
* server, however all new connections will use the new settings.
|
||||
*
|
||||
* If the new settings are different from those already applied to the
|
||||
* server then a message will be written to the log.
|
||||
*
|
||||
* @param server The server to update
|
||||
* @param protocol The new protocol for the server
|
||||
* @param user The monitor user for the server
|
||||
* @param passwd The password to use for the monitor user
|
||||
*/
|
||||
void
|
||||
server_update(SERVER *server, char *protocol, char *user, char *passwd)
|
||||
{
|
||||
if (!strcmp(server->protocol, protocol))
|
||||
{
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "Update server protocol for server %s to protocol %s",
|
||||
server->name, protocol);
|
||||
free(server->protocol);
|
||||
server->protocol = strdup(protocol);
|
||||
}
|
||||
|
||||
if (strcmp(server->monuser, user) == 0 || strcmp(server->monpw, passwd) == 0)
|
||||
{
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "Update server monitor credentials for server %s",
|
||||
server->name);
|
||||
free(server->monuser);
|
||||
free(server->monpw);
|
||||
serverAddMonUser(server, user, passwd);
|
||||
}
|
||||
}
|
||||
|
||||
|
199
core/service.c
199
core/service.c
@ -40,6 +40,8 @@
|
||||
#include <users.h>
|
||||
#include <dbusers.h>
|
||||
#include <poll.h>
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
|
||||
static SPINLOCK service_spin = SPINLOCK_INIT;
|
||||
static SERVICE *allServices = NULL;
|
||||
@ -87,33 +89,22 @@ SERVICE *service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a service
|
||||
* Start an individual port/protocol pair
|
||||
*
|
||||
* This function loads the protocol modules for each port on which the
|
||||
* service listens and starts the listener on that port
|
||||
*
|
||||
* Also create the router_instance for the service.
|
||||
*
|
||||
* @param service The Service that should be started
|
||||
* @return Returns the number of listeners created
|
||||
* @param service The service
|
||||
* @param port The port to start
|
||||
* @return The number of listeners started
|
||||
*/
|
||||
int
|
||||
serviceStart(SERVICE *service)
|
||||
static int
|
||||
serviceStartPort(SERVICE *service, SERV_PROTOCOL *port)
|
||||
{
|
||||
SERV_PROTOCOL *port;
|
||||
int listeners = 0;
|
||||
char config_bind[40];
|
||||
GWPROTOCOL *funcs;
|
||||
|
||||
service->router_instance = service->router->createInstance(service,
|
||||
service->routerOptions);
|
||||
|
||||
port = service->ports;
|
||||
while (port)
|
||||
{
|
||||
if ((port->listener = dcb_alloc()) == NULL)
|
||||
{
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(port->protocol, "MySQLClient") == 0) {
|
||||
@ -121,7 +112,7 @@ GWPROTOCOL *funcs;
|
||||
|
||||
loaded = load_mysql_users(service);
|
||||
|
||||
fprintf(stderr, "@@@@ MySQL Users loaded: %i\n", loaded);
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "MySQL Users loaded: %i\n", loaded);
|
||||
}
|
||||
|
||||
if ((funcs = (GWPROTOCOL *)load_module(port->protocol, MODULE_PROTOCOL)) == NULL)
|
||||
@ -137,6 +128,33 @@ GWPROTOCOL *funcs;
|
||||
port->listener->session = session_alloc(service, port->listener);
|
||||
port->listener->session->state = SESSION_STATE_LISTENER;
|
||||
|
||||
return listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a service
|
||||
*
|
||||
* This function loads the protocol modules for each port on which the
|
||||
* service listens and starts the listener on that port
|
||||
*
|
||||
* Also create the router_instance for the service.
|
||||
*
|
||||
* @param service The Service that should be started
|
||||
* @return Returns the number of listeners created
|
||||
*/
|
||||
int
|
||||
serviceStart(SERVICE *service)
|
||||
{
|
||||
SERV_PROTOCOL *port;
|
||||
int listeners = 0;
|
||||
|
||||
service->router_instance = service->router->createInstance(service,
|
||||
service->routerOptions);
|
||||
|
||||
port = service->ports;
|
||||
while (port)
|
||||
{
|
||||
listeners += serviceStartPort(service, port);
|
||||
port = port->next;
|
||||
}
|
||||
if (listeners)
|
||||
@ -145,6 +163,28 @@ GWPROTOCOL *funcs;
|
||||
return listeners;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start an individual listener
|
||||
*
|
||||
* @param service The service to start the listener for
|
||||
* @param protocol The name of the protocol
|
||||
* @param port The port number
|
||||
*/
|
||||
void
|
||||
serviceStartProtocol(SERVICE *service, char *protocol, int port)
|
||||
{
|
||||
SERV_PROTOCOL *ptr;
|
||||
|
||||
ptr = service->ports;
|
||||
while (ptr)
|
||||
{
|
||||
if (strcmp(ptr->protocol, protocol) == 0 && ptr->port == port)
|
||||
serviceStartPort(service, ptr);
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Start all the services
|
||||
*
|
||||
@ -289,6 +329,32 @@ SERV_PROTOCOL *proto;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a protocol/port pair si part of the service
|
||||
*
|
||||
* @param service The service
|
||||
* @param protocol The name of the protocol module
|
||||
* @param port The port to listen on
|
||||
* @return TRUE if the protocol/port is already part of the service
|
||||
*/
|
||||
int
|
||||
serviceHasProtocol(SERVICE *service, char *protocol, unsigned short port)
|
||||
{
|
||||
SERV_PROTOCOL *proto;
|
||||
|
||||
spinlock_acquire(&service->spin);
|
||||
proto = service->ports;
|
||||
while (proto)
|
||||
{
|
||||
if (strcmp(proto->protocol, protocol) == 0 && proto->port == port)
|
||||
break;
|
||||
proto = proto->next;
|
||||
}
|
||||
spinlock_release(&service->spin);
|
||||
|
||||
return proto != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a backend database server to a service
|
||||
*
|
||||
@ -304,6 +370,27 @@ serviceAddBackend(SERVICE *service, SERVER *server)
|
||||
spinlock_release(&service->spin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a server is part of a service
|
||||
*
|
||||
* @param service The service to add the server to
|
||||
* @param server The server to add
|
||||
* @return Non-zero if the server is already part of the service
|
||||
*/
|
||||
int
|
||||
serviceHasBackend(SERVICE *service, SERVER *server)
|
||||
{
|
||||
SERVER *ptr;
|
||||
|
||||
spinlock_acquire(&service->spin);
|
||||
ptr = service->databases;
|
||||
while (ptr && ptr != server)
|
||||
ptr = ptr->nextdb;
|
||||
spinlock_release(&service->spin);
|
||||
|
||||
return ptr != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a router option to a service
|
||||
*
|
||||
@ -334,6 +421,23 @@ int i;
|
||||
spinlock_release(&service->spin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the router options for the service
|
||||
*
|
||||
* @param service The service to remove the options from
|
||||
*/
|
||||
void
|
||||
serviceClearRouterOptions(SERVICE *service)
|
||||
{
|
||||
int i;
|
||||
|
||||
spinlock_acquire(&service->spin);
|
||||
for (i = 0; service->routerOptions[i]; i++)
|
||||
free(service->routerOptions[i]);
|
||||
free(service->routerOptions);
|
||||
service->routerOptions = NULL;
|
||||
spinlock_release(&service->spin);
|
||||
}
|
||||
/**
|
||||
* Set the service user that is used to log in to the backebd servers
|
||||
* associated with this service.
|
||||
@ -378,6 +482,27 @@ serviceGetUser(SERVICE *service, char **user, char **auth)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a named service
|
||||
*
|
||||
* @param servname The name of the service to find
|
||||
* @return The service or NULL if not found
|
||||
*/
|
||||
SERVICE *
|
||||
service_find(char *servname)
|
||||
{
|
||||
SERVICE *service;
|
||||
|
||||
spinlock_acquire(&service_spin);
|
||||
service = allServices;
|
||||
while (service && strcmp(service->name, servname) != 0)
|
||||
service = service->next;
|
||||
spinlock_release(&service_spin);
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print details of an individual service
|
||||
*
|
||||
@ -462,3 +587,39 @@ SERVICE *ptr;
|
||||
}
|
||||
spinlock_release(&service_spin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the definition of a service
|
||||
*
|
||||
* @param service The service to update
|
||||
* @param router The router module to use
|
||||
* @param user The user to use to extract information from the database
|
||||
* @param auth The password for the user above
|
||||
*/
|
||||
void
|
||||
service_update(SERVICE *service, char *router, char *user, char *auth)
|
||||
{
|
||||
void *router_obj;
|
||||
|
||||
if (!strcmp(service->routerModule, router))
|
||||
{
|
||||
if ((router_obj = load_module(router, MODULE_ROUTER)) == NULL)
|
||||
{
|
||||
skygw_log_write(NULL, LOGFILE_ERROR, "Failed to update router for service %s to %s",
|
||||
service->name, router);
|
||||
}
|
||||
else
|
||||
{
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "Update router for service %s to %s",
|
||||
service->name, router);
|
||||
free(service->routerModule);
|
||||
service->routerModule = strdup(router);
|
||||
service->router = router_obj;
|
||||
}
|
||||
}
|
||||
if (strcmp(service->credentials.name, user) == 0 || strcmp(service->credentials.authdata, auth) == 0)
|
||||
{
|
||||
skygw_log_write(NULL, LOGFILE_MESSAGE, "Update credentials for service %s", service->name);
|
||||
serviceSetUser(service, user, auth);
|
||||
}
|
||||
}
|
||||
|
@ -58,5 +58,6 @@ typedef struct {
|
||||
} GATEWAY_CONF;
|
||||
|
||||
extern int config_load(char *);
|
||||
extern int config_reload();
|
||||
extern int config_threadcount();
|
||||
#endif
|
||||
|
@ -96,6 +96,7 @@ typedef struct server {
|
||||
|
||||
extern SERVER *server_alloc(char *, char *, unsigned short);
|
||||
extern int server_free(SERVER *);
|
||||
extern SERVER *server_find(char *, unsigned short);
|
||||
extern void printServer(SERVER *);
|
||||
extern void printAllServers();
|
||||
extern void dprintAllServers(DCB *);
|
||||
@ -104,4 +105,5 @@ extern char *server_status(SERVER *);
|
||||
extern void server_set_status(SERVER *, int);
|
||||
extern void server_clear_status(SERVER *, int);
|
||||
extern void serverAddMonUser(SERVER *, char *, char *);
|
||||
extern void server_update(SERVER *, char *, char *, char *);
|
||||
#endif
|
||||
|
@ -109,15 +109,21 @@ typedef struct service {
|
||||
|
||||
extern SERVICE *service_alloc(char *, char *);
|
||||
extern int service_free(SERVICE *);
|
||||
extern SERVICE *service_find(char *);
|
||||
extern int serviceAddProtocol(SERVICE *, char *, unsigned short);
|
||||
extern int serviceHasProtocol(SERVICE *, char *, unsigned short);
|
||||
extern void serviceAddBackend(SERVICE *, SERVER *);
|
||||
extern int serviceHasBackend(SERVICE *, SERVER *);
|
||||
extern void serviceAddRouterOption(SERVICE *, char *);
|
||||
extern void serviceClearRouterOptions(SERVICE *);
|
||||
extern int serviceStart(SERVICE *);
|
||||
extern int serviceStartAll();
|
||||
extern void serviceStartProtocol(SERVICE *, char *, int);
|
||||
extern int serviceStop(SERVICE *);
|
||||
extern int serviceRestart(SERVICE *);
|
||||
extern int serviceSetUser(SERVICE *, char *, char *);
|
||||
extern int serviceGetUser(SERVICE *, char **, char **);
|
||||
extern void service_update(SERVICE *, char *, char *, char *);
|
||||
extern void printService(SERVICE *);
|
||||
extern void printAllServices();
|
||||
extern void dprintAllServices(DCB *);
|
||||
|
@ -55,6 +55,6 @@ depend:
|
||||
cc -M $(CFLAGS) $(SRCS) > depend.mk
|
||||
|
||||
install: $(MODULES)
|
||||
install -D $< $(DEST)/gateway/modules
|
||||
install -D $(MODULES) $(DEST)/MaxScale/modules
|
||||
|
||||
include depend.mk
|
||||
|
@ -111,7 +111,7 @@ MYSQL_MONITOR *handle;
|
||||
/**
|
||||
* Stop a running monitor
|
||||
*
|
||||
* @param handle Handle on thr running monior
|
||||
* @param arg Handle on thr running monior
|
||||
*/
|
||||
static void
|
||||
stopMonitor(void *arg)
|
||||
@ -125,7 +125,7 @@ MYSQL_MONITOR *handle = (MYSQL_MONITOR *)arg;
|
||||
* Register a server that must be added to the monitored servers for
|
||||
* a monitoring module.
|
||||
*
|
||||
* @param handle A handle on the running monitor module
|
||||
* @param arg A handle on the running monitor module
|
||||
* @param server The server to add
|
||||
*/
|
||||
static void
|
||||
@ -155,7 +155,7 @@ MONITOR_SERVERS *ptr, *db;
|
||||
/**
|
||||
* Remove a server from those being monitored by a monitoring module
|
||||
*
|
||||
* @param handle A handle on the running monitor module
|
||||
* @param arg A handle on the running monitor module
|
||||
* @param server The server to remove
|
||||
*/
|
||||
static void
|
||||
|
@ -72,7 +72,7 @@ tags:
|
||||
ctags $(SRCS) $(HDRS)
|
||||
|
||||
install: $(MODULES)
|
||||
install -D $< $(DEST)/gateway/modules
|
||||
install -D $(MODULES) $(DEST)/MaxScale/modules
|
||||
|
||||
depend:
|
||||
rm -f depend.mk
|
||||
|
@ -43,8 +43,7 @@ DEBUGCLIOBJ=$(DEBUGCLISRCS:.c=.o)
|
||||
SRCS=$(TESTSRCS) $(READCONSRCS) $(DEBUGCLISRCS)
|
||||
OBJ=$(SRCS:.c=.o)
|
||||
LIBS=$(UTILSPATH)/skygw_utils.o -lssl -llog_manager
|
||||
MODULES=libtestroute.so libreadconnroute.so libdebugcli.so \
|
||||
libreadwritesplit.so
|
||||
MODULES= libdebugcli.so libreadconnroute.so libtestroute.so
|
||||
|
||||
|
||||
all: $(MODULES)
|
||||
@ -78,6 +77,7 @@ depend:
|
||||
(cd readwritesplit; make depend)
|
||||
|
||||
install: $(MODULES)
|
||||
install -D $< $(DEST)/gateway/modules
|
||||
install -D $(MODULES) $(DEST)/MaxScale/modules
|
||||
(cd readwritesplit; make DEST=$(DEST) install)
|
||||
|
||||
include depend.mk
|
||||
|
@ -159,7 +159,7 @@ CLI_SESSION *client;
|
||||
|
||||
session->state = SESSION_STATE_READY;
|
||||
|
||||
dcb_printf(session->client, "Welcome the SkySQL Gateway Debug Interface (%s).\n",
|
||||
dcb_printf(session->client, "Welcome the SkySQL MaxScale Debug Interface (%s).\n",
|
||||
version_str);
|
||||
dcb_printf(session->client, "Type help for a list of available commands.\n\n");
|
||||
|
||||
@ -226,7 +226,7 @@ CLI_SESSION *session = (CLI_SESSION *)router_session;
|
||||
if (strrchr(session->cmdbuf, '\n'))
|
||||
{
|
||||
if (execute_cmd(session))
|
||||
dcb_printf(session->session->client, "Gateway> ");
|
||||
dcb_printf(session->session->client, "MaxScale> ");
|
||||
else
|
||||
session->session->client->func.close(session->session->client);
|
||||
}
|
||||
|
@ -107,6 +107,8 @@ static void shutdown_service(DCB *dcb, SERVICE *service);
|
||||
struct subcommand shutdownoptions[] = {
|
||||
{ "gateway", 0, shutdown_gateway, "Shutdown the gateway",
|
||||
{0, 0, 0} },
|
||||
{ "maxscale", 0, shutdown_gateway, "Shutdown the MaxScale gateway",
|
||||
{0, 0, 0} },
|
||||
{ "service", 1, shutdown_service, "Shutdown a service, e.g. shutdown service 0x4838320",
|
||||
{ARG_TYPE_ADDRESS, 0, 0} },
|
||||
{ NULL, 0, NULL, NULL,
|
||||
|
@ -58,6 +58,6 @@ depend:
|
||||
cc -M $(CFLAGS) $(SRCS) > depend.mk
|
||||
|
||||
install: $(MODULES)
|
||||
install -D $< $(DEST)/gateway/modules
|
||||
install -D $(MODULES) $(DEST)/MaxScale/modules
|
||||
|
||||
include depend.mk
|
||||
|
@ -23,10 +23,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <mysql.h>
|
||||
#if defined(SS_DEBUG)
|
||||
#include <skygw_utils.h>
|
||||
#include <log_manager.h>
|
||||
#endif
|
||||
#include <query_classifier.h>
|
||||
#include <dcb.h>
|
||||
#include <spinlock.h>
|
||||
@ -306,7 +304,7 @@ static void* newSession(
|
||||
* by which a router may cleanup data structure etc.
|
||||
*
|
||||
* @param instance The router instance data
|
||||
* @param session The session being closed
|
||||
* @param router_session The session being closed
|
||||
*/
|
||||
static void closeSession(
|
||||
ROUTER* instance,
|
||||
@ -362,7 +360,7 @@ static void closeSession(
|
||||
* contain the remainder, or part thereof of the query.
|
||||
*
|
||||
* @param instance The query router instance
|
||||
* @param session The session associated with the client
|
||||
* @param router_session The session associated with the client
|
||||
* @param queue Gateway buffer queue with the packets received
|
||||
*
|
||||
* @return The number of queries forwarded
|
||||
|
Reference in New Issue
Block a user