Browse code

core: mechanism to execute child_init() for special ranks on demand

- new special rank PROC_POSTCHILDINIT, to execute child_init() for main
process only when ksr_module_set_flag(KSRMOD_FLAG_POSTCHILDINIT) is
executed in mod_init()

Daniel-Constantin Mierla authored on 18/11/2021 13:33:28
Showing 3 changed files
... ...
@@ -862,21 +862,30 @@ void destroy_modules()
862 862
 
863 863
 static int init_mod_child( struct sr_module* m, int rank )
864 864
 {
865
+	int ret;
865 866
 	if (m) {
866 867
 		/* iterate through the list; if error occurs,
867 868
 		 * propagate it up the stack
868 869
 		 */
869 870
 		if (init_mod_child(m->next, rank)!=0) return -1;
870 871
 		if (m->exports.init_child_f) {
871
-			LM_DBG("idx %d rank %d: %s [%s]\n", process_no, rank,
872
-					m->exports.name, my_desc());
873
-			if (m->exports.init_child_f(rank)<0) {
874
-				LM_ERR("error while initializing module %s (%s)"
875
-						" (idx: %d rank: %d desc: [%s])\n",
876
-						m->exports.name, m->path, process_no, rank, my_desc());
877
-				return -1;
872
+			ret = 0;
873
+			if(rank!=PROC_POSTCHILDINIT
874
+					|| (m->modflags&KSRMOD_FLAG_POSTCHILDINIT)) {
875
+				LM_DBG("idx %d rank %d: %s [%s]\n", process_no, rank,
876
+						m->exports.name, my_desc());
877
+				ret = m->exports.init_child_f(rank);
878
+				if(ret<0) {
879
+					LM_ERR("error while initializing module %s (%s)"
880
+							" (idx: %d rank: %d desc: [%s])\n",
881
+							m->exports.name, m->path, process_no, rank, my_desc());
882
+					return -1;
883
+				} else {
884
+					/* module correctly initialized */
885
+					return 0;
886
+				}
878 887
 			} else {
879
-				/* module correctly initialized */
888
+				/* module does not want execution for this rank */
880 889
 				return 0;
881 890
 			}
882 891
 		}
... ...
@@ -898,25 +907,29 @@ int init_child(int rank)
898 907
 	char* type;
899 908
 
900 909
 	switch(rank) {
901
-	case PROC_MAIN:       type = "PROC_MAIN";       break;
902
-	case PROC_TIMER:      type = "PROC_TIMER";      break;
903
-	case PROC_RPC:        type = "PROC_RPC";        break;
904
-	case PROC_TCP_MAIN:   type = "PROC_TCP_MAIN";   break;
905
-	case PROC_UNIXSOCK:   type = "PROC_UNIXSOCK";   break;
906
-	case PROC_ATTENDANT:  type = "PROC_ATTENDANT";  break;
907
-	case PROC_INIT:       type = "PROC_INIT";       break;
908
-	case PROC_NOCHLDINIT: type = "PROC_NOCHLDINIT"; break;
909
-	case PROC_SIPINIT:    type = "PROC_SIPINIT";    break;
910
-	case PROC_SIPRPC:     type = "PROC_SIPRPC";     break;
911
-	default:              type = "CHILD";           break;
910
+	case PROC_MAIN:          type = "PROC_MAIN";       break;
911
+	case PROC_TIMER:         type = "PROC_TIMER";      break;
912
+	case PROC_RPC:           type = "PROC_RPC";        break;
913
+	case PROC_TCP_MAIN:      type = "PROC_TCP_MAIN";   break;
914
+	case PROC_UNIXSOCK:      type = "PROC_UNIXSOCK";   break;
915
+	case PROC_ATTENDANT:     type = "PROC_ATTENDANT";  break;
916
+	case PROC_INIT:          type = "PROC_INIT";       break;
917
+	case PROC_NOCHLDINIT:    type = "PROC_NOCHLDINIT"; break;
918
+	case PROC_SIPINIT:       type = "PROC_SIPINIT";    break;
919
+	case PROC_SIPRPC:        type = "PROC_SIPRPC";     break;
920
+	case PROC_POSTCHILDINIT: type = "PROC_POSTCHILDINIT"; break;
921
+	default:                 type = "CHILD";           break;
912 922
 	}
913 923
 	LM_DBG("initializing %s with rank %d\n", type, rank);
914 924
 
915
-	if(async_task_child_init(rank)<0)
916
-		return -1;
925
+	if(rank!=PROC_POSTCHILDINIT) {
926
+		if(async_task_child_init(rank)<0) {
927
+			return -1;
928
+		}
929
+	}
917 930
 
918 931
 	ret = init_mod_child(modules, rank);
919
-	if(rank!=PROC_INIT) {
932
+	if(rank!=PROC_INIT && rank!=PROC_POSTCHILDINIT) {
920 933
 		pt[process_no].status = 1;
921 934
 	}
922 935
 	return ret;
... ...
@@ -924,21 +937,37 @@ int init_child(int rank)
924 937
 
925 938
 
926 939
 
940
+static sr_module_t *ksr_module_init_ptr = NULL;
941
+
942
+/**
943
+ * set module flags when mod_init() is executed
944
+ */
945
+void ksr_module_set_flag(unsigned int flag)
946
+{
947
+	if(ksr_module_init_ptr==NULL) {
948
+		return;
949
+	}
950
+	ksr_module_init_ptr->modflags |= flag;
951
+}
952
+
927 953
 /* recursive module initialization; (recursion is used to
928 954
  * process the module linear list in the same order in
929 955
  * which modules are loaded in config file
930 956
 */
931
-
932 957
 static int init_mod( struct sr_module* m )
933 958
 {
959
+	int ret;
934 960
 	if (m) {
935 961
 		/* iterate through the list; if error occurs,
936 962
 		 * propagate it up the stack
937 963
 		 */
938 964
 		if (init_mod(m->next)!=0) return -1;
939
-			if (m->exports.init_mod_f) {
965
+			if(m->exports.init_mod_f) {
940 966
 				LM_DBG("%s\n", m->exports.name);
941
-				if (m->exports.init_mod_f()!=0) {
967
+				ksr_module_init_ptr = m;
968
+				ret = m->exports.init_mod_f();
969
+				ksr_module_init_ptr = NULL;
970
+				if(ret!=0) {
942 971
 					LM_ERR("Error while initializing module %s (%s)\n",
943 972
 								m->exports.name, m->path);
944 973
 					return -1;
... ...
@@ -137,6 +137,10 @@ typedef int (*param_func_t)( modparam_t type, void* val);
137 137
 #define call_fixup(fixup, param, param_no) \
138 138
 	((fixup) ? (fixup)(param, param_no) : 0)
139 139
 
140
+/* flags to execute child_init() for special ranks */
141
+#define KSRMOD_FLAG_POSTCHILDINIT (1<<1)
142
+void ksr_module_set_flag(unsigned int flag);
143
+
140 144
 /* Macros - used as rank in child_init function */
141 145
 #define PROC_MAIN      0  /**< Main process */
142 146
 #define PROC_TIMER    -1  /**< Timer attendant process */
... ...
@@ -145,7 +149,9 @@ typedef int (*param_func_t)( modparam_t type, void* val);
145 149
 #define PROC_TCP_MAIN -4  /**< TCP main process */
146 150
 #define PROC_UNIXSOCK -5  /**< Unix socket server */
147 151
 #define PROC_ATTENDANT -10  /**< main "attendant process */
148
-#define PROC_INIT     -127 /**< special rank, the context is the main ser
152
+#define PROC_POSTCHILDINIT -126  /**< special rank - main kamailio process after
153
+									after all child_init() are executed */
154
+#define PROC_INIT     -127 /**< special rank, the context is the main kamailio
149 155
 							  process, but this is guaranteed to be executed
150 156
 							  before any process is forked, so it can be used
151 157
 							  to setup shared variables that depend on some
... ...
@@ -320,11 +326,12 @@ typedef struct sr_module {
320 326
 	char* path;
321 327
 	void* handle;
322 328
 	ksr_module_exports_t exports;
329
+	unsigned int modflags;
323 330
 	struct sr_module* next;
324 331
 } sr_module_t;
325 332
 
326 333
 
327
-extern struct sr_module* modules; /**< global module list*/
334
+extern sr_module_t* modules; /**< global module list*/
328 335
 extern response_function* mod_response_cbks; /**< response callback array */
329 336
 extern int mod_response_cbk_no; /**< size of reponse callbacks array */
330 337
 
... ...
@@ -1498,6 +1498,12 @@ int main_loop(void)
1498 1498
 			LM_ERR("init_child failed\n");
1499 1499
 			goto error;
1500 1500
 		}
1501
+
1502
+		if (init_child(PROC_POSTCHILDINIT) < 0) {
1503
+			LM_ERR("error in init_child for rank PROC_POSTCHILDINIT\n");
1504
+			goto error;
1505
+		}
1506
+
1501 1507
 		*_sr_instance_started = 1;
1502 1508
 		return udp_rcv_loop();
1503 1509
 	}else{ /* fork: */
... ...
@@ -1864,6 +1870,11 @@ int main_loop(void)
1864 1870
 			unix_tcp_sock=-1;
1865 1871
 		}
1866 1872
 #endif
1873
+		if (init_child(PROC_POSTCHILDINIT) < 0) {
1874
+			LM_ERR("error in init_child for rank PROC_POSTCHILDINIT\n");
1875
+			goto error;
1876
+		}
1877
+
1867 1878
 		/* init cfg, but without per child callbacks support */
1868 1879
 		cfg_child_no_cb_init();
1869 1880
 		cfg_ok=1;