Blame SOURCES/0080-Ticket-408-Fix-crash-when-disabling-enabling-the-set.patch

cc3dff
From f649d36ecf04926704add30a9f3179bd862de4c1 Mon Sep 17 00:00:00 2001
cc3dff
From: Mark Reynolds <mreynolds@redhat.com>
cc3dff
Date: Thu, 16 Jan 2014 15:21:28 -0500
cc3dff
Subject: [PATCH 80/83] Ticket 408 - Fix crash when disabling/enabling the
cc3dff
 setting
cc3dff
cc3dff
Bug Description:  Enabling/disabling can lead to crash as the setting
cc3dff
                  was not designed to be dynamically updated.
cc3dff
cc3dff
Fix Description:  Do not use the actual config setting to determine if the
cc3dff
                  cache is enabled.  Instead we record when the cache is
cc3dff
                  initialized.  The server still needs to be restarted for
cc3dff
                  the config change to take effect.
cc3dff
cc3dff
                  Also freed the cache at server shtudown.
cc3dff
cc3dff
https://fedorahosted.org/389/ticket/408
cc3dff
cc3dff
Reviewed by: rmeggins(Thanks!)
cc3dff
(cherry picked from commit 03c90f04065059ee310e9fa7d98228e0aa39fa50)
cc3dff
(cherry picked from commit 50ad64a442495810a84558c6c17dcc2263b815b6)
cc3dff
(cherry picked from commit e0d85bead832c6aa7a2ec01157ab786a53fb5272)
cc3dff
---
cc3dff
 ldap/servers/slapd/back-ldbm/monitor.c |  2 +-
cc3dff
 ldap/servers/slapd/dn.c                | 93 +++++++++++++++++++++++++++-------
cc3dff
 ldap/servers/slapd/main.c              |  1 +
cc3dff
 ldap/servers/slapd/slapi-private.h     |  2 +
cc3dff
 4 files changed, 78 insertions(+), 20 deletions(-)
cc3dff
cc3dff
diff --git a/ldap/servers/slapd/back-ldbm/monitor.c b/ldap/servers/slapd/back-ldbm/monitor.c
cc3dff
index 3427809..409c771 100644
cc3dff
--- a/ldap/servers/slapd/back-ldbm/monitor.c
cc3dff
+++ b/ldap/servers/slapd/back-ldbm/monitor.c
cc3dff
@@ -146,7 +146,7 @@ int ldbm_back_monitor_instance_search(Slapi_PBlock *pb, Slapi_Entry *e,
cc3dff
         MSET("maxDnCacheCount");
cc3dff
     }
cc3dff
     /* normalized dn cache stats */
