Project

General

Profile

0005-server.c-support-i-secs-idle-timeout-option_patch.txt

mackyle, 2015-12-05 01:23

 
1
From adedac4902838db25ae8897337674ac334e61126 Mon Sep 17 00:00:00 2001
2
From: "Kyle J. McKay" <mackyle@gmail.com>
3
Date: Fri, 4 Dec 2015 16:45:26 -0800
4
Subject: [PATCH] server.c: support -i <secs> idle timeout option
5

    
6
After <secs> of no activity the server will initiate a graceful
7
shutdown.  Defaults to off (0).
8

    
9
Signed-off-by: Kyle J. McKay <mackyle@gmail.com>
10
---
11
 src/server.c | 44 ++++++++++++++++++++++++++++++++++++--------
12
 1 file changed, 36 insertions(+), 8 deletions(-)
13

    
14
diff --git a/src/server.c b/src/server.c
15
index 2764c9a5..d36fce18 100644
16
--- a/src/server.c
17
+++ b/src/server.c
18
@@ -531,6 +531,7 @@ static void show_help (void) {
19
 "usage:\n" \
20
 " -f <name>  filename of the config-file\n" \
21
 " -m <name>  module directory (default: "LIBRARY_DIR")\n" \
22
+" -i <secs>  graceful shutdown after <secs> of inactivity\n" \
23
 " -p         print the parsed config-file in internal form, and exit\n" \
24
 " -t         test the config-file, and exit\n" \
25
 " -D         don't go to background (default: go to background)\n" \
26
@@ -553,6 +554,8 @@ int main (int argc, char **argv) {
27
 	int num_childs = 0;
28
 	int pid_fd = -1, fd;
29
 	size_t i;
30
+	time_t idle_timeout = 0, server_activity = time(NULL);
31
+	int timed_out = 0;
32
 #ifdef HAVE_SIGACTION
33
 	struct sigaction act;
34
 #endif
35
@@ -588,7 +591,7 @@ int main (int argc, char **argv) {
36
 #endif
37
 	srv->srvconf.dont_daemonize = 0;
38
 
39
-	while(-1 != (o = getopt(argc, argv, "f:m:hvVDpt"))) {
40
+	while(-1 != (o = getopt(argc, argv, "f:m:i:hvVDpt"))) {
41
 		switch(o) {
42
 		case 'f':
43
 			if (srv->config_storage) {
44
@@ -606,6 +609,18 @@ int main (int argc, char **argv) {
45
 		case 'm':
46
 			buffer_copy_string(srv->srvconf.modules_dir, optarg);
47
 			break;
48
+		case 'i': {
49
+			char *endptr;
50
+			long timeout = strtol(optarg, &endptr, 0);
51
+			if (!*optarg || *endptr || timeout < 0) {
52
+				log_error_write(srv, __FILE__, __LINE__, "ss",
53
+						"Invalid idle timeout value:", optarg);
54
+				server_free(srv);
55
+				return -1;
56
+			}
57
+			idle_timeout = (time_t)timeout;
58
+			break;
59
+		}
60
 		case 'p': print_config = 1; break;
61
 		case 't': test_config = 1; break;
62
 		case 'D': srv->srvconf.dont_daemonize = 1; break;
63
@@ -1506,6 +1521,7 @@ int main (int argc, char **argv) {
64
 						"polls:", n);
65
 			}
66
 #endif
67
+			server_activity = time(NULL);
68
 			fd_ndx = -1;
69
 			do {
70
 				fdevent_handler handler;
71
@@ -1546,6 +1562,13 @@ int main (int argc, char **argv) {
72
 					strerror(errno));
73
 		}
74
 
75
+		if (idle_timeout && !graceful_shutdown && time(NULL) - server_activity >= idle_timeout) {
76
+			log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_timeout,
77
+					"s exceeded, initiating graceful shutdown");
78
+			timed_out = 1;
79
+			graceful_shutdown = 1;
80
+		}
81
+
82
 		for (ndx = 0; ndx < srv->joblist->used; ndx++) {
83
 			connection *con = srv->joblist->ptr[ndx];
84
 			handler_t r;
85
@@ -1595,16 +1618,21 @@ int main (int argc, char **argv) {
86
 		}
87
 	}
88
 
89
+	if (timed_out) {
90
+		log_error_write(srv, __FILE__, __LINE__, "s",
91
+				"server stopped by idle timeout");
92
+	} else {
93
 #ifdef HAVE_SIGACTION
94
-	log_error_write(srv, __FILE__, __LINE__, "sdsd", 
95
-			"server stopped by UID =",
96
-			last_sigterm_info.si_uid,
97
-			"PID =",
98
-			last_sigterm_info.si_pid);
99
+		log_error_write(srv, __FILE__, __LINE__, "sdsd",
100
+				"server stopped by UID =",
101
+				last_sigterm_info.si_uid,
102
+				"PID =",
103
+				last_sigterm_info.si_pid);
104
 #else
105
-	log_error_write(srv, __FILE__, __LINE__, "s", 
106
-			"server stopped");
107
+		log_error_write(srv, __FILE__, __LINE__, "s",
108
+				"server stopped");
109
 #endif
110
+	}
111
 
112
 	/* clean-up */
113
 	log_error_close(srv);
114
-- 
115
2.4.10
116