From: Stefan Fritsch Date: Tue, 6 Oct 2009 19:39:38 +0000 (+0000) Subject: Work around broken cache management in mod_ldap: If LDAPSharedCacheSize is too X-Git-Tag: 2.3.3~192 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=da0e12aacfd9ba86d5e2d9343e1ba1d5dfb25fd9;p=apache Work around broken cache management in mod_ldap: If LDAPSharedCacheSize is too small, try to free some memory by purging the cache and log a warning. Also increase the default LDAPSharedCacheSize to 500000. This is a more realistic size suitable for the default values of 1024 for LdapCacheEntries and LdapOpCacheEntries. PR: 46749 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@822458 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 11c316d7b2..ef5c5c8916 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,12 @@ Changes with Apache 2.3.3 mod_proxy_ftp: NULL pointer dereference on error paths. [Stefan Fritsch , Joe Orton] + *) mod_ldap: If LDAPSharedCacheSize is too small, try harder to purge + some cache entries and log a warning. Also increase the default + LDAPSharedCacheSize to 500000. This is a more realistic size suitable + for the default values of 1024 for LdapCacheEntries/LdapOpCacheEntries. + PR 46749. [Stefan Fritsch] + *) mod_rewrite: Make sure that a hostname:port isn't fully qualified if the request is a CONNECT request. [Bill Zajac ] diff --git a/docs/manual/mod/mod_ldap.xml b/docs/manual/mod/mod_ldap.xml index ea184b427d..28f1711170 100644 --- a/docs/manual/mod/mod_ldap.xml +++ b/docs/manual/mod/mod_ldap.xml @@ -67,7 +67,7 @@ by other LDAP modules # be loaded. Change the "yourdomain.example.com" to
# match your domain.

- LDAPSharedCacheSize 200000
+ LDAPSharedCacheSize 500000
LDAPCacheEntries 1024
LDAPCacheTTL 600
LDAPOpCacheEntries 1024
@@ -412,12 +412,12 @@ by other LDAP modules LDAPSharedCacheSize Size in bytes of the shared-memory cache LDAPSharedCacheSize bytes -LDAPSharedCacheSize 102400 +LDAPSharedCacheSize 500000 server config

Specifies the number of bytes to allocate for the shared - memory cache. The default is 100kb. If set to 0, shared memory + memory cache. The default is 500kb. If set to 0, shared memory caching will not be used.

diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c index d01945a2e0..dc489a7110 100644 --- a/modules/ldap/util_ldap.c +++ b/modules/ldap/util_ldap.c @@ -2402,7 +2402,7 @@ static void *util_ldap_create_config(apr_pool_t *p, server_rec *s) apr_thread_mutex_create(&st->mutex, APR_THREAD_MUTEX_DEFAULT, st->pool); #endif - st->cache_bytes = 100000; + st->cache_bytes = 500000; st->search_cache_ttl = 600000000; st->search_cache_size = 1024; st->compare_cache_ttl = 600000000; diff --git a/modules/ldap/util_ldap_cache_mgr.c b/modules/ldap/util_ldap_cache_mgr.c index 13d824532b..085dd1da4d 100644 --- a/modules/ldap/util_ldap_cache_mgr.c +++ b/modules/ldap/util_ldap_cache_mgr.c @@ -442,6 +442,7 @@ void *util_ald_cache_fetch(util_ald_cache_t *cache, void *payload) void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload) { unsigned long hashval; + void *tmp_payload; util_cache_node_t *node; /* sanity check */ @@ -454,21 +455,68 @@ void *util_ald_cache_insert(util_ald_cache_t *cache, void *payload) util_ald_cache_purge(cache); if (cache->numentries >= cache->maxentries) { /* if the purge was not effective, we leave now to avoid an overflow */ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "Purge of LDAP cache failed"); return NULL; } } - /* should be safe to add an entry */ - if ((node = (util_cache_node_t *)util_ald_alloc(cache, sizeof(util_cache_node_t))) == NULL) { - return NULL; + node = (util_cache_node_t *)util_ald_alloc(cache, + sizeof(util_cache_node_t)); + if (node == NULL) { + /* + * XXX: The cache management should be rewritten to work + * properly when LDAPSharedCacheSize is too small. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "LDAPSharedCacheSize is too small. Increase it or " + "reduce LDAPCacheEntries/LDAPOpCacheEntries!"); + if (cache->numentries < cache->fullmark) { + /* + * We have not even reached fullmark, trigger a complete purge. + * This is still better than not being able to add new entries + * at all. + */ + cache->marktime = apr_time_now(); + } + util_ald_cache_purge(cache); + node = (util_cache_node_t *)util_ald_alloc(cache, + sizeof(util_cache_node_t)); + if (node == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "Could not allocate memory for LDAP cache entry"); + return NULL; + } } /* Take a copy of the payload before proceeeding. */ - payload = (*cache->copy)(cache, payload); - if (!payload) { - util_ald_free(cache, node); - return NULL; + tmp_payload = (*cache->copy)(cache, payload); + if (tmp_payload == NULL) { + /* + * XXX: The cache management should be rewritten to work + * properly when LDAPSharedCacheSize is too small. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, + "LDAPSharedCacheSize is too small. Increase it or " + "reduce LDAPCacheEntries/LDAPOpCacheEntries!"); + if (cache->numentries < cache->fullmark) { + /* + * We have not even reached fullmark, trigger a complete purge. + * This is still better than not being able to add new entries + * at all. + */ + cache->marktime = apr_time_now(); + } + util_ald_cache_purge(cache); + tmp_payload = (*cache->copy)(cache, payload); + if (tmp_payload == NULL) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, + "Could not allocate memory for LDAP cache value"); + util_ald_free(cache, node); + return NULL; + } } + payload = tmp_payload; /* populate the entry */ cache->inserts++;