]> granicus.if.org Git - apache/commitdiff
Work around broken cache management in mod_ldap: If LDAPSharedCacheSize is too
authorStefan Fritsch <sf@apache.org>
Tue, 6 Oct 2009 19:39:38 +0000 (19:39 +0000)
committerStefan Fritsch <sf@apache.org>
Tue, 6 Oct 2009 19:39:38 +0000 (19:39 +0000)
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

CHANGES
docs/manual/mod/mod_ldap.xml
modules/ldap/util_ldap.c
modules/ldap/util_ldap_cache_mgr.c

diff --git a/CHANGES b/CHANGES
index 11c316d7b2cbc830ddb7baf39dd3f308ca671151..ef5c5c8916571234074fd77ad98276eb2844d752 100644 (file)
--- 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 <sf fritsch.de>, 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 <billz consultla.com>]
 
index ea184b427d797589de3ae9b01337d7517f8e9569..28f1711170c94eef5ff3f8da8af168f6336e36cf 100644 (file)
@@ -67,7 +67,7 @@ by other LDAP modules</description>
       # be loaded. Change the "yourdomain.example.com" to<br />
       # match your domain.<br />
       <br />
-      LDAPSharedCacheSize 200000<br />
+      LDAPSharedCacheSize 500000<br />
       LDAPCacheEntries 1024<br />
       LDAPCacheTTL 600<br />
       LDAPOpCacheEntries 1024<br />
@@ -412,12 +412,12 @@ by other LDAP modules</description>
 <name>LDAPSharedCacheSize</name>
 <description>Size in bytes of the shared-memory cache</description>
 <syntax>LDAPSharedCacheSize <var>bytes</var></syntax>
-<default>LDAPSharedCacheSize 102400</default>
+<default>LDAPSharedCacheSize 500000</default>
 <contextlist><context>server config</context></contextlist>
 
 <usage>
     <p>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.</p>
 </usage>
 </directivesynopsis>
index d01945a2e0c95cb4a2df3c4607aad70e13eac58d..dc489a71108f64ec0d1dd1b393e2179e94835b61 100644 (file)
@@ -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;
index 13d824532b004bdb90a5c75360dd691efc21dd22..085dd1da4d93bdf9b9aa7dc061a72b3fba73c3ae 100644 (file)
@@ -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++;