File 0002-configurable-max-failed-starts.patch of Package apache2-mod_fastcgi

From: Yehuda Sadeh <yehuda.sadeh@dreamhost.com>
Date: Tue, 7 Jun 2011 10:45:02 -0700
Subject: [PATCH] configurable max failed starts

A zero value disables the feature completely
---
 fcgi.h        |  5 +++++
 fcgi_config.c |  9 +++++++++
 fcgi_pm.c     | 11 ++++++++---
 fcgi_util.c   |  1 +
 mod_fastcgi.c |  1 +
 mod_fastcgi.h |  2 +-
 6 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/fcgi.h b/fcgi.h
index 0aebc16..e5d084b 100644
--- a/fcgi.h
+++ b/fcgi.h
@@ -215,6 +215,10 @@ typedef struct _FastCgiServerInfo {
                                      * restarts after failure.  Can be zero. */
     u_int minServerLife;            /* minimum number of seconds a server must
                                      * live before it's considered borked. */
+    u_int maxFailedStarts;          /* The number of failed starts that can occur
+				     * before the application is considered broken
+				     * and start attempts fall back to
+				     * failedStartsDelay. */
     int restartOnExit;              /* = TRUE = restart. else terminate/free */
     u_int numFailures;              /* num restarts due to exit failure */
     int bad;                        /* is [not] having start problems */
@@ -620,6 +624,7 @@ extern u_int dynamicRestartDelay;
 extern array_header *dynamic_pass_headers;
 extern u_int dynamic_idle_timeout;
 extern int dynamicMinServerLife;
+extern int dynamicMaxFailedStarts;
 extern int dynamicFlush;
 
 
diff --git a/fcgi_config.c b/fcgi_config.c
index bafd921..2a8a650 100644
--- a/fcgi_config.c
+++ b/fcgi_config.c
@@ -288,6 +288,7 @@ apcb_t fcgi_config_reset_globals(void* dummy)
     dynamicInitStartDelay = DEFAULT_INIT_START_DELAY;
     dynamicRestartDelay = FCGI_DEFAULT_RESTART_DELAY;
     dynamicMinServerLife = FCGI_DEFAULT_MIN_SERVER_LIFE;
+    dynamicMaxFailedStarts = FCGI_DEFAULT_MAX_FAILED_STARTS;
     dynamic_pass_headers = NULL;
     dynamic_idle_timeout = FCGI_DEFAULT_IDLE_TIMEOUT;
 	dynamicFlush = FCGI_FLUSH;
@@ -697,6 +698,10 @@ const char *fcgi_config_new_static_server(cmd_parms *cmd, void *dummy, const cha
             if ((err = get_u_int(tp, &arg, &s->minServerLife, 0)))
                 return invalid_value(tp, name, NULL, option, err);
         }
+        else if (strcasecmp(option, "-max-failed-starts") == 0) {
+            if ((err = get_u_int(tp, &arg, &s->maxFailedStarts, 0)))
+                return invalid_value(tp, name, NULL, option, err);
+        }
         else if (strcasecmp(option, "-priority") == 0) {
             if ((err = get_u_int(tp, &arg, &s->processPriority, 0)))
                 return invalid_value(tp, name, fs_path, option, err);
@@ -1123,6 +1128,10 @@ const char *fcgi_config_set_config(cmd_parms *cmd, void *dummy, const char *arg)
             if ((err = get_int(tp, &arg, &dynamicMinServerLife, 0)))
                 return invalid_value(tp, name, NULL, option, err);
         }
+        else if (strcasecmp(option, "-max-failed-starts") == 0) {
+            if ((err = get_int(tp, &arg, &dynamicMaxFailedStarts, 0)))
+                return invalid_value(tp, name, NULL, option, err);
+        }
         else if (strcasecmp(option, "-restart-delay") == 0) {
             if ((err = get_u_int(tp, &arg, &dynamicRestartDelay, 0)))
                 return invalid_value(tp, name, NULL, option, err);
diff --git a/fcgi_pm.c b/fcgi_pm.c
index 08fd33d..b73305a 100644
--- a/fcgi_pm.c
+++ b/fcgi_pm.c
@@ -1749,6 +1749,7 @@ void fcgi_pm_main(void *dummy)
 #endif
         unsigned int numChildren;
 		unsigned int minServerLife;
+        unsigned int maxFailedStarts;
 
         /*
          * If we came out of sigsuspend() for any reason other than
@@ -1777,6 +1778,10 @@ void fcgi_pm_main(void *dummy)
                 ? dynamicMinServerLife 
                 : s->minServerLife;
 
+            maxFailedStarts = (s->directive == APP_CLASS_DYNAMIC) 
+                ? dynamicMaxFailedStarts
+                : s->minServerLife;
+
             for (i = 0; i < numChildren; ++i) 
             {
                 if (s->procs[i].pid <= 0 && s->procs[i].state == FCGI_START_STATE)
@@ -1795,7 +1800,7 @@ void fcgi_pm_main(void *dummy)
                         s->procs[i].start_time = 0;
                     }
                     
-                    if (s->numFailures > MAX_FAILED_STARTS)
+                    if (maxFailedStarts && s->numFailures > maxFailedStarts)
                     {
                         time_t last_start_time = s->procs[i].start_time;
 
@@ -1830,7 +1835,7 @@ void fcgi_pm_main(void *dummy)
                                     " running for %d seconds given %d attempts, its restart"
                                     " interval has been backed off to %d seconds",
                                     (s->directive == APP_CLASS_DYNAMIC) ? " (dynamic)" : "",
-                                    s->fs_path, minServerLife, MAX_FAILED_STARTS,
+                                    s->fs_path, minServerLife, s->maxFailedStarts,
                                     FAILED_STARTS_DELAY);
                             }
                             else
@@ -1861,7 +1866,7 @@ void fcgi_pm_main(void *dummy)
                         if (s->bad) 
                         {
                             s->bad = 0;
-                            s->numFailures = MAX_FAILED_STARTS;
+                            s->numFailures = s->maxFailedStarts;
                         }
 
                         if (s->listenFd < 0 && init_listen_sock(s)) 
diff --git a/fcgi_util.c b/fcgi_util.c
index af200d0..8d4d2ab 100644
--- a/fcgi_util.c
+++ b/fcgi_util.c
@@ -413,6 +413,7 @@ fcgi_util_fs_new(pool *p)
     s->initStartDelay = DEFAULT_INIT_START_DELAY;
     s->restartDelay = FCGI_DEFAULT_RESTART_DELAY;
 	s->minServerLife = FCGI_DEFAULT_MIN_SERVER_LIFE;
+    s->maxFailedStarts = FCGI_DEFAULT_MAX_FAILED_STARTS;
     s->restartOnExit = FALSE;
     s->directive = APP_CLASS_UNKNOWN;
     s->processPriority = FCGI_DEFAULT_PRIORITY;
diff --git a/mod_fastcgi.c b/mod_fastcgi.c
index e3c1e48..c7e02cc 100644
--- a/mod_fastcgi.c
+++ b/mod_fastcgi.c
@@ -152,6 +152,7 @@ u_int dynamicRestartDelay = FCGI_DEFAULT_RESTART_DELAY;
 array_header *dynamic_pass_headers = NULL;
 u_int dynamic_idle_timeout = FCGI_DEFAULT_IDLE_TIMEOUT;
 int dynamicMinServerLife = FCGI_DEFAULT_MIN_SERVER_LIFE;
+int dynamicMaxFailedStarts = FCGI_DEFAULT_MAX_FAILED_STARTS;
 
 /*******************************************************************************
  * Construct a message and write it to the pm_pipe.
diff --git a/mod_fastcgi.h b/mod_fastcgi.h
index 8077edb..9c84310 100644
--- a/mod_fastcgi.h
+++ b/mod_fastcgi.h
@@ -39,7 +39,7 @@
  * The number of failed starts that can occur before the application is
  * considered broken and start attempts fall back to FAILED_STARTS_DELAY.
  */
-#define MAX_FAILED_STARTS 3
+#define FCGI_DEFAULT_MAX_FAILED_STARTS 3
 
 /*
  * The number of seconds between attempts to start an application that