Browse code

- init_childs(PROC_MAIN) moved before starting tcp_main to allow possible tcp usage from module started processes - fork_process() sanity checks & debugging: fail & log a bug if called with make_sock==1 from a process != main or if called after tcp was started; reset is_main for children - fork_tcp_process() sanity checks as above - init_pt(): initialize tcp comm. fds to -1, fix description writing for main/attendant.

Andrei Pelinescu-Onciul authored on 25/10/2006 18:44:36
Showing 4 changed files
... ...
@@ -67,7 +67,7 @@ MAIN_NAME=ser
67 67
 VERSION = 0
68 68
 PATCHLEVEL = 10
69 69
 SUBLEVEL =   99
70
-EXTRAVERSION = -dev54-tm_fixes
70
+EXTRAVERSION = -dev55-tm_fixes
71 71
 
72 72
 SER_VER = $(shell expr $(VERSION) \* 1000000 + $(PATCHLEVEL) \* 1000 + \
73 73
 			$(SUBLEVEL) )
... ...
@@ -76,6 +76,7 @@ extern struct socket_info* sendipv6_tls; /* same as above for ipv6 */
76 76
 extern unsigned int maxbuffer;
77 77
 extern int children_no;
78 78
 #ifdef USE_TCP
79
+extern int tcp_main_pid;
79 80
 extern int tcp_children_no;
80 81
 extern int tcp_disable;
81 82
 extern int tcp_accept_aliases;
... ...
@@ -64,8 +64,10 @@
64 64
  *  2006-07-13  added dns cache/failover init. (andrei)
65 65
  *  2006-10-13  added global variables stun_refresh_interval, stun_allow_stun
66 66
  *               and stun_allow_fp (vlada)
67
- *  2006-10-25  don't log messages from signal hanlders if NO_SIG_DEBUG is
67
+ *  2006-10-25  don't log messages from signal handlers if NO_SIG_DEBUG is
68 68
  *               defined; improved exit kill timeout (andrei)
69
+ *              init_childs(PROC_MAIN) before starting tcp_main, to allow
70
+ *               tcp usage for module started processes (andrei)
69 71
  */
70 72
 
71 73
 
... ...
@@ -341,6 +343,7 @@ int addresses_no=0;                   /* number of names/ips */
341 341
 #endif
342 342
 struct socket_info* udp_listen=0;
343 343
 #ifdef USE_TCP
344
+int tcp_main_pid=0; /* set after the tcp main process is started */
344 345
 struct socket_info* tcp_listen=0;
345 346
 #endif
346 347
 #ifdef USE_TLS
... ...
@@ -489,7 +492,7 @@ static void kill_all_children(int signum)
489 489
 
490 490
 
491 491
 
492
-/* if this handler is called, a critical timeout has occured while
492
+/* if this handler is called, a critical timeout has occurred while
493 493
  * waiting for the children to finish => we should kill everything and exit */
494 494
 static void sig_alarm_kill(int signo)
495 495
 {
... ...
@@ -501,7 +504,7 @@ static void sig_alarm_kill(int signo)
501 501
 }
502 502
 
503 503
 
504
-/* like sig_alarm_kill, but the timeout has occured when cleaning up
504
+/* like sig_alarm_kill, but the timeout has occurred when cleaning up
505 505
  * => try to leave a core for future diagnostics */
506 506
 static void sig_alarm_abort(int signo)
507 507
 {
... ...
@@ -848,8 +851,6 @@ int main_loop()
848 848
 #endif
849 849
 
850 850
 	/* one "main" process and n children handling i/o */
851
-
852
-	is_main=0;
853 851
 	if (dont_fork){
854 852
 #ifdef STATS
855 853
 		setstats( 0 );
... ...
@@ -922,10 +923,6 @@ int main_loop()
922 922
 			LOG(L_ERR, "main_dontfork: init_child failed\n");
923 923
 			goto error;
924 924
 		}
925
-
926
-		is_main=1; /* hack 42: call init_child with is_main=0 in case
927
-					 some modules wants to fork a child */
928
-
929 925
 		return udp_rcv_loop();
930 926
 	}else{
931 927
 
... ...
@@ -1018,7 +1015,6 @@ int main_loop()
1018 1018
 			goto error;
1019 1019
 		}else if (pid==0){
1020 1020
 			/* child */
1021
-			/* is_main=0; */
1022 1021
 			if (arm_slow_timer()<0) goto error;
1023 1022
 			slow_timer_main();
1024 1023
 		}else{
... ...
@@ -1033,12 +1029,20 @@ int main_loop()
1033 1033
 			goto error;
1034 1034
 		}else if (pid==0){
1035 1035
 			/* child */
1036
-			/* is_main=0; */
1037 1036
 			if (arm_timer()<0) goto error;
1038 1037
 			timer_main();
1039 1038
 		}else{
1040 1039
 		}
