Project

General

Profile

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

mackyle, 2015-12-03 23:09

 
1
From 476d2d789b68991c899f5fc63da108f402ed20db Mon Sep 17 00:00:00 2001
2
From: "Kyle J. McKay" <mackyle@gmail.com>
3
Date: Thu, 3 Dec 2015 11:20:38 -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 | 49 +++++++++++++++++++++++++++++++++++++++----------
12
 1 file changed, 39 insertions(+), 10 deletions(-)
13

    
14
diff --git a/src/server.c b/src/server.c
15
index 6200c94c..9c9840f5 100644
16
--- a/src/server.c
17
+++ b/src/server.c
18
@@ -526,6 +526,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
@@ -548,6 +549,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
@@ -583,7 +586,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
@@ -601,6 +604,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
@@ -1487,6 +1502,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
@@ -1527,6 +1543,14 @@ int main (int argc, char **argv) {
72
 					strerror(errno));
73
 		}
74
 
75
+		if (idle_timeout && time(NULL) - server_activity >= idle_timeout) {
76
+			log_error_write(srv, __FILE__, __LINE__, "sDs", "[note] idle timeout", (int)idle_timeout,
77
+					"s exceeded, graceful shutdown started");
78
+			timed_out = 1;
79
+			graceful_shutdown = 1;
80
+			break;
81
+		}
82
+
83
 		for (ndx = 0; ndx < srv->joblist->used; ndx++) {
84
 			connection *con = srv->joblist->ptr[ndx];
85
 			handler_t r;
86
@@ -1549,7 +1573,7 @@ int main (int argc, char **argv) {
87
 	}
88
 
89
 	if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
90
-	    0 == graceful_shutdown && 0 <= pid_fd) {
91
+	    (0 == graceful_shutdown || timed_out) && 0 <= pid_fd) {
92
 		if (0 != ftruncate(pid_fd, 0)) {
93
 			log_error_write(srv, __FILE__, __LINE__, "sbds",
94
 					"ftruncate failed for:",
95
@@ -1564,7 +1588,7 @@ int main (int argc, char **argv) {
96
 	}
97
 	if (!buffer_string_is_empty(srv->srvconf.pid_file) &&
98
 	    buffer_string_is_empty(srv->srvconf.changeroot) &&
99
-	    0 == graceful_shutdown) {
100
+	    (0 == graceful_shutdown || timed_out)) {
101
 		if (0 != unlink(srv->srvconf.pid_file->ptr)) {
102
 			if (errno != EACCES && errno != EPERM) {
103
 				log_error_write(srv, __FILE__, __LINE__, "sbds",
104
@@ -1576,16 +1600,21 @@ int main (int argc, char **argv) {
105
 		}
106
 	}
107
 
108
+	if (timed_out) {
109
+		log_error_write(srv, __FILE__, __LINE__, "s",
110
+				"server stopped by idle timeout");
111
+	} else {
112
 #ifdef HAVE_SIGACTION
113
-	log_error_write(srv, __FILE__, __LINE__, "sdsd", 
114
-			"server stopped by UID =",
115
-			last_sigterm_info.si_uid,
116
-			"PID =",
117
-			last_sigterm_info.si_pid);
118
+		log_error_write(srv, __FILE__, __LINE__, "sdsd",
119
+				"server stopped by UID =",
120
+				last_sigterm_info.si_uid,
121
+				"PID =",
122
+				last_sigterm_info.si_pid);
123
 #else
124
-	log_error_write(srv, __FILE__, __LINE__, "s", 
125
-			"server stopped");
126
+		log_error_write(srv, __FILE__, __LINE__, "s",
127
+				"server stopped");
128
 #endif
129
+	}
130
 
131
 	/* clean-up */
132
 	log_error_close(srv);
133
-- 
134
2.4.10
135