Re: bug fix for Apache mod_fastcgi.c

Stanley Gambarin (gambarin@OpenMarket.com)
Fri, 28 Feb 1997 17:28:33 -0500

Message-Id: <199702282228.RAA18175@u4-138.openmarket.com>
To: Bob Ramstad <rramstad@nfic.com>
Subject: Re: bug fix for Apache mod_fastcgi.c 
In-Reply-To: Your message of "Thu, 20 Feb 1997 16:02:47 EST."
             <199702202102.QAA06232@bill-graham.nfic.com> 
Date: Fri, 28 Feb 1997 17:28:33 -0500
From: Stanley Gambarin <gambarin@OpenMarket.com>

> howdy.  some may recall a thread a while back where people were having
> problems with Apache (and perhaps other servers) spawning orphan
> FastCGI processes.  from investigations here, it appears that the
> problem is that Apache doesn't set up a signal handler until virtually
> all initialization is completed.  the configuration file is parsed
> fairly early -- therefore the FastCGI processes are started early too.
> if Apache discovers a problem which doesn't allow it to successfully
> start, it exits without sending any signals to the children.
>
	There is a bit of misunderstanding on your part.  Allow me to 
extrapolate: Apache is designed as to parse the configuration files twice
on the startup.  Part of the configuration files include calling an 
initialization function for each module.  In mod_fastcgi, this function is
called ModFastCgiInit() and that is what starts up the process manager that
itself starts fastcgi applications.  When Apache notices that it needs to 
reread its configuration files (standalone_main() in http_main.c), it first
calls clear_pool() function to free memory and stuff and then rereads.  Now, 
clear_pool() calls free_proc_chain() in alloc.c which basically does the 
following for the fastcgi process manager:
	- issue SIGTERM
	- sleep 3 seconds
	- issue SIGKILL
	Consider process manager now: after it catches SIGTERM it only has
3 seconds to kill off all running fastcgi processes.  If it is unable to do so,
it gets killed, and fastcgi processes run without a parent.  Therefore, our
problem is not for the process manager to check if it has no parent process,
but for fastcgi processes to check for that condition.

> this is actually a somewhat general problem.  exit is called many
> times in the Apache code -- given the various states of initialization
> which the system might be in, this could be bad, as there doesn't
> appear to be much effort to clean up before exiting.  again,
> generally, it would make sense for each module to have a cleanup
> function and to have Apache call each of these if it needs to shut
> down and that particular module has been initialized.
>
	Yes, this would be an ideal way to handle things.  There are other
alternatives however.  One possibility is to change the FastCGI protocol to 
account for such behavior (not a good idea, since its very server-specific).
Change the Apache API to call cleanup() function for every module.  Another 
alternative is to introduce another kill_condition where the free_proc_chain()
function would issue a SIGTERM once, and not issue SIGKILL.  Finally, 
you can do a hack and do the following:
	- once process manager recieves a SIGTERM, it forks off a copy
and kills the parent.  Now, the Apache server issuing SIGKILL would have no
effect as process manager is running with no ppid (parent process id).  After
that, process manager goes around, issuing SIGTERM to all its children
(which are fastcgi applications), and after all of them are killed off,
the process manager does an exit();

	My thoughts on the above are:  if someone from the Apache group
can talk to them about using another kill_condition, I would greatly 
appreciate it.  (I doubt very much that the cleanup() functionality
would be implemented in the near future,  if at all).  If the above is
unsuccessful, I may consider using the fork() alternative, but that is
open to debate.

						Hope that was of some help.
								Stanley.