Addition for shutdown mechanism for the gateway

Addition of stop and restart service

Fix for telnetd in Makefile

Fix for printing the server names in services
This commit is contained in:
Mark Riddoch 2013-06-25 14:00:18 +02:00
parent 72223fd4cf
commit 34fdbdb34d
11 changed files with 167 additions and 16 deletions

View File

@ -336,7 +336,7 @@ service.o: service.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/bits/setjmp.h ../include/dcb.h ../include/buffer.h \
../include/server.h ../include/router.h ../include/modules.h \
../include/users.h ../include/hashtable.h ../include/atomic.h \
../include/dbusers.h
../include/dbusers.h ../include/poll.h
server.o: server.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
/usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \

View File

@ -50,9 +50,10 @@ static void sighup_handler (int i) {
}
static void sigterm_handler (int i) {
extern void shutdown_gateway();
fprintf(stderr, "Signal SIGTERM %i received ...Exiting!\n", i);
exit(0);
shutdown_gateway();
}
/* wrapper for sigaction */
@ -170,7 +171,8 @@ main(int argc, char **argv)
{
int daemon_mode = 1;
sigset_t sigset;
int n;
int n, n_threads;
void **threads;
char buf[1024], *home, *cnf_file = NULL;
if ((home = getenv("GATEWAY_HOME")) != NULL)
@ -250,8 +252,24 @@ char buf[1024], *home, *cnf_file = NULL;
* Start the polling threads, note this is one less than is configured as the
* main thread will also poll.
*/
for (n = 0; n < config_threadcount() - 1; n++)
thread_start(poll_waitevents);
n_threads = config_threadcount();
threads = (void **)calloc(n_threads, sizeof(void *));
for (n = 0; n < n_threads - 1; n++)
threads[n] = thread_start(poll_waitevents);
poll_waitevents();
for (n = 0; n < n_threads - 1; n++)
thread_wait(threads[n]);
printf("Gateway shutdown\n");
return 0;
} // End of main
/**
* Shutdown the gateway
*/
void
shutdown_gateway()
{
poll_shutdown();
}

View File

@ -37,6 +37,7 @@
*/
static int epoll_fd = -1; /**< The epoll file descriptor */
static int shutdown = 0; /**< Flag the shutdown of the poll subsystem */
/**
* The polling statistics
@ -117,12 +118,18 @@ int i, nfds;
while (1)
{
atomic_add(&pollStats.n_polls, 1);
if ((nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1)) == -1)
if ((nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, 0)) == -1)
{
}
else
else if (nfds == 0)
{
if ((nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, EPOLL_TIMEOUT)) == -1)
{
}
}
if (nfds > 0)
{
atomic_add(&pollStats.n_polls, 1);
for (i = 0; i < nfds; i++)
{
DCB *dcb = (DCB *)events[i].data.ptr;
@ -158,9 +165,22 @@ int i, nfds;
}
}
}
if (shutdown)
{
return;
}
}
}
/**
* Shutdown the polling loop
*/
void
poll_shutdown()
{
shutdown = 1;
}
/**
* Debug routine to print the polling statistics
*

View File

@ -39,6 +39,7 @@
#include <dcb.h>
#include <users.h>
#include <dbusers.h>
#include <poll.h>
static SPINLOCK service_spin = SPINLOCK_INIT;
static SERVICE *allServices = NULL;
@ -160,6 +161,61 @@ int n = 0;
return n;
}
/**
* Stop a service
*
* This function stops the listener for the service
*
* @param service The Service that should be stopped
* @return Returns the number of listeners restarted
*/
int
serviceStop(SERVICE *service)
{
SERV_PROTOCOL *port;
int listeners = 0;
port = service->ports;
while (port)
{
poll_remove_dcb(port->listener);
port->listener->session->state = SESSION_STATE_LISTENER_STOPPED;
listeners++;
port = port->next;
}
return listeners;
}
/**
* Restart a service
*
* This function stops the listener for the service
*
* @param service The Service that should be restarted
* @return Returns the number of listeners restarted
*/
int
serviceRestart(SERVICE *service)
{
SERV_PROTOCOL *port;
int listeners = 0;
port = service->ports;
while (port)
{
poll_add_dcb(port->listener);
port->listener->session->state = SESSION_STATE_LISTENER;
listeners++;
port = port->next;
}
return listeners;
}
/**
* Deallocate the specified service
*
@ -306,7 +362,7 @@ SERVER *ptr = service->databases;
while (ptr)
{
printf("\t\t%s:%d Protocol: %s\n", ptr->name, ptr->port, ptr->protocol);
ptr = ptr->next;
ptr = ptr->nextdb;
}
printf("\tTotal connections: %d\n", service->stats.n_sessions);
printf("\tCurrently connected: %d\n", service->stats.n_current);
@ -360,7 +416,7 @@ SERVICE *ptr;
{
dcb_printf(dcb, "\t\t%s:%d Protocol: %s\n", server->name, server->port,
server->protocol);
server = server->next;
server = server->nextdb;
}
dcb_printf(dcb, "\tTotal connections: %d\n", ptr->stats.n_sessions);
dcb_printf(dcb, "\tCurrently connected: %d\n", ptr->stats.n_current);

View File

@ -130,6 +130,7 @@ void
printSession(SESSION *session)
{
printf("Session %p\n", session);
printf("\tState: %s\n", session_state(session->state));
printf("\tService: %s (%p)\n", session->service->name, session->service);
printf("\tClient DCB: %p\n", session->client);
printf("\tConnected: %s", asctime(localtime(&session->stats.connect)));
@ -174,6 +175,7 @@ SESSION *ptr;
while (ptr)
{
dcb_printf(dcb, "Session %p\n", ptr);
dcb_printf(dcb, "\tState: %s\n", session_state(ptr->state));
dcb_printf(dcb, "\tService: %s (%p)\n", ptr->service->name, ptr->service);
dcb_printf(dcb, "\tClient DCB: %p\n", ptr->client);
if (ptr->client && ptr->client->remote)
@ -222,6 +224,8 @@ session_state(int state)
return "Session Ready";
case SESSION_STATE_LISTENER:
return "Listener Session";
case SESSION_STATE_LISTENER_STOPPED:
return "Stopped Listener Session";
default:
return "Invalid State";
}

View File

@ -49,8 +49,9 @@ pthread_t thd;
}
/**
* Wait for all running threads to complete.
* Wait for a running threads to complete.
*
* @param thd The thread handle
*/
void
thread_wait(void *thd)

