]> granicus.if.org Git - apache/commitdiff
On the 2.4.x branch:
authorStefan Eissing <icing@apache.org>
Thu, 27 Apr 2017 14:25:56 +0000 (14:25 +0000)
committerStefan Eissing <icing@apache.org>
Thu, 27 Apr 2017 14:25:56 +0000 (14:25 +0000)
   Merged /httpd/httpd/trunk:r1784203,1784205,1784227-1784228,1784275,1785871,1786009,1789387

mod_proxy_hcheck: Honor checks in Vhosts w/o hanging

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1792905 13f79535-47bb-0310-9956-ffa450edef68

STATUS
docs/manual/mod/mod_proxy_hcheck.xml
modules/proxy/mod_proxy_hcheck.c

diff --git a/STATUS b/STATUS
index d120a099c3d0455418f16e785c8e6aa66fc66d31..d337ab174d837221d3d8d8b5e44bb054596ea65e 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -139,22 +139,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  *) mod_proxy_hcheck: Honor checks in Vhosts w/o hanging
-     trunk patch: http://svn.apache.org/r1784203
-                  http://svn.apache.org/r1784205
-                  http://svn.apache.org/r1784227
-                  http://svn.apache.org/r1784228
-                  http://svn.apache.org/r1784275
-                  http://svn.apache.org/r1785871
-                  http://svn.apache.org/r1786009
-                  http://svn.apache.org/r1789387
-     2.4.x patch: trunk works *after r1779573 above* (modulo CHANGES)
-              ie: http://home.apache.org/~ylavic/patches/httpd2.4-hcheck-after-r1779573.patch
-           FULL hcheck patch: http://home.apache.org/~jim/patches/httpd2.4-hcheck.patch
-                              http://svn.apache.org/r1789387
-           (includes all hcheck related patches, including showstopper)
-     +1: jim, ylavic, icing
-
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
   [ New proposals should be added at the end of the list ]
 
index a27ce296318e6453875139e77bb2287c59252174..72a26d548467a493f826731a83ddc90b54317aac 100644 (file)
@@ -204,9 +204,9 @@ ProxyPass "/apps"     "http://backend.example.com/" hctemplate=tcp5
 
 <directivesynopsis>
 <name>ProxyHCTPsize</name>
-<description>Sets the size of the threadpool used for the health check workers.</description>
+<description>Sets the total server-wide size of the threadpool used for the health check workers.</description>
 <syntax>ProxyHCTPsize &lt;size&gt;</syntax>
-<contextlist><context>server config</context><context>virtual host</context>
+<contextlist><context>server config</context>
 </contextlist>
 
 <usage>
index 39a4914c2d9810101b547338fe1a064928ced2de..a458a38f7e32c0e595968ac6570052196836747a 100644 (file)
@@ -54,10 +54,7 @@ typedef struct {
     apr_bucket_alloc_t *ba;
     apr_array_header_t *templates;
     apr_table_t *conditions;
-    ap_watchdog_t *watchdog;
     apr_hash_t *hcworkers;
-    apr_thread_pool_t *hctp;
-    int tpsize;
     server_rec *s;
 } sctx_t;
 
@@ -79,18 +76,19 @@ typedef struct {
 
 static void *hc_create_config(apr_pool_t *p, server_rec *s)
 {
-    sctx_t *ctx = (sctx_t *) apr_palloc(p, sizeof(sctx_t));
+    sctx_t *ctx = apr_pcalloc(p, sizeof(sctx_t));
+    ctx->s = s;
     apr_pool_create(&ctx->p, p);
     ctx->ba = apr_bucket_alloc_create(p);
     ctx->templates = apr_array_make(p, 10, sizeof(hc_template_t));
     ctx->conditions = apr_table_make(p, 10);
     ctx->hcworkers = apr_hash_make(p);
-    ctx->tpsize = HC_THREADPOOL_SIZE;
-    ctx->s = s;
-
     return ctx;
 }
 
+static ap_watchdog_t *watchdog;
+static int tpsize = HC_THREADPOOL_SIZE;
+
 /*
  * This serves double duty by not only validating (and creating)
  * the health-check template, but also ties into set_worker_param()
@@ -257,7 +255,6 @@ static const char *set_hc_condition(cmd_parms *cmd, void *dummy, const char *arg
     if (*expr) {
         return "error: extra parameter(s)";
     }
-
     return NULL;
 }
 
@@ -305,23 +302,18 @@ static const char *set_hc_template(cmd_parms *cmd, void *dummy, const char *arg)
         }
         /* No error means we have a valid template */
     }
