From adedac4902838db25ae8897337674ac334e61126 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Fri, 4 Dec 2015 16:45:26 -0800 Subject: [PATCH] server.c: support -i idle timeout option After of no activity the server will initiate a graceful shutdown. Defaults to off (0). Signed-off-by: Kyle J. McKay --- src/server.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/server.c b/src/server.c index 2764c9a5..d36fce18 100644 --- a/src/server.c +++ b/src/server.c @@ -531,6 +531,7 @@ static void show_help (void) { "usage:\n" \ " -f filename of the config-file\n" \ " -m module directory (default: "LIBRARY_DIR")\n" \ +" -i graceful shutdown after of inactivity\n" \ " -p print the parsed config-file in internal form, and exit\n" \ " -t test the config-file, and exit\n" \ " -D don't go to background (default: go to background)\n" \ @@ -553,6 +554,8 @@ int main (int argc, char **argv) { int num_childs = 0; int pid_fd = -1, fd; size_t i; + time_t idle_timeout = 0, server_activity = time(NULL); + int timed_out = 0; #ifdef HAVE_SIGACTION struct sigaction act; #endif @@ -588,7 +591,7 @@ int main (int argc, char **argv) { #endif srv->srvconf.dont_daemonize = 0; - while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) { + while(-1 != (o = getopt(argc, argv, "f:m:i:hvVDpt"))) { switch(o) { case 'f': if (srv->config_storage) { @@ -606,6 +609,18 @@ int main (int argc, char **argv) { case 'm': buffer_copy_string(srv->srvconf.modules_dir, optarg); break; + case 'i': { + char *endptr; + long timeout = strtol(optarg, &endptr, 0); + if (!*optarg || *endptr || timeout < 0) { + log_error_write(srv, __FILE__, __LINE__, "ss", + "Invalid idle timeout value:", optarg); + server_free(srv); + return -1; + } + idle_timeout = (time_t)timeout; + break; + } case 'p': print_config = 1; break; case 't': test_config = 1; break; case 'D': srv->srvconf.dont_daemonize = 1; break; @@ -1506,6 +1521,7 @@ int main (int argc, char **argv) { "polls:", n); } #endif + server_activity = time(NULL); fd_ndx = -1; do { fdevent_handler handler; @@ -1546,6 +1562,13 @@ int main (int argc, char **argv) { strerror(errno)); } + if (idle_timeout && !graceful_shutdown && time(NULL) - server_activity >= idle_timeout) { + log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_timeout, + "s exceeded, initiating graceful shutdown"); + timed_out = 1; + graceful_shutdown = 1; + } + for (ndx = 0; ndx < srv->joblist->used; ndx++) { connection *con = srv->joblist->ptr[ndx]; handler_t r; @@ -1595,16 +1618,21 @@ int main (int argc, char **argv) { } } + if (timed_out) { + log_error_write(srv, __FILE__, __LINE__, "s", + "server stopped by idle timeout"); + } else { #ifdef HAVE_SIGACTION - log_error_write(srv, __FILE__, __LINE__, "sdsd", - "server stopped by UID =", - last_sigterm_info.si_uid, - "PID =", - last_sigterm_info.si_pid); + log_error_write(srv, __FILE__, __LINE__, "sdsd", + "server stopped by UID =", + last_sigterm_info.si_uid, + "PID =", + last_sigterm_info.si_pid); #else - log_error_write(srv, __FILE__, __LINE__, "s", - "server stopped"); + log_error_write(srv, __FILE__, __LINE__, "s", + "server stopped"); #endif + } /* clean-up */ log_error_close(srv); -- 2.4.10