Jeff Trawick wrote:
I have been working with a user on one of these fork bomb scenarios
and assumed it was the child_init hook. But after giving them a test
fix that relies on a child setting scoreboard fields in child_main
before child-init hooks run, and also adds some debugging traces
related to calling child-init hooks, it is clear that their stall
occurs BEFORE the child-init hook. Which leaves a stretch of fairly
simple code.
(Best theory is bad stuff happening in an atfork handler registred by
a third-party module or some library it uses. But that's besides the
point.)
after more thought, there is a simpler patch that should do the job. the key to both of
these is how threads in SERVER_DEAD state with a pid in the scoreboard are treated. this
means that p_i_s_m forked on a previous timer pop but some thread never made it into
SERVER_STARTING state.
the difference: this patch just counts those potential threads as idle, and allows
MinSpareThreads worth of processes to be forked before putting on the brakes. the
previous patch pauses the forking immediately when the strange situation is detected but
requires more code and a new variable. I'm leaning toward this one because it is simpler.
opinions?
Greg
--- server/mpm/worker/worker.c (revision 398659)
+++ server/mpm/worker/worker.c (working copy)
@@ -1422,7 +1422,7 @@
*/
if (ps->pid != 0) { /* XXX just set all_dead_threads in outer for
loop if no pid? not much else matters */
- if (status <= SERVER_READY && status != SERVER_DEAD &&
+ if (status <= SERVER_READY &&
!ps->quiescing &&
ps->generation == ap_my_generation) {
++idle_thread_count;