Browse code

db: Fixing problem with incorrect initialization of db connections

The sip-router core is based on the ser core and thus has a slightly
different initialization sequence of the main sr process. Namely we
also call the child_init function of all modules in the main process
with rank PROC_INIT. This is a kind of delayed initialization (called
after all mod_init functions have finished but before the main
process started forking children).

There should be no database connections opened in child_init called
with PROC_INIT parameter. This would result in database connections
opened in the main process and inherited by all children. Such
connections could then be used from multiple processes simultaneously
and that can cause race conditions.

This change checks for the value of the rank parameter in child_init
functions and skips database initialization if the value is PROC_INIT,
PROC_MAIN, or PROC_TCP_MAIN.

The problem was reported by Juha and he deserves the credit for helping to
investigate the issue.

Jan Janak authored on 10/06/2009 20:41:27
Showing 22 changed files
... ...
@@ -229,6 +229,9 @@ static int mod_init(void) {
229 229
 
230 230
 
231 231
 static int child_init(int rank) {
232
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
233
+		return 0; /* do nothing for the main process */
234
+
232 235
 	if(mode == CARRIERROUTE_MODE_DB){
233 236
 		return carrierroute_db_open();
234 237
 	}
... ...
@@ -280,6 +280,9 @@ static int mod_init(void)
280 280
 /* Child initialization function */
281 281
 static int child_init(int rank)
282 282
 {	
283
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
284
+		return 0; /* do nothing for the main process */
285
+
283 286
     return pres_db_open();
284 287
 }
285 288
 
... ...
@@ -527,6 +527,9 @@ static int mod_init( void )
527 527
 
528 528
 static int child_init(int rank)
529 529
 {
530
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
531
+		return 0; /* do nothing for the main process */
532
+
530 533
 #ifdef SQL_ACC
531 534
 	if(db_url.s && acc_db_init_child(&db_url)<0) {
532 535
 		LM_ERR("could not open database connection");
... ...
@@ -111,6 +111,9 @@ struct module_exports exports = {
111 111
  */
112 112
 static int child_init(int rank)
113 113
 {
114
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
115
+		return 0; /* do nothing for the main process */
116
+
114 117
 	db_handle = adbf.init(&db_url);
115 118
 	if (!db_handle)
116 119
 	{
... ...
@@ -156,6 +156,9 @@ struct module_exports exports = {
156 156
 
157 157
 static int child_init(int rank)
158 158
 {
159
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
160
+		return 0; /* do nothing for the main process */
161
+	
159 162
 	auth_db_handle = auth_dbf.init(&db_url);
160 163
 	if (auth_db_handle == 0){
161 164
 		LM_ERR("unable to connect to the database\n");
... ...
@@ -201,7 +201,7 @@ static int avpops_child_init(int rank)
201 201
 	if (db_url.s==0)
202 202
 		return 0;
203 203
 	/* skip main process and TCP manager process */
204
-	if (rank==PROC_MAIN || rank==PROC_TCP_MAIN)
204
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
205 205
 		return 0;
206 206
 	/* init DB connection */
207 207
 	return avpops_db_init(&db_url, &db_table, db_columns);
... ...
@@ -398,6 +398,9 @@ error:
398 398
 
399 399
 static int cpl_child_init(int rank)
400 400
 {
401
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
402
+		return 0; /* do nothing for the main process */
403
+
401 404
 	return cpl_db_init(&db_url, &db_table);
402 405
 }
403 406
 
... ...
@@ -180,6 +180,9 @@ struct module_exports exports = {
180 180
 
181 181
 static int child_init(int rank)
182 182
 {
183
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
184
+		return 0; /* do nothing for the main process */
185
+
183 186
 	return group_db_init(&db_url);
184 187
 }
185 188
 
... ...
@@ -415,6 +415,9 @@ static int mod_init(void)
415 415
  */
416 416
 static int child_init(int rank)
417 417
 {	
418
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
419
+		return 0; /* do nothing for the main process */
420
+
418 421
 	if (imc_dbf.init==0)
419 422
 	{
420 423
 		LM_ERR("database not bound\n");
... ...
@@ -441,6 +441,9 @@ static int mod_init(void)
441 441
  */
442 442
 static int child_init(int rank)
443 443
 {
444
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
445
+		return 0; /* do nothing for the main process */
446
+
444 447
 	LM_DBG("rank #%d / pid <%d>\n", rank, getpid());
445 448
 	if (msilo_dbf.init==0)
446 449
 	{
... ...
@@ -288,6 +288,9 @@ static int child_init(void)
288 288
 /* each child get a new connection to the database */
289 289
 static int mod_child_init(int r)
290 290
 {
291
+	if (r=PROC_INIT || r==PROC_MAIN || r==PROC_TCP_MAIN)
292
+		return 0; /* do nothing for the main process */
293
+
291 294
 	if ( child_init()!=0 )
292 295
 		return -1;
293 296
 
... ...
@@ -226,6 +226,9 @@ error:
226 226
  */
227 227
 int init_child_trusted(int rank)
228 228
 {
229
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
230
+		return 0; /* do nothing for the main process */
231
+
229 232
 	if (!db_url.s) {
230 233
 		return 0;
231 234
 	}
... ...
@@ -350,6 +350,9 @@ static int mod_init(void)
350 350
  */
351 351
 static int child_init(int rank)
352 352
 {
353
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
354
+		return 0; /* do nothing for the main process */
355
+
353 356
 	pid = my_pid();
354 357
 	
355 358
 	if(library_mode)
... ...
@@ -283,6 +283,9 @@ static int child_init(int rank)
283 283
 {
284 284
 	LM_DBG("[%d]  pid [%d]\n", rank, getpid());
285 285
 	
286
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
287
+		return 0; /* do nothing for the main process */
288
+
286 289
 	if (pxml_dbf.init==0)
287 290
 	{
288 291
 		LM_CRIT("database not bound\n");
... ...
@@ -247,6 +247,9 @@ static int mod_init(void)
247 247
 
248 248
 static int child_init(int rank)
249 249
 {
250
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
251
+		return 0; /* do nothing for the main process */
252
+
250 253
 	if (pua_dbf.init==0)
251 254
 	{
252 255
 		LM_CRIT("database not bound\n");
... ...
@@ -453,6 +453,9 @@ static int mod_init(void)
453 453
  */
454 454
 static int child_init(int rank)
455 455
 {
456
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
457
+		return 0; /* do nothing for the main process */
458
+
456 459
 	LM_DBG("child [%d]  pid [%d]\n", rank, getpid());
457 460
 	if (rls_dbf.init==0)
458 461
 	{
... ...
@@ -321,6 +321,9 @@ static int mod_init(void)
321 321
 
322 322
 static int child_init(int rank)
323 323
 {
324
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
325
+		return 0; /* do nothing for the main process */
326
+
324 327
 	db_con = db_funcs.init(&db_url);
325 328
 	if (!db_con) {
326 329
 		LM_ERR("unable to connect to database. Please check configuration.\n");
... ...
@@ -113,6 +113,9 @@ struct module_exports exports = {
113 113
  */
114 114
 static int child_init(int rank)
115 115
 {
116
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
117
+		return 0; /* do nothing for the main process */
118
+
116 119
 	db_handle = db_funcs.init(&db_url);
117 120
 	if (!db_handle)
118 121
 	{
... ...
@@ -89,7 +89,7 @@ struct module_exports exports= {
89 89
 
90 90
 static int child_init(int rank)
91 91
 {
92
-	if (rank==PROC_MAIN || rank==PROC_TCP_MAIN)
92
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
93 93
 		return 0;
94 94
 	return sql_connect();
95 95
 }
... ...
@@ -141,6 +141,9 @@ struct module_exports exports = {
141 141
  */
142 142
 static int child_init(int rank)
143 143
 {
144
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
145
+		return 0; /* do nothing for the main process */
146
+
144 147
 	if (db_url.len)
145 148
 		return uridb_db_init(&db_url);
146 149
 	else
... ...
@@ -567,6 +567,9 @@ static int mod_init(void)
567 567
 
568 568
 static int child_init(int rank)
569 569
 {
570
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
571
+		return 0; /* do nothing for the main process */
572
+
570 573
 	if (userblacklist_db_open() != 0) return -1;
571 574
 	dtrie_root=dtrie_init(10);
572 575
 	if (dtrie_root == NULL) {
... ...
@@ -169,6 +169,9 @@ static int mod_init(void)
169 169
 
170 170
 static int child_init(int rank)
171 171
 {
172
+	if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
173
+		return 0; /* do nothing for the main process */
174
+
172 175
 	if((xcap_db = xcap_dbf.init(&xcap_db_url))==NULL)
173 176
 	{
174 177
 		LM_ERR("cannot connect to db\n");