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:
parent
72223fd4cf
commit
34fdbdb34d
@ -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 \
|
||||
|
@ -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();
|
||||
}
|
||||
|
26
core/poll.c
26
core/poll.c
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user