cc3dff
-    if(config_get_ndn_cache_enabled()){
cc3dff
+    if(ndn_cache_started()){
cc3dff
         ndn_cache_get_stats(&hits, &tries, &size, &maxsize, &count);
cc3dff
         sprintf(buf, "%" NSPRIu64, (long long unsigned int)tries);
cc3dff
         MSET("normalizedDnCacheTries");
cc3dff
diff --git a/ldap/servers/slapd/dn.c b/ldap/servers/slapd/dn.c
cc3dff
index 9530b84..1eab631 100644
cc3dff
--- a/ldap/servers/slapd/dn.c
cc3dff
+++ b/ldap/servers/slapd/dn.c
cc3dff
@@ -103,6 +103,7 @@ static void ndn_cache_update_lru(struct ndn_cache_lru **node);
cc3dff
 static void ndn_cache_add(char *dn, size_t dn_len, char *ndn, size_t ndn_len);
cc3dff
 static void ndn_cache_delete(char *dn);
cc3dff
 static void ndn_cache_flush();
cc3dff
+static void ndn_cache_free();
cc3dff
 static int ndn_started = 0;
cc3dff
 static PRLock *lru_lock = NULL;
cc3dff
 static Slapi_RWLock *ndn_cache_lock = NULL;
cc3dff
@@ -2751,7 +2752,7 @@ ndn_hash_string(const void *key)
cc3dff
 void
cc3dff
 ndn_cache_init()
cc3dff
 {
cc3dff
-    if(!config_get_ndn_cache_enabled()){
cc3dff
+    if(!config_get_ndn_cache_enabled() || ndn_started){
cc3dff
         return;
cc3dff
     }
cc3dff
     ndn_cache_hashtable = PL_NewHashTable( NDN_CACHE_BUCKETS, ndn_hash_string, PL_CompareStrings, PL_CompareValues, 0, 0);
cc3dff
@@ -2764,24 +2765,49 @@ ndn_cache_init()
cc3dff
     ndn_cache->cache_size = sizeof(struct ndn_cache_ctx) + sizeof(PLHashTable) + sizeof(PLHashTable);
cc3dff
     ndn_cache->head = NULL;
cc3dff
     ndn_cache->tail = NULL;
cc3dff
-
cc3dff
+    ndn_started = 1;
cc3dff
     if ( NULL == ( lru_lock = PR_NewLock()) ||  NULL == ( ndn_cache_lock = slapi_new_rwlock())) {
cc3dff
-        char *errorbuf = NULL;
cc3dff
-        if(ndn_cache_hashtable){
cc3dff
-            PL_HashTableDestroy(ndn_cache_hashtable);
cc3dff
-        }
cc3dff
-        ndn_cache_hashtable = NULL;
cc3dff
-        config_set_ndn_cache_enabled(CONFIG_NDN_CACHE, "off", errorbuf, 1 );
cc3dff
-        slapi_counter_destroy(&ndn_cache->cache_hits);
cc3dff
-        slapi_counter_destroy(&ndn_cache->cache_tries);
cc3dff
-        slapi_counter_destroy(&ndn_cache->cache_misses);
cc3dff
-        slapi_ch_free((void **)&ndn_cache);
cc3dff
+        ndn_cache_destroy();
cc3dff
         slapi_log_error( SLAPI_LOG_FATAL, "ndn_cache_init", "Failed to create locks.  Disabling cache.\n" );
cc3dff
-    } else {
cc3dff
-        ndn_started = 1;
cc3dff
     }
cc3dff
 }
cc3dff
 
cc3dff
+void
cc3dff
+ndn_cache_destroy()
cc3dff
+{
cc3dff
+    char *errorbuf = NULL;
cc3dff
+
cc3dff
+    if(!ndn_started){
cc3dff
+        return;
cc3dff
+    }
cc3dff
+    if(lru_lock){
cc3dff
+        PR_DestroyLock(lru_lock);
cc3dff
+        lru_lock = NULL;
cc3dff
+    }
cc3dff
+    if(ndn_cache_lock){
cc3dff
+        slapi_destroy_rwlock(ndn_cache_lock);
cc3dff
+        ndn_cache_lock = NULL;
cc3dff
+    }
cc3dff
+    if(ndn_cache_hashtable){
cc3dff
+    	ndn_cache_free();
cc3dff
+        PL_HashTableDestroy(ndn_cache_hashtable);
cc3dff
+        ndn_cache_hashtable = NULL;
cc3dff
+    }
cc3dff
+    config_set_ndn_cache_enabled(CONFIG_NDN_CACHE, "off", errorbuf, 1 );
cc3dff
+    slapi_counter_destroy(&ndn_cache->cache_hits);
cc3dff
+    slapi_counter_destroy(&ndn_cache->cache_tries);
cc3dff
+    slapi_counter_destroy(&ndn_cache->cache_misses);
cc3dff
+    slapi_ch_free((void **)&ndn_cache);
cc3dff
+
cc3dff
+    ndn_started = 0;
cc3dff
+}
cc3dff
+
cc3dff
+int
cc3dff
+ndn_cache_started()
cc3dff
+{
cc3dff
+    return ndn_started;
cc3dff
+}
cc3dff
+
cc3dff
 /*
cc3dff
  *  Look up this dn in the ndn cache
cc3dff
  */
cc3dff
@@ -2994,19 +3020,48 @@ ndn_cache_flush()
cc3dff
     slapi_log_error( SLAPI_LOG_CACHE, "ndn_cache_flush","Flushed cache.\n");
cc3dff
 }
cc3dff
 
cc3dff
+static void
cc3dff
+ndn_cache_free()
cc3dff
+{
cc3dff
+    struct ndn_cache_lru *node, *next, *flush_node;
cc3dff
+
cc3dff
+    if(!ndn_cache){
cc3dff
+        return;
cc3dff
+    }
cc3dff
+
cc3dff
+    node = ndn_cache->tail;
cc3dff
+    while(ndn_cache->cache_count){
cc3dff
+        flush_node = node;
cc3dff
+        /* update the lru */
cc3dff
+        next = node->prev;
cc3dff
+        if(next){
cc3dff
+            next->next = NULL;
cc3dff
+        }
cc3dff
+        ndn_cache->tail = next;
cc3dff
+        node = next;
cc3dff
+        /* now update the hash */
cc3dff
+        ndn_cache->cache_count--;
cc3dff
+        ndn_cache_delete(flush_node->key);
cc3dff
+        slapi_ch_free_string(&flush_node->key);
cc3dff
+        slapi_ch_free((void **)&flush_node);
cc3dff
+    }
cc3dff
+}
cc3dff
+
cc3dff
 /* this is already "write" locked from ndn_cache_add */
cc3dff
 static void
cc3dff
 ndn_cache_delete(char *dn)
cc3dff
 {
cc3dff
-    struct ndn_hash_val *ht_val;
cc3dff
+    struct ndn_hash_val *ht_entry;
cc3dff
 
cc3dff
-    ht_val = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
cc3dff
-    if(ht_val){
cc3dff
-        ndn_cache->cache_size -= ht_val->size;
cc3dff
-        slapi_ch_free_string(&ht_val->ndn);
cc3dff
+    ht_entry = (struct ndn_hash_val *)PL_HashTableLookupConst(ndn_cache_hashtable, dn);
cc3dff
+    if(ht_entry){
cc3dff
+        ndn_cache->cache_size -= ht_entry->size;
cc3dff
+        slapi_ch_free_string(&ht_entry->ndn);
cc3dff
+        slapi_ch_free((void **)&ht_entry);
cc3dff
         PL_HashTableRemove(ndn_cache_hashtable, dn);
cc3dff
     }
cc3dff
 }
cc3dff
+
cc3dff
 /* stats for monitor */
cc3dff
 void
cc3dff
 ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count)
cc3dff
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
cc3dff
index a17a2c5..ad8dd83 100644
cc3dff
--- a/ldap/servers/slapd/main.c
cc3dff
+++ b/ldap/servers/slapd/main.c
cc3dff
@@ -1280,6 +1280,7 @@ main( int argc, char **argv)
cc3dff
 cleanup:
cc3dff
 	SSL_ShutdownServerSessionIDCache();
cc3dff
 	SSL_ClearSessionCache();
cc3dff
+	ndn_cache_destroy();
cc3dff
 	NSS_Shutdown();
cc3dff
 	PR_Cleanup();
cc3dff
 #ifdef _WIN32
cc3dff
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
cc3dff
index 194f3fd..eaa5f98 100644
cc3dff
--- a/ldap/servers/slapd/slapi-private.h
cc3dff
+++ b/ldap/servers/slapd/slapi-private.h
cc3dff
@@ -392,6 +392,8 @@ Slapi_DN *slapi_sdn_init_normdn_passin(Slapi_DN *sdn, const char *dn);
cc3dff
 char *slapi_dn_normalize_original( char *dn );
cc3dff
 char *slapi_dn_normalize_case_original( char *dn );
cc3dff
 void ndn_cache_init();
cc3dff
+void ndn_cache_destroy();
cc3dff
+int ndn_cache_started();
cc3dff
 void ndn_cache_get_stats(PRUint64 *hits, PRUint64 *tries, size_t *size, size_t *max_size, long *count);
cc3dff
 #define NDN_DEFAULT_SIZE 20971520 /* 20mb - size of normalized dn cache */
cc3dff
 
cc3dff
-- 
cc3dff
1.8.1.4
cc3dff