瀏覽代碼

- log messages in children signal handlers off if NO_SIG_DEBUG
is defined (safer, but not default for now)
- new config param.: exit_timeout (how much time ser will wait for
its shutdown to complete, when it expires it will kill everything)
- missing timeout added to SIGTERM triggered shutdown

Andrei Pelinescu-Onciul 19 年之前
父節點
當前提交
96d091075b
共有 8 個文件被更改,包括 63 次插入13 次删除
  1. 6 2
      Makefile.defs
  2. 8 3
      NEWS
  3. 3 0
      cfg.lex
  4. 3 0
      cfg.y
  5. 1 1
      config.h
  6. 6 0
      dprint.h
  7. 3 0
      globals.h
  8. 33 7
      main.c

+ 6 - 2
Makefile.defs

@@ -67,7 +67,7 @@ MAIN_NAME=ser
 VERSION = 0
 PATCHLEVEL = 10
 SUBLEVEL =   99
-EXTRAVERSION = -dev53-tm_fixes
+EXTRAVERSION = -dev54-tm_fixes
 
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
 			$(SUBLEVEL) )
@@ -353,6 +353,9 @@ endif
 #		Don't forget to set PROFILE (see below)
 # -DUSE_STUN
 #		compiles in stun support
+# -DNO_SIG_DEBUG
+#        turns off debugging messages in signal handlers (which might be 
+#         unsafe)
 
 # Sometimes is needes correct non-quoted $OS. HACK: gcc translates known OS to number ('linux'), so there is added underscore
 
@@ -383,7 +386,8 @@ DEFS+= $(extra_defs) \
 	 #-DUSE_SHM_MEM \
 	 #-DSTATS \
 	 #-DNO_LOG \
-	 #-DPROFILING
+	 #-DPROFILING \
+	 #-DNO_SIG_DEBUG
 
 #PROFILE=  -pg	# set this if you want profiling
 				# you may also want to set -DPROFILING

+ 8 - 3
NEWS

@@ -177,9 +177,14 @@ core:
    are available (see tm docs)
 - avps directly accessible from script with %avp_name (variable style)
 new config variables:
-   stun_refresh_interval = number in milisecond (default 0); value for attribute
-       REFRESH INTERVAL
-   stun_allow_stun = 0 | 1 (off | on - defaul 1); use STUN or not if compiled
+   exit_timeout = seconds - how much time ser will wait for all the shutdown
+       procedures to complete. If this time is exceeded, all the remaining
+       processes are immediately killed and ser exits immediately (it might
+       also generate a core dump if the cleanup part takes too long).
+       Default: 60 s. Use 0 to disable.
+   stun_refresh_interval = number in millisecond (default 0); value for 
+      attribute REFRESH INTERVAL
+   stun_allow_stun = 0 | 1 (off | on - default 1); use STUN or not if compiled
    stun_allow_fp = 0 | 1 (off | on - default 1); use FINGERPRINT attribute
    use_dns_cache = on | off  (default on)  
    use_dns_failover = on | off (default off)

+ 3 - 0
cfg.lex

@@ -290,6 +290,7 @@ OPEN_FD_LIMIT		"open_files_limit"
 MCAST_LOOPBACK		"mcast_loopback"
 MCAST_TTL		"mcast_ttl"
 TOS			"tos"
+KILL_TIMEOUT	"exit_timeout"|"ser_kill_timeout"
 
 /* stun config variables */
 STUN_REFRESH_INTERVAL "stun_refresh_interval"
@@ -532,6 +533,8 @@ EAT_ABLE	[\ \t\b\r]
 									return MCAST_TTL; }
 <INITIAL>{TOS}			{	count(); yylval.strval=yytext;
 									return TOS; }
+<INITIAL>{KILL_TIMEOUT}			{	count(); yylval.strval=yytext;
+									return KILL_TIMEOUT; }
 <INITIAL>{LOADMODULE}	{ count(); yylval.strval=yytext; return LOADMODULE; }
 <INITIAL>{MODPARAM}     { count(); yylval.strval=yytext; return MODPARAM; }
 

+ 3 - 0
cfg.y

@@ -320,6 +320,7 @@ static struct socket_id* mk_listen_id(char*, int, int);
 %token MCAST_LOOPBACK
 %token MCAST_TTL
 %token TOS
+%token KILL_TIMEOUT
 
 %token FLAGS_DECL
 %token AVPFLAGS_DECL
@@ -869,6 +870,8 @@ assign_stm:
 	| MCAST_TTL EQUAL error { yyerror("number expected"); }
 	| TOS EQUAL NUMBER { tos=$3; }
 	| TOS EQUAL error { yyerror("number expected"); }
+	| KILL_TIMEOUT EQUAL NUMBER { ser_kill_timeout=$3; }
+	| KILL_TIMEOUT EQUAL error { yyerror("number expected"); }
 	| STUN_REFRESH_INTERVAL EQUAL NUMBER { 
 		#ifdef USE_STUN
 			stun_refresh_interval=$3;

+ 1 - 1
config.h

@@ -180,7 +180,7 @@
 								+ 1 /*sep*/ + 8 /*int2hex*/ + \
 								1 /*extra space, needed by t_calc_branch*/)
 