-
     return NULL;
 }
 
 #if HC_USE_THREADS
 static const char *set_hc_tpsize (cmd_parms *cmd, void *dummy, const char *arg)
 {
-    sctx_t *ctx;
-
-    const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS);
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
     if (err)
         return err;
-    ctx = (sctx_t *) ap_get_module_config(cmd->server->module_config,
-                                          &proxy_hcheck_module);
 
-    ctx->tpsize = atoi(arg);
-    if (ctx->tpsize < 0)
+    tpsize = atoi(arg);
+    if (tpsize < 0)
         return "Invalid ProxyHCTPsize parameter. Parameter must be "
                ">= 0";
     return NULL;
@@ -876,30 +868,32 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
     sctx_t *ctx = (sctx_t *)data;
     server_rec *s = ctx->s;
     proxy_server_conf *conf;
+    static apr_thread_pool_t *hctp = NULL;
+
     switch (state) {
         case AP_WATCHDOG_STATE_STARTING:
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03258)
                          "%s watchdog started.",
                          HCHECK_WATHCHDOG_NAME);
 #if HC_USE_THREADS
-            if (ctx->tpsize) {
-                rv =  apr_thread_pool_create(&ctx->hctp, ctx->tpsize,
-                                             ctx->tpsize, ctx->p);
+            if (tpsize && hctp == NULL) {
+                rv =  apr_thread_pool_create(&hctp, tpsize,
+                                             tpsize, ctx->p);
                 if (rv != APR_SUCCESS) {
                     ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03312)
                                  "apr_thread_pool_create() with %d threads failed",
-                                 ctx->tpsize);
+                                 tpsize);
                     /* we can continue on without the threadpools */
-                    ctx->hctp = NULL;
+                    hctp = NULL;
                 } else {
                     ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03313)
                                  "apr_thread_pool_create() with %d threads succeeded",
-                                 ctx->tpsize);
+                                 tpsize);
                 }
             } else {
                 ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(03314)
                              "Skipping apr_thread_pool_create()");
-                ctx->hctp = NULL;
+                hctp = NULL;
             }
 
 #endif
@@ -907,13 +901,14 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
 
         case AP_WATCHDOG_STATE_RUNNING:
             /* loop thru all workers */
-            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
+            ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, s,
                          "Run of %s watchdog.",
                          HCHECK_WATHCHDOG_NAME);
             if (s) {
                 int i;
                 conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module);
                 balancer = (proxy_balancer *)conf->balancers->elts;
+                ctx->s = s;
                 for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
                     int n;
                     proxy_worker **workers;
@@ -928,7 +923,7 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                            (now > worker->s->updated + worker->s->interval)) {
                             baton_t *baton;
                             apr_pool_t *ptemp;
-                            ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
+                            ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                                          "Checking %s worker: %s  [%d] (%pp)", balancer->s->name,
                                          worker->s->name, worker->s->method, worker);
 
@@ -945,12 +940,12 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                             baton->ptemp = ptemp;
                             baton->hc = hc_get_hcworker(ctx, worker, ptemp);
 
-                            if (!ctx->hctp) {
+                            if (!hctp) {
                                 hc_check(NULL, baton);
                             }
 #if HC_USE_THREADS
                             else {
-                                rv = apr_thread_pool_push(ctx->hctp, hc_check, (void *)baton,
+                                rv = apr_thread_pool_push(hctp, hc_check, (void *)baton,
                                                           APR_THREAD_TASK_PRIORITY_NORMAL, NULL);
                             }
 #endif
@@ -958,7 +953,6 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                         workers++;
                     }
                 }
-                /* s = s->next; */
             }
             break;
 
@@ -967,27 +961,37 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                          "stopping %s watchdog.",
                          HCHECK_WATHCHDOG_NAME);
 #if HC_USE_THREADS
-            rv =  apr_thread_pool_destroy(ctx->hctp);
-            if (rv != APR_SUCCESS) {
-                ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03315)
-                             "apr_thread_pool_destroy() failed");
+            if (hctp) {
+                rv =  apr_thread_pool_destroy(hctp);
+                if (rv != APR_SUCCESS) {
+                    ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03315)
+                                 "apr_thread_pool_destroy() failed");
+                }
             }
 #endif
-            ctx->hctp = NULL;
+            hctp = NULL;
             break;
     }
     return rv;
 }
