From a1cd1984ae2a588b102a3102a199a5404e3686dd Mon Sep 17 00:00:00 2001 From: Yann Ylavic Date: Thu, 15 Mar 2018 23:15:49 +0000 Subject: [PATCH] Merge r1826845 from trunk: mod_slotmem_shm: SHMs need to be attached in MPM winnt children processes. We can't (re-)create them since they exist already and are owned by the parent process. Submitted by: ylavic Reviewed by: ylavic, covener, rjung git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1826897 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 +++ modules/slotmem/mod_slotmem_shm.c | 48 +++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index da634c676f..07dea06a1f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,10 @@ -*- coding: utf-8 -*- Changes with Apache 2.4.33 + *) mod_slomem_shm: Fix failure to create balancers's slotmems in Windows MPM, + where children processes need to attach them instead since they are owned + by the parent process already. [Yann Ylavic] + *) ab: try all destination socket addresses returned by apr_sockaddr_info_get instead of failing on first one when not available. Needed for instance if localhost resolves to both ::1 and 127.0.0.1 diff --git a/modules/slotmem/mod_slotmem_shm.c b/modules/slotmem/mod_slotmem_shm.c index e7599726d4..681515aa19 100644 --- a/modules/slotmem/mod_slotmem_shm.c +++ b/modules/slotmem/mod_slotmem_shm.c @@ -274,11 +274,30 @@ static apr_status_t restore_slotmem(sharedslotdesc_t *desc, return rv; } +/* + * Whether the module is called from a MPM that re-enter main() and + * pre/post_config phases. + */ +static APR_INLINE int is_child_process(void) +{ +#ifdef WIN32 + return getenv("AP_PARENT_PID") != NULL; +#else + return 0; +#endif +} + static apr_status_t cleanup_slotmem(void *is_startup) { int is_exiting = (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_EXITING); ap_slotmem_instance_t *mem; + if (is_child_process()) { + /* No reuse/retained data from here, let pconf cleanup everything */ + *retained_globallistmem = globallistmem = NULL; + return APR_SUCCESS; + } + /* When in startup/pre-config's cleanup, the retained data and global pool * are not used yet, but the SHMs contents were untouched hence they don't * need to be persisted, simply unlink them. @@ -439,17 +458,26 @@ static apr_status_t slotmem_create(ap_slotmem_instance_t **new, { if (fbased) { - apr_shm_remove(fname, pool); - rv = apr_shm_create(&shm, size, fname, gpool); + /* For MPMs (e.g. winnt) that run pre/post_config() phases in + * both the parent and children processes, SHMs created by the + * parent exist in the children already; only attach them. + */ + if (is_child_process()) { + rv = apr_shm_attach(&shm, fname, gpool); + } + else { + apr_shm_remove(fname, pool); + rv = apr_shm_create(&shm, size, fname, gpool); + } } else { rv = apr_shm_create(&shm, size, NULL, pool); } ap_log_error(APLOG_MARK, rv == APR_SUCCESS ? APLOG_DEBUG : APLOG_ERR, rv, ap_server_conf, APLOGNO(02611) - "create: apr_shm_create(%s) %s", - fname ? fname : "", - rv == APR_SUCCESS ? "succeeded" : "failed"); + "create: apr_shm_%s(%s) %s", + fbased && is_child_process() ? "attach" : "create", + fname, rv == APR_SUCCESS ? "succeeded" : "failed"); if (rv != APR_SUCCESS) { return rv; } @@ -811,7 +839,15 @@ static int pre_config(apr_pool_t *pconf, apr_pool_t *plog, } globallistmem = *retained_globallistmem; - if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG) { + /* For the first (dry-)loading or children in MPMs which (re-)run + * pre_config we don't need to retain slotmems, so use pconf and its + * normal cleanups. Otherwise we use ap_pglobal to match the lifetime + * of retained data and register our own cleanup to update them. + */ + if (is_child_process()) { + gpool = pconf; + } + else if (ap_state_query(AP_SQ_MAIN_STATE) != AP_SQ_MS_CREATE_PRE_CONFIG) { gpool = ap_pglobal; } else { -- 2.40.0