1041 1040
 	}
1041
+
1042
+/* init childs with rank==MAIN before starting tcp main (in case they want to 
1043
+ *  fork  a tcp capable process, the corresponding tcp. comm. fds in pt[] must
1044
+ *  be set before calling tcp_main_loop()) */
1045
+	if (init_child(PROC_MAIN) < 0) {
1046
+		LOG(L_ERR, "main: error in init_child\n");
1047
+		goto error;
1048
+	}
1049
+
1042 1050
 #ifdef USE_TCP
1043 1051
 		if (!tcp_disable){
1044 1052
 				/* start tcp  & tls receivers */
... ...
@@ -1053,6 +1057,7 @@ int main_loop()
1053 1053
 				/* child */
1054 1054
 				tcp_main_loop();
1055 1055
 			}else{
1056
+				tcp_main_pid=pid;
1056 1057
 				unix_tcp_sock=-1;
1057 1058
 			}
1058 1059
 		}
... ...
@@ -1061,20 +1066,10 @@ int main_loop()
1061 1061
 	strncpy(pt[0].desc, "attendant", MAX_PT_DESC );
1062 1062
 #ifdef USE_TCP
1063 1063
 	if(!tcp_disable){
1064
-		pt[process_no].unix_sock=-1;
1065
-		pt[process_no].idx=-1; /* this is not a "tcp" process*/
1064
+		/* main's tcp sockets are disabled by default from init_pt() */
1066 1065
 		unix_tcp_sock=-1;
1067 1066
 	}
1068 1067
 #endif
1069
-	/*DEBUG- remove it*/
1070
-
1071
-	/* process_bit = 0; */
1072
-	is_main=1;
1073
-
1074
-	if (init_child(PROC_MAIN) < 0) {
1075
-		LOG(L_ERR, "main: error in init_child\n");
1076
-		goto error;
1077
-	}
1078 1068
 
1079 1069
 	/*DEBUG- remove it*/
1080 1070
 #ifdef EXTRA_DEBUG
... ...
@@ -1091,7 +1086,7 @@ int main_loop()
1091 1091
 
1092 1092
 	/*return 0; */
1093 1093
  error:
1094
-	is_main=1;  /* if we are here, we are the "main process",
1094
+				 /* if we are here, we are the "main process",
1095 1095
 				  any forked children should exit with exit(-1) and not
1096 1096
 				  ever use return */
1097 1097
 	return -1;
... ...
@@ -33,6 +33,8 @@
33 33
  * --------
34 34
  *  2006-06-14	added process table in shared mem (dragos)
35 35
  *  2006-09-20	added profile support (-DPROFILING) (hscholz)
36
+ *  2006-10-25	sanity check before allowing forking w/ tcp support (is_main
37
+ *               & tcp not started yet); set is_main=0 in childs (andrei)
36 38
  */
37 39
 
38 40
 
... ...
@@ -60,6 +62,10 @@ static int estimated_proc_no=0;
60 60
 /* returns 0 on success, -1 on error */
61 61
 int init_pt(int proc_no)
62 62
 {
63
+#ifdef USE_TCP
64
+	int r;
65
+#endif
66
+	
63 67
 	estimated_proc_no+=proc_no;
64 68
 	/*alloc pids*/
65 69
 #ifdef SHM_MEM
... ...
@@ -76,10 +82,15 @@ int init_pt(int proc_no)
76 76
 		return -1;
77 77
 	}
78 78
 	memset(pt, 0, sizeof(struct process_table)*estimated_proc_no);