-
+static int hc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
+                         apr_pool_t *ptemp)
+{
+    tpsize = HC_THREADPOOL_SIZE;
+    return OK;
+}
 static int hc_post_config(apr_pool_t *p, apr_pool_t *plog,
-                       apr_pool_t *ptemp, server_rec *s)
+                       apr_pool_t *ptemp, server_rec *main_s)
 {
     apr_status_t rv;
-    sctx_t *ctx;
+    server_rec *s = main_s;
 
     APR_OPTIONAL_FN_TYPE(ap_watchdog_get_instance) *hc_watchdog_get_instance;
     APR_OPTIONAL_FN_TYPE(ap_watchdog_register_callback) *hc_watchdog_register_callback;
 
+    if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) {
+        return OK;
+    }
     hc_watchdog_get_instance = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_get_instance);
     hc_watchdog_register_callback = APR_RETRIEVE_OPTIONAL_FN(ap_watchdog_register_callback);
     if (!hc_watchdog_get_instance || !hc_watchdog_register_callback) {
@@ -995,10 +999,7 @@ static int hc_post_config(apr_pool_t *p, apr_pool_t *plog,
                      "mod_watchdog is required");
         return !OK;
     }
-    ctx = (sctx_t *) ap_get_module_config(s->module_config,
-                                          &proxy_hcheck_module);
-
-    rv = hc_watchdog_get_instance(&ctx->watchdog,
+    rv = hc_watchdog_get_instance(&watchdog,
                                   HCHECK_WATHCHDOG_NAME,
                                   0, 1, p);
     if (rv) {
@@ -1007,18 +1008,31 @@ static int hc_post_config(apr_pool_t *p, apr_pool_t *plog,
                      HCHECK_WATHCHDOG_NAME);
         return !OK;
     }
-    rv = hc_watchdog_register_callback(ctx->watchdog,
-            apr_time_from_sec(HCHECK_WATHCHDOG_INTERVAL),
-            ctx,
-            hc_watchdog_callback);
-    if (rv) {
-        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03264)
-                     "Failed to register watchdog callback (%s)",
-                     HCHECK_WATHCHDOG_NAME);
-        return !OK;
+    while (s) {
+        sctx_t *ctx = ap_get_module_config(s->module_config,
+                                           &proxy_hcheck_module);
+
+        if (s != ctx->s) {
+            ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, s, APLOGNO(10019)
+                         "Missing unique per-server context: %s (%pp:%pp) (no hchecks)",
+                         s->server_hostname, s, ctx->s);
+            s = s->next;
+            continue;
+        }
+        rv = hc_watchdog_register_callback(watchdog,
+                apr_time_from_sec(HCHECK_WATHCHDOG_INTERVAL),
+                ctx,
+                hc_watchdog_callback);
+        if (rv) {
+            ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, APLOGNO(03264)
+                         "Failed to register watchdog callback (%s)",
+                         HCHECK_WATHCHDOG_NAME);
+            return !OK;
+        }
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03265)
+                     "watchdog callback registered (%s for %s)", HCHECK_WATHCHDOG_NAME, s->server_hostname);
+        s = s->next;
     }
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03265)
-                 "watchdog callback registered (%s)", HCHECK_WATHCHDOG_NAME);
     return OK;
 }
 
@@ -1171,7 +1185,7 @@ static const command_rec command_table[] = {
     AP_INIT_RAW_ARGS("ProxyHCExpr", set_hc_condition, NULL, OR_FILEINFO,
                      "Define a health check condition ruleset expression"),
 #if HC_USE_THREADS
-    AP_INIT_TAKE1("ProxyHCTPsize", set_hc_tpsize, NULL, OR_FILEINFO,
+    AP_INIT_TAKE1("ProxyHCTPsize", set_hc_tpsize, NULL, RSRC_CONF,
                      "Set size of health check thread pool"),
 #endif
     { NULL }
@@ -1185,6 +1199,7 @@ static void hc_register_hooks(apr_pool_t *p)
     APR_REGISTER_OPTIONAL_FN(hc_show_exprs);
     APR_REGISTER_OPTIONAL_FN(hc_select_exprs);
     APR_REGISTER_OPTIONAL_FN(hc_valid_expr);
+    ap_hook_pre_config(hc_pre_config, NULL, NULL, APR_HOOK_MIDDLE);
     ap_hook_post_config(hc_post_config, aszPre, aszSucc, APR_HOOK_LAST);
     ap_hook_expr_lookup(hc_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
 }