From 8d956d17809a8a6f9d9bcb669e9a55388a5b4f7c Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Tue, 25 Nov 2025 11:39:28 +0000 Subject: [PATCH 1/2] mod_proxy_hcheck: Fix healthcheck disabled due to child restart while updating When a child gets restarted while the healthcheck watchdog running for a worker, the healcheck will be disabled for that worker indefinitively because its ->updated time remains zero. Fix all zero ->updated time at startup. * mod_proxy_hcheck.c(hc_watchdog_callback): Have AP_WATCHDOG_STATE_STARTING set the ->updated time of all the workers to "now" (if zero). Move up scoped variables common to AP_WATCHDOG_STATE_{STARTING,RUNNING} loops. Reported by: Lubos Uhliarik git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1929972 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/mod_proxy_hcheck.c | 46 ++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/modules/proxy/mod_proxy_hcheck.c b/modules/proxy/mod_proxy_hcheck.c index 70f1de8f453..48e8cf903f1 100644 --- a/modules/proxy/mod_proxy_hcheck.c +++ b/modules/proxy/mod_proxy_hcheck.c @@ -992,12 +992,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; + proxy_worker **workers; + proxy_worker *worker; + apr_time_t now; + int i, n; + + conf = ap_get_module_config(s->module_config, &proxy_module); 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 a child exits while running an hcheck the ->updated time will + * be zero, preventing further hcheck for the worker. + */ + now = apr_time_now(); + balancer = (proxy_balancer *)conf->balancers->elts; + for (i = 0; i < conf->balancers->nelts; i++, balancer++) { + workers = (proxy_worker **)balancer->workers->elts; + for (n = 0; n < balancer->workers->nelts; n++, workers++) { + worker = *workers; + if (worker->s->updated == 0) { + worker->s->updated = now; + } + } + } #if HC_USE_THREADS if (tpsize && hctp == NULL) { rv = apr_thread_pool_create(&hctp, tpsize, @@ -1023,29 +1043,28 @@ static apr_status_t hc_watchdog_callback(int state, void *data, case AP_WATCHDOG_STATE_RUNNING: /* loop thru all workers */ - 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; - apr_time_t now; - proxy_worker **workers; - proxy_worker *worker; /* Have any new balancers or workers been added dynamically? */ ap_proxy_sync_balancer(balancer, s, conf); - workers = (proxy_worker **)balancer->workers->elts; + now = apr_time_now(); - for (n = 0; n < balancer->workers->nelts; n++) { + workers = (proxy_worker **)balancer->workers->elts; + for (n = 0; n < balancer->workers->nelts; n++, workers++) { worker = *workers; if (!PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED) && (worker->s->method != NONE) && - (worker->s->updated != 0) && - (now > worker->s->updated + worker->s->interval)) { + (now > worker->s->updated + worker->s->interval) && + (worker->s->updated != 0)) { baton_t *baton; apr_pool_t *ptemp; + /* Zero to prevent concurrent checks for the same worker, + * should a check take longer than the watchdog interval. + */ + worker->s->updated = 0; + ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "Checking %s worker: %s [%d] (%pp)", balancer->s->name, worker->s->name_ex, worker->s->method, worker); @@ -1063,7 +1082,7 @@ static apr_status_t hc_watchdog_callback(int state, void *data, apr_pool_destroy(ptemp); return rv; } - worker->s->updated = 0; + #if HC_USE_THREADS if (hctp) { apr_thread_pool_push(hctp, hc_check, (void *)baton, @@ -1077,7 +1096,6 @@ static apr_status_t hc_watchdog_callback(int state, void *data, hc_check(NULL, baton); } } - workers++; } } } From a3a90b6898865fe4734247c4f8b07d3203dd1f74 Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Tue, 25 Nov 2025 11:43:03 +0000 Subject: [PATCH 2/2] Follow up to r1929972: CHANGES entry. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1929973 13f79535-47bb-0310-9956-ffa450edef68 --- changes-entries/proxy_heathcheck_updated.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changes-entries/proxy_heathcheck_updated.txt diff --git a/changes-entries/proxy_heathcheck_updated.txt b/changes-entries/proxy_heathcheck_updated.txt new file mode 100644 index 00000000000..afd1359fd02 --- /dev/null +++ b/changes-entries/proxy_heathcheck_updated.txt @@ -0,0 +1,2 @@ + *) mod_proxy_hcheck: Fix healthcheck disabled due to child restart while + updating. [Yann Ylavic]