At every startup, in balancer_post_config:
conf->max_balancers = conf->balancers->nelts + conf->bgrowth;
which means that if you add a balancer and restart, storage->create()
(eg. slotmem_create) will try to find an existing slot with this ID
and the exact ALIGNED_PROXY_BALANCER_SHARED_SIZE * conf->max_balancers
size, and fail:
if (apr_shm_size_get(shm) != size) {
apr_shm_detach(shm);
ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(02599)
"existing shared memory for %s could not be used
(failed size check)",
fname);
return APR_EINVAL;
}
By using storage->attach() first (which is based on the ID only and
returns the existing item_size and item_num), we can do the check
ourselves and fail only if conf->max_balancers > item_num, allowing
for balancers to be added thanks to growth margin used at startup.
On Tue, Aug 25, 2015 at 2:12 PM, Jim Jagielski <[email protected]> wrote:
> How and when do ALIGNED_PROXY_BALANCER_SHARED_SIZE and conf->max_balancers
> change???
>
>> On Aug 21, 2015, at 8:34 AM, [email protected] wrote:
>>
>> Author: ylavic
>> Date: Fri Aug 21 12:34:02 2015
>> New Revision: 1696960
>>
>> URL: http://svn.apache.org/r1696960
>> Log:
>> mod_proxy_balancer: Fix balancers and balancer members reuse on
>> restart when new ones are added. PR 58024.
>>
>> Since slotmem_create() issues a strict check on the size of an existing
>> slot before reusing it, it won't reuse existing balancers and members when
>> new ones are added during restart (whereas growth margins would allow it).
>> Fix this by using slotmem_attach() first and if it succeeds do the checks
>> based on the returned previous number of existing entries.
>>
>> Modified:
>> httpd/httpd/trunk/CHANGES
>> httpd/httpd/trunk/docs/log-message-tags/next-number
>> httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
>>
>> Modified: httpd/httpd/trunk/CHANGES
>> URL:
>> http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1696960&r1=1696959&r2=1696960&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/CHANGES [utf-8] (original)
>> +++ httpd/httpd/trunk/CHANGES [utf-8] Fri Aug 21 12:34:02 2015
>> @@ -1,6 +1,9 @@
>> -*- coding: utf-8
>> -*-
>> Changes with Apache 2.5.0
>>
>> + *) mod_proxy_balancer: Fix balancers and balancer members reuse on
>> + restart when new ones are added. PR 58024. [Yann Ylavic]
>> +
>> *) mod_socache_memcache: Add the 'MemcacheConnTTL' directive to control how
>> long to keep idle connections with the memcache server(s).
>> Change default value from 600 usec (!) to 15 sec. PR 58091
>>
>> Modified: httpd/httpd/trunk/docs/log-message-tags/next-number
>> URL:
>> http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/log-message-tags/next-number?rev=1696960&r1=1696959&r2=1696960&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/docs/log-message-tags/next-number (original)
>> +++ httpd/httpd/trunk/docs/log-message-tags/next-number Fri Aug 21 12:34:02
>> 2015
>> @@ -1 +1 @@
>> -2964
>> +2966
>>
>> Modified: httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c
>> URL:
>> http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c?rev=1696960&r1=1696959&r2=1696960&view=diff
>> ==============================================================================
>> --- httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c (original)
>> +++ httpd/httpd/trunk/modules/proxy/mod_proxy_balancer.c Fri Aug 21 12:34:02
>> 2015
>> @@ -761,8 +761,11 @@ static int balancer_post_config(apr_pool
>> char *id;
>> proxy_balancer *balancer;
>> ap_slotmem_type_t type;
>> + apr_size_t attached_size;
>> + unsigned int attached_num;
>> void *sconf = s->module_config;
>> conf = (proxy_server_conf *)ap_get_module_config(sconf,
>> &proxy_module);
>> +
>> /*
>> * During create_proxy_config() we created a dummy id. Now that
>> * we have identifying info, we can create the real id
>> @@ -794,11 +797,39 @@ static int balancer_post_config(apr_pool
>> (int)ALIGNED_PROXY_BALANCER_SHARED_SIZE,
>> (int)conf->balancers->nelts, conf->max_balancers);
>>
>> - rv = storage->create(&new, conf->id,
>> - ALIGNED_PROXY_BALANCER_SHARED_SIZE,
>> - conf->max_balancers, type, pconf);
>> + /* First try to attach() since the number of configured
>> balancers
>> + * may have changed during restart, and we don't want create()
>> to
>> + * fail because the overall size * number of entries is not
>> stricly
>> + * identical to the previous run. There may still be enough
>> room
>> + * for this new run thanks to bgrowth margin, so if attach()
>> + * succeeds we can only check for the number of available
>> entries
>> + * to be *greater or* equal to what we need now. If attach()
>> fails
>> + * we simply fall back to create().
>> + */
>> + rv = storage->attach(&new, conf->id,
>> + &attached_size, &attached_num,
>> + pconf);
>> + if (rv != APR_SUCCESS) {
>> + rv = storage->create(&new, conf->id,
>> + ALIGNED_PROXY_BALANCER_SHARED_SIZE,
>> + conf->max_balancers, type, pconf);
>> + }
>> + else {
>> + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02964)
>> + "Balancers attached: %d, %d (%d)",
>> + (int)ALIGNED_PROXY_BALANCER_SHARED_SIZE,
>> + (int)attached_num, conf->max_balancers);
>> + if (attached_size == ALIGNED_PROXY_BALANCER_SHARED_SIZE
>> + && attached_num >= conf->balancers->nelts) {
>> + conf->max_balancers = attached_num;
>> + }
>> + else {
>> + rv = APR_ENOSPC;
>> + }
>> + }
>> if (rv != APR_SUCCESS) {
>> - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01179)
>> "balancer slotmem_create failed");
>> + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01179)
>> + "balancer slotmem create or attach failed");
>> return !OK;
>> }
>> conf->bslot = new;
>> @@ -864,11 +895,32 @@ static int balancer_post_config(apr_pool
>> (int)ALIGNED_PROXY_WORKER_SHARED_SIZE,
>> (int)balancer->max_workers, i);
>>
>> - rv = storage->create(&new, balancer->s->sname,
>> - ALIGNED_PROXY_WORKER_SHARED_SIZE,
>> - balancer->max_workers, type, pconf);
>> + /* try to attach first (see rationale from balancers above) */
>> + rv = storage->attach(&new, balancer->s->sname,
>> + &attached_size, &attached_num,
>> + pconf);
>> + if (rv != APR_SUCCESS) {
>> + rv = storage->create(&new, balancer->s->sname,
>> + ALIGNED_PROXY_WORKER_SHARED_SIZE,
>> + balancer->max_workers, type, pconf);
>> + }
>> + else {
>> + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02965)
>> + "Workers attached: %s (%s), %d, %d (%d) [%u]",
>> + balancer->s->name, balancer->s->sname,
>> + (int)ALIGNED_PROXY_WORKER_SHARED_SIZE,
>> + (int)attached_num, balancer->max_workers, i);
>> + if (attached_size == ALIGNED_PROXY_WORKER_SHARED_SIZE
>> + && attached_num >= balancer->workers->nelts) {
>> + balancer->max_workers = attached_num;
>> + }
>> + else {
>> + rv = APR_ENOSPC;
>> + }
>> + }
>> if (rv != APR_SUCCESS) {
>> - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01185)
>> "worker slotmem_create failed");
>> + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(01185)
>> + "worker slotmem create or attach failed");
>> return !OK;
>> }
>> balancer->wslot = new;
>>
>>
>