View File

@ -31,10 +31,12 @@
* @endverbatim
*/
#define MAX_EVENTS 1000
#define EPOLL_TIMEOUT 1000 /**< The epoll timeout we use (milliseconds) */
extern void poll_init();
extern int poll_add_dcb(DCB *);
extern int poll_remove_dcb(DCB *);
extern void poll_waitevents();
extern void poll_shutdown();
extern void dprintPollStats(DCB *);
#endif

View File

@ -112,6 +112,8 @@ extern int serviceAddProtocol(SERVICE *, char *, unsigned short);
extern void serviceAddBackend(SERVICE *, SERVER *);
extern int serviceStart(SERVICE *);
extern int serviceStartAll();
extern int serviceStop(SERVICE *);
extern int serviceRestart(SERVICE *);
extern int serviceSetUser(SERVICE *, char *, char *);
extern int serviceGetUser(SERVICE *, char **, char **);
extern void printService(SERVICE *);

View File

@ -60,9 +60,10 @@ typedef struct session {
struct session *next; /**< Linked list of all sessions */
} SESSION;
#define SESSION_STATE_ALLOC 0
#define SESSION_STATE_READY 1
#define SESSION_STATE_LISTENER 2
#define SESSION_STATE_ALLOC 0 /**< The session has been allocated */
#define SESSION_STATE_READY 1 /**< The session is ready to route queries */
#define SESSION_STATE_LISTENER 2 /**< The session is a running listener */
#define SESSION_STATE_LISTENER_STOPPED 3 /**< The session listener is stopped */
#define SESSION_PROTOCOL(x, type) DCB_PROTOCOL((x)->client, type)

View File

@ -28,7 +28,7 @@ MYSQLBACKENDSRCS=mysql_backend.c mysql_common.c
MYSQLBACKENDOBJ=$(MYSQLBACKENDSRCS:.c=.o)
TELNETDSRCS=telnetd.c
TELNETDOBJ=$(TELNETDSRCS:.c=.o)
SRCS=$(MYSQLCLIENTSRCS) $(MYSQLBACKENDSRCS)
SRCS=$(MYSQLCLIENTSRCS) $(MYSQLBACKENDSRCS) $(TELNETDSRCS)
OBJ=$(SRCS:.c=.o)
LIBS=
MODULES=libMySQLClient.so libMySQLBackend.so libtelnetd.so

View File

@ -80,6 +80,27 @@ struct subcommand showoptions[] = {
{ NULL, 0, NULL, NULL }
};
extern void shutdown_gateway();
static void shutdown_service(DCB *dcb, SERVICE *service);
/**
* The subcommands of the shutdown command
*/
struct subcommand shutdownoptions[] = {
{ "gateway", 0, shutdown_gateway, "Shutdown the gateway" },
{ "service", 1, shutdown_service, "Shutdown a service, e.g. shutdown service 0x4838320" },
{ NULL, 0, NULL, NULL }
};
static void restart_service(DCB *dcb, SERVICE *service);
/**
* The subcommands of the restart command
*/
struct subcommand restartoptions[] = {
{ "service", 1, restart_service, "Restart a service, e.g. restart service 0x4838320" },
{ NULL, 0, NULL, NULL }
};
/**
* The debug command table
*/
@ -88,6 +109,8 @@ static struct {
struct subcommand *options;
} cmds[] = {
{ "show", showoptions },
{ "shutdown", shutdownoptions },
{ "restart", restartoptions },
{ NULL, NULL }
};
@ -230,3 +253,27 @@ char *saveptr, *delim = " \t\r\n";
return 1;
}
/**
* Debug command to stop a service
*
* @param dcb The DCB to print any output to
* @param service The service to shutdown
*/
static void
shutdown_service(DCB *dcb, SERVICE *service)
{
serviceStop(service);
}
/**
* Debug command to restart a stopped service
*
* @param dcb The DCB to print any output to
* @param service The service to restart
*/
static void
restart_service(DCB *dcb, SERVICE *service)
{
serviceRestart(service);
}