From 557417c7d35b026369c9fb526455a138559a40a7 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Thu, 27 Apr 2017 14:25:56 +0000 Subject: [PATCH] On the 2.4.x branch: 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 | 16 ---- docs/manual/mod/mod_proxy_hcheck.xml | 4 +- modules/proxy/mod_proxy_hcheck.c | 119 +++++++++++++++------------ 3 files changed, 69 insertions(+), 70 deletions(-) diff --git a/STATUS b/STATUS index d120a099c3..d337ab174d 100644 --- 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 ] diff --git a/docs/manual/mod/mod_proxy_hcheck.xml b/docs/manual/mod/mod_proxy_hcheck.xml index a27ce29631..72a26d5484 100644 --- a/docs/manual/mod/mod_proxy_hcheck.xml +++ b/docs/manual/mod/mod_proxy_hcheck.xml @@ -204,9 +204,9 @@ ProxyPass "/apps" "http://backend.example.com/" hctemplate=tcp5 ProxyHCTPsize -Sets the size of the threadpool used for the health check workers. +Sets the total server-wide size of the threadpool used for the health check workers. ProxyHCTPsize <size> -server configvirtual host +server config diff --git a/modules/proxy/mod_proxy_hcheck.c b/modules/proxy/mod_proxy_hcheck.c index 39a4914c2d..a458a38f7e 100644 --- a/modules/proxy/mod_proxy_hcheck.c +++ b/modules/proxy/mod_proxy_hcheck.c @@ -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); } -- 2.40.0