Browse Source

Bug 676053 - export task followed by import task causes cache assertion

https://bugzilla.redhat.com/show_bug.cgi?id=676053

Description: When Simple Paged Results is requested and a page is
returned, one entry is read ahead to check whether more entries
exist or not.  The read-ahead retrieves an entry (if any) and adds
it into the entry cache.  Simple Paged Results code puts the read-
ahead entry back, but there was missing to call cache_return for
the entry (that decrementing refcnt).  If ldif2db.pl is called with
the cache state, it finds out the entry which is still referred.
This patch calls cache_return when the Simple Paged Results puts
the read-ahead entry back.  Plus, adding a debug function dump_hash.
Noriko Hosoi 14 years ago
parent
commit
00a1379427
2 changed files with 64 additions and 2 deletions
  1. 41 2
      ldap/servers/slapd/back-ldbm/cache.c
  2. 23 0
      ldap/servers/slapd/back-ldbm/ldbm_search.c

+ 41 - 2
ldap/servers/slapd/back-ldbm/cache.c

@@ -275,6 +275,42 @@ int remove_hash(Hashtable *ht, const void *key, size_t keylen)
     return 0;
 }
 
+#ifdef LDAP_CACHE_DEBUG
+void
+dump_hash(Hashtable *ht)
+{
+    u_long i;
+    void *e;
+    char ep_id[16];
+    char ep_ids[80];
+    char *p;
+    int ids_size = 80;
+
+    LDAPDebug0Args(LDAP_DEBUG_ANY, "entry cache:\n");
+    p = ep_ids;
+    for (i = 0; i < ht->size; i++) {
+        int len;
+        e = ht->slot[i];
+        if (NULL == e) {
+            continue;
+        }
+        do {
+            PR_snprintf(ep_id, 16, "%u", ((struct backcommon *)e)->ep_id);
+            len = strlen(ep_id);
+            if (ids_size < len + 1) {
+                LDAPDebug1Arg(LDAP_DEBUG_ANY, "%s\n", ep_ids);
+                p = ep_ids; ids_size = 80;
+            }
+            PR_snprintf(p, ids_size, "%s", ep_id);
+            p += len; ids_size -= len + 1;
+        } while (e = HASH_NEXT(ht, e));
+    }
+    if (p != ep_ids) {
+        LDAPDebug1Arg(LDAP_DEBUG_ANY, "%s\n", ep_ids);
+    }
+}
+#endif
+
 /* hashtable distribution stats --
  * slots: # of slots in the hashtable
  * total_entries: # of entries in the hashtable
@@ -574,9 +610,12 @@ static void entrycache_clear_int(struct cache *cache)
     }
     cache->c_maxsize = size;
     if (cache->c_curentries > 0) {
-       LDAPDebug1Arg(LDAP_DEBUG_ANY,
+        LDAPDebug1Arg(LDAP_DEBUG_ANY,
                      "entrycache_clear_int: there are still %ld entries "
-                     "in the entry cache. :/\n", cache->c_curentries);
+                     "in the entry cache.\n", cache->c_curentries);
+#ifdef LDAP_CACHE_DEBUG
+        dump_hash(cache->c_idtable);
+#endif
     }
 }
 

+ 23 - 0
ldap/servers/slapd/back-ldbm/ldbm_search.c

@@ -1458,9 +1458,32 @@ bail:
 void
 ldbm_back_prev_search_results( Slapi_PBlock *pb )
 {
+    backend *be;
+    ldbm_instance *inst;
     back_search_result_set *sr;
+
+    slapi_pblock_get( pb, SLAPI_BACKEND, &be );
+    if (!be) {
+        LDAPDebug0Args(LDAP_DEBUG_ANY,
+                       "ldbm_back_prev_search_results: no backend\n");
+        return;
+    }
+    inst = (ldbm_instance *) be->be_instance_info;
+    if (!inst) {
+        LDAPDebug0Args(LDAP_DEBUG_ANY,
+                       "ldbm_back_prev_search_results: no backend instance\n");
+        return;
+    }
     slapi_pblock_get( pb, SLAPI_SEARCH_RESULT_SET, &sr );
     if (sr) {
+        if (sr->sr_entry) {
+            /* The last entry should be returned to cache */
+            LDAPDebug1Arg(LDAP_DEBUG_BACKLDBM,
+                          "ldbm_back_prev_search_results: returning: %s\n",
+                          slapi_entry_get_dn_const(sr->sr_entry->ep_entry));
+            CACHE_RETURN (&inst->inst_cache, &(sr->sr_entry));
+            sr->sr_entry = NULL;
+        }
         idl_iterator_decrement(&(sr->sr_current));
     }
     return;