|
diff --git a/src/server.c b/src/server.c
|
|
index 26ecbcc..fd07c85 100644
|
|
--- a/src/server.c
|
|
+++ b/src/server.c
|
|
@@ -530,6 +530,7 @@ static void show_help (void) {
|
|
"usage:\n" \
|
|
" -f <name> filename of the config-file\n" \
|
|
" -m <name> module directory (default: "LIBRARY_DIR")\n" \
|
|
+" -i <secs> graceful shutdown after <secs> 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" \
|
|
@@ -552,6 +553,7 @@ int main (int argc, char **argv) {
|
|
int num_childs = 0;
|
|
int pid_fd = -1, fd;
|
|
size_t i;
|
|
+ time_t idle_limit = 0, last_active_ts = time(NULL);
|
|
#ifdef HAVE_SIGACTION
|
|
struct sigaction act;
|
|
#endif
|
|
@@ -587,7 +589,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) {
|
|
@@ -605,6 +607,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_limit = (time_t)timeout;
|
|
+ break;
|
|
+ }
|
|
case 'p': print_config = 1; break;
|
|
case 't': test_config = 1; break;
|
|
case 'D': srv->srvconf.dont_daemonize = 1; break;
|
|
@@ -1082,6 +1096,11 @@ int main (int argc, char **argv) {
|
|
num_childs = srv->srvconf.max_worker;
|
|
if (num_childs > 0) {
|
|
int child = 0;
|
|
+ if (idle_limit) {
|
|
+ idle_limit = 0;
|
|
+ log_error_write(srv, __FILE__, __LINE__, "s",
|
|
+ "server idle time limit disabled with server.max-worker (combination not supported).");
|
|
+ }
|
|
while (!child && !srv_shutdown && !graceful_shutdown) {
|
|
if (num_childs > 0) {
|
|
switch (fork()) {
|
|
@@ -1291,6 +1310,13 @@ int main (int argc, char **argv) {
|
|
/* trigger waitpid */
|
|
srv->cur_ts = min_ts;
|
|
|
|
+ /* check idle time limit, if enabled */
|
|
+ if (idle_limit && idle_limit < min_ts - last_active_ts && !graceful_shutdown) {
|
|
+ log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_limit,
|
|
+ "s exceeded, initiating graceful shutdown");
|
|
+ graceful_shutdown = 2; /* value 2 indicates idle timeout */
|
|
+ }
|
|
+
|
|
/* cleanup stat-cache */
|
|
stat_cache_trigger_cleanup(srv);
|
|
/**
|
|
@@ -1493,6 +1519,7 @@ int main (int argc, char **argv) {
|
|
"polls:", n);
|
|
}
|
|
#endif
|
|
+ last_active_ts = srv->cur_ts;
|
|
fd_ndx = -1;
|
|
do {
|
|
fdevent_handler handler;
|
|
@@ -1568,16 +1595,21 @@ int main (int argc, char **argv) {
|
|
}
|
|
}
|
|
|
|
+ if (2 == graceful_shutdown) { /* value 2 indicates idle timeout */
|
|
+ log_error_write(srv, __FILE__, __LINE__, "s",
|
|
+ "server stopped after 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);
|