|
@@ -0,0 +1,149 @@
|
|
|
|
+#$Id$
|
|
|
|
+#
|
|
|
|
+# Module intialization description
|
|
|
|
+#
|
|
|
|
+# History
|
|
|
|
+#--------
|
|
|
|
+# 2007-06-07 created by Andrei Pelinescu <[email protected]>
|
|
|
|
+#
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+This document is a very brief overview on what possibilities are for a module
|
|
|
|
+to run some initializations (or put in another way what's safe and what's
|
|
|
|
+ not safe to do in mod_init and mod_child_init).
|
|
|
|
+
|
|
|
|
+The interesting function are the mod_init (the init_f memeber of
|
|
|
|
+ the module_exports structure) and the mod_child_init (init_child_f in
|
|
|
|
+ module_exports) functions.
|
|
|
|
+
|
|
|
|
+mod_init
|
|
|
|
+--------
|
|
|
|
+
|
|
|
|
+mod_init is called after parsing the config, loading all the modules and
|
|
|
|
+ going into daemon mode. mod_init is called in the main process context,
|
|
|
|
+ before changing the uid or gid (so if you want to do something requiring
|
|
|
|
+ higher privileges this is the place to do it). This is not the right place
|
|
|
|
+ to fork more ser processes, but instead is the only place where one can
|
|
|
|
+ register future forked processes (see register_procs()).
|
|
|
|
+mod_init is ideal for initializing per process variables, assuming that you
|
|
|
|
+ don't need different values for each ser child (in which case see mod_child_init below) and shared memory variables assuming that you don't need ser's number of processes (which is not available at this point).
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+mod_child_init
|
|
|
|
+---------------
|
|
|
|
+
|
|
|
|
+mod_child_init is called for each forked ser process with 2 exceptions:
|
|
|
|
+ - it's called for the main process too and it's called twice
|
|
|
|
+ - it's not called for ser processes forked with PROC_NOCHLDINIT
|
|
|
|
+
|
|
|
|
+mod_child_init is always called after mod_init. It takes one parameter, the
|
|
|
|
+ process rank. This parameter can be used to differentiate between normal
|
|
|
|
+ new-forked-process calls and some special calls.
|
|
|
|
+There are two very special rank values: PROC_INIT (as of 2007-06-06) and
|
|
|
|
+ PROC_MAIN:
|
|
|
|
+mod_child_init(PROC_INIT) is the first mod_child_init call made, and it's
|
|
|
|
+ guaranteed to happen before any child process is forked. The process context
|
|
|
|
+ is the "main" process (as for mod_init), but this time we have a little bit
|
|
|
|
+ more information: we know the number of ser processes. This is the right
|
|
|
|
+ place to initialize things like shared arrays[get_max_procs()].
|
|
|
|
+Note also that everything done here will be inherited in all the future
|
|
|
|
+ children processes (since it's executed in the "main" process context before
|
|
|
|
+ forking).
|
|
|
|
+
|
|
|
|
+mod_child_init(PROC_MAIN) is another call that is done in the same "main"
|
|
|
|
+ process context. This call happens just before initializing the main tcp
|
|
|
|
+ process. This is the only right place for forking more ser processes
|
|
|
|
+ (see fork_process()). WARNING: the context is the same "main" process as
|
|
|
|
+ for mod_child_init(PROC_INIT) and mod_init() so care must be taken not to
|
|
|
|
+ initialize things twice or three times for the "main" process.
|
|
|
|
+
|
|
|
|
+Except for the "main" process case mod_child_init(rank) will be called only
|
|
|
|
+once for each new child process, just after forking. A positive non-zero rank
|
|
|
|
+ means the current process is a normal ser process and a negative rank has
|
|
|
|
+ some special meaning (grep PROC_ sr_module.h for more info).
|
|
|
|
+mod_child_init(rank) is the best place for initializing per process variables,
|
|
|
|
+ opening per process database connections, new sockets a.s.o. Note however
|
|
|
|
+ that several mod_child_init()s can execute in the same time (with the
|
|
|
|
+ PROC_INIT exceptions) so this is not a good place for initializing shared
|
|
|
|
+ memory variables.
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+mod_child_init in the no-fork case
|
|
|
|
+----------------------------------
|
|
|
|
+
|
|
|
|
+If ser is started in no-fork mode it will try to start as few processes as
|
|
|
|
+possible (as of this date it will start 3 processes the main process and the
|
|
|
|
+ 2 timers). In this case mod_child_init() will be called 3 times in the
|
|
|
|
+ same "main" process context: mod_child_init(PROC_INIT);
|
|
|
|
+ mod_child_init(PROC_MAIN) and mod_child_init(1) (since the first process is
|
|
|
|
+ also the "main" one).
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Forking new ser processes from a module
|
|
|
|
+---------------------------------------
|
|
|
|
+
|
|
|
|
+static int mod_init()
|
|
|
|
+{
|
|
|
|
+ register_procs(2); /* we want to create 2 extra processes */
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int mod_child(int rank)
|
|
|
|
+{
|
|
|
|
+ int pid;
|
|
|
|
+
|
|
|
|
+ if (rank==PROC_MAIN){
|
|
|
|
+ pid=fork_process(some_positive_number, "name", 1);
|
|
|
|
+ if (pid<0)
|
|
|
|
+ return -1; /* error */
|
|
|
|
+ else if (pid ==0){
|
|
|
|
+ /* child1_main_loop(); */
|
|
|
|
+ }else{ /* parent */
|
|
|
|
+ pid=fork_process(some_other_postivie_number, "name2", 1);
|
|
|
|
+ if (pid<0)
|
|
|
|
+ /* ... same as above */
|
|
|
|
+ ...
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+Summary
|
|
|
|
+-------
|
|
|
|
+
|
|
|
|
+mod_init():
|
|
|
|
+ - register the number of processes that will be forked from
|
|
|
|
+ mod_child_init(PROC_MAIN) (if any) , see register_procs().
|
|
|
|
+ - initialize things requiring higher privileges
|
|
|
|
+ - initialize per process variables with common value (they will be
|
|
|
|
+ inherited by all the future children)
|
|
|
|
+ - initialize shared memory variables if possible (no need for things that
|
|
|
|
+ are available latter like the process count)
|
|
|
|
+
|
|
|
|
+mod_child_init(PROC_INIT)
|
|
|
|
+ - same as mod_init except for registering processes & privileged stuff
|
|
|
|
+ - the process number is now available so for example initializing shared
|
|
|
|
+ per process statistics arrays (int stats[proc_no]) is possible
|
|
|
|
+ - guaranteed to be run before any process is forked (like mod_init()).
|
|
|
|
+
|
|
|
|
+ WARNING: same process context as mod_init() and mod_child_init(PROC_MAIN) so
|
|
|
|
+ care must be taken not to initialize things 2 or 3 times for the "main"
|
|
|
|
+ process.
|
|
|
|
+
|
|
|
|
+mod_child_init(PROC_MAIN)
|
|
|
|
+ - the only place from where another ser process can be forked (see fork_process ()), but remember first to register the number of to-be-forked processes in
|
|
|
|
+ mod_init()
|
|
|
|
+
|
|
|
|
+mod_child_init(rank!=PROC_INIT && rank!=PROC_MAIN)
|
|
|
|
+ - initialize other per process variables (e.g. different values), whose
|
|
|
|
+ initial values will be visible only in the current process (they won't
|
|
|
|
+ be inherited anymore).
|
|
|
|
+ - open per process db connections, sockets a.s.o.
|
|
|
|
+ - seed custom random generators
|
|
|
|
+
|
|
|
|
+ WARNINGs: - several mod_child_inits() can run in parallel
|
|
|
|
+ - the rank number is not necessarily unique
|
|
|
|
+
|
|
|
|
+ -
|