79
-
79
+#ifdef USE_TCP
80
+	for (r=0; r<estimated_proc_no; r++){
81
+		pt[r].unix_sock=-1;
82
+		pt[r].idx=-1;
83
+	}
84
+#endif
80 85
 	process_no=0; /*main process number*/
81 86
 	pt[process_no].pid=getpid();
82
-	memcpy(pt[*process_count].desc,"main",5);
87
+	memcpy(pt[process_no].desc,"main",5);
83 88
 	*process_count=1;
84 89
 	return 0;
85 90
 }
... ...
@@ -136,6 +147,18 @@ int fork_process(int child_id, char *desc, int make_sock)
136 136
 	#ifdef USE_TCP
137 137
 		sockfd[0]=sockfd[1]=-1;
138 138
 		if(make_sock && !tcp_disable){
139
+			 if (!is_main){
140
+				 LOG(L_CRIT, "BUG: fork_process(..., 1) called from a non "
141
+						 "\"main\" process! If forking from a module's "
142
+						 "child_init() fork only if rank==PROC_MAIN or"
143
+						 " give up tcp send support (use 0 for make_sock)\n");
144
+				 goto error;
145
+			 }
146
+			 if (tcp_main_pid){
147
+				 LOG(L_CRIT, "BUG: fork_process(..., 1) called, but tcp main "
148
+						 " is already started\n");
149
+				 goto error;
150
+			 }
139 151
 			 if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
140 152
 				LOG(L_ERR, "ERROR: fork_process(): socketpair failed: %s\n",
141 153
 							strerror(errno));
... ...
@@ -160,6 +183,7 @@ int fork_process(int child_id, char *desc, int make_sock)
160 160
 		goto error;
161 161
 	}else if (pid==0){
162 162
 		/* child */
163
+		is_main=0; /* a forked process cannot be the "main" one */
163 164
 		process_no=child_process_no;
164 165
 #ifdef PROFILING
165 166
 		monstartup((u_long) &_start, (u_long) &etext);
... ...
@@ -173,7 +197,7 @@ int fork_process(int child_id, char *desc, int make_sock)
173 173
 		 * this is actually relevant as the parent updates
174 174
 		 * the pt & process_count. */
175 175
 		lock_get(process_lock);
176
-		lock_release(process_lock);	
176
+		lock_release(process_lock);
177 177
 #endif
178 178
 		#ifdef USE_TCP
179 179
 			if (make_sock && !tcp_disable){
... ...
@@ -203,7 +227,7 @@ int fork_process(int child_id, char *desc, int make_sock)
203 203
 			if (make_sock && !tcp_disable){
204 204
 				close(sockfd[1]);
205 205
 				pt[child_process_no].unix_sock=sockfd[0];
206
-				pt[child_process_no].idx=-1; /* this is not "tcp" process*/
206
+				pt[child_process_no].idx=-1; /* this is not a "tcp" process*/
207 207
 			}
208 208
 		#endif
209 209
 #ifdef FORK_DONT_WAIT
... ...
@@ -242,6 +266,16 @@ int fork_tcp_process(int child_id, char *desc, int r, int *reader_fd_1)
242 242
 	reader_fd[0]=reader_fd[1]=-1;
243 243
 	ret=-1;
244 244
 	
245
+	if (!is_main){
246
+		 LOG(L_CRIT, "BUG: fork_tcp_process() called from a non \"main\" "
247
+				 	"process\n");
248
+		 goto error;
249
+	 }
250
+	 if (tcp_main_pid){
251
+		 LOG(L_CRIT, "BUG: fork_tcp_process(..., 1) called _after_ starting"
252
+				 	" tcp main\n");
253
+		 goto error;
254
+	 }
245 255
 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd)<0){
246 256
 		LOG(L_ERR, "ERROR: fork_tcp_process(): socketpair failed: %s\n",
247 257
 					strerror(errno));
... ...
@@ -276,6 +310,7 @@ int fork_tcp_process(int child_id, char *desc, int r, int *reader_fd_1)
276 276
 		goto end;
277 277
 	}
278 278
 	if (pid==0){
279
+		is_main=0; /* a forked process cannot be the "main" one */
279 280
 		process_no=child_process_no;
280 281
 #ifdef PROFILING
281 282
 		monstartup((u_long) &_start, (u_long) &etext);