-
+#define DEFAULT_SER_KILL_TIMEOUT 60 /* seconds */
 
 /* maximum path length */
 #define PATH_MAX_GUESS	1024

+ 6 - 0
dprint.h

@@ -50,9 +50,15 @@ extern int log_facility;
 extern volatile int dprint_crit; /* protection against "simultaneous"
 									printing from signal handlers */
 
+#ifdef NO_SIG_DEBUG
+#define DPRINT_NON_CRIT		(1)
+#define DPRINT_CRIT_ENTER
+#define DPRINT_CRIT_EXIT
+#else
 #define DPRINT_NON_CRIT		(dprint_crit==0)
 #define DPRINT_CRIT_ENTER	(dprint_crit++)
 #define DPRINT_CRIT_EXIT	(dprint_crit--)
+#endif
 
 #define DPRINT_LEV	1
 /* priority at which we log */

+ 3 - 0
globals.h

@@ -166,6 +166,9 @@ extern str default_global_address;
 /* pre-ser ports */
 extern str default_global_port;
 
+/* how much time to allow for shutdown, before killing everything */
+int ser_kill_timeout;
+
 /* core dump and file limits */
 extern int disable_core_dump;
 extern int open_files_limit;

+ 33 - 7
main.c

@@ -63,7 +63,9 @@
  *  2005-07-25  use sigaction for setting the signal handlers (andrei)
  *  2006-07-13  added dns cache/failover init. (andrei)
  *  2006-10-13  added global variables stun_refresh_interval, stun_allow_stun
- *              and stun_allow_fp (vlada)
+ *               and stun_allow_fp (vlada)
+ *  2006-10-25  don't log messages from signal hanlders if NO_SIG_DEBUG is
+ *               defined; improved exit kill timeout (andrei)
  */
 
 
@@ -146,6 +148,13 @@
 #endif
 #include "version.h"
 
+/* define SIG_DEBUG by default */
+#ifdef NO_SIG_DEBUG
+#undef SIG_DEBUG
+#else
+#define SIG_DEBUG
+#endif
+
 static char id[]="@(#) $Id$";
 static char* version=SER_FULL_VERSION;
 static char* flags=SER_COMPILE_FLAGS;
@@ -369,6 +378,9 @@ struct host_alias* aliases=0; /* name aliases list */
 /* Parameter to child_init */
 int child_rank = 0;
 
+/* how much to wait for children to terminate, before taking extreme measures*/
+int ser_kill_timeout=DEFAULT_SER_KILL_TIMEOUT;
+
 /* process_bm_t process_bit = 0; */
 #ifdef ROUTE_SRV
 #endif
@@ -523,11 +535,17 @@ void handle_sigs()
 
 			/* first of all, kill the children also */
 			kill_all_children(SIGTERM);
-
-			     /* Wait for all the children to die */
-			while(wait(0) > 0);
-
+			if (set_sig_h(SIGALRM, sig_alarm_kill) == SIG_ERR ) {
+				LOG(L_ERR, "ERROR: could not install SIGALARM handler\n");
+				/* continue, the process will die anyway if no
+				 * alarm is installed which is exactly what we want */
+			}
+			alarm(ser_kill_timeout);
+			/* Wait for all the children to die */
+			while((wait(0) > 0) || (errno==EINTR));
+			set_sig_h(SIGALRM, sig_alarm_abort);
 			cleanup(1); /* cleanup & show status*/
+			alarm(0);
 			dprint("Thank you for flying " NAME "\n");
 			exit(0);
 			break;
@@ -578,8 +596,9 @@ void handle_sigs()
 				/* continue, the process will die anyway if no
 				 * alarm is installed which is exactly what we want */
 			}
-			alarm(60); /* 1 minute close timeout */
-			while(wait(0) > 0); /* wait for all the children to terminate*/
+			alarm(ser_kill_timeout);
+			while((wait(0) > 0) || (errno==EINTR)); /* wait for all the 
+													   children to terminate*/
 			set_sig_h(SIGALRM, sig_alarm_abort);
 			cleanup(1); /* cleanup & show status*/
 			alarm(0);
@@ -621,16 +640,20 @@ static void sig_usr(int signo)
 		/* process the important signals */
 		switch(signo){
 			case SIGPIPE:
+#ifdef SIG_DEBUG /* signal unsafe stuff follows */
 					LOG(L_INFO, "INFO: signal %d received\n", signo);
+#endif
 				break;
 			case SIGINT:
 			case SIGTERM:
+#ifdef SIG_DEBUG /* signal unsafe stuff follows */
 					LOG(L_INFO, "INFO: signal %d received\n", signo);
 					/* print memory stats for non-main too */
 					#ifdef PKG_MALLOC
 					LOG(memlog, "Memory status (pkg):\n");
 					pkg_status();
 					#endif
+#endif
 					exit(0);
 					break;
 			case SIGUSR1:
@@ -642,11 +665,14 @@ static void sig_usr(int signo)
 					break;
 			case SIGCHLD:
 #ifndef 			STOP_JIRIS_CHANGES
+#ifdef SIG_DEBUG /* signal unsafe stuff follows */
 					DBG("SIGCHLD received: "
 						"we do not worry about grand-children\n");
+#endif
 #else
 					exit(0); /* terminate if one child died */
 #endif
+					break;
 		}
 	}
 }