From 0590ea6e29fbc419dc371fd390a47fc8a74af142 Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Tue, 17 Dec 2013 20:07:26 -0700
Subject: [PATCH] fix various problems that cause a lot of valgrind noise, but are not harmful otherwise

---
 ldap/servers/plugins/retrocl/retrocl.c |    2 +
 ldap/servers/slapd/connection.c        |   40 +++++++++++++++++++++++++++++++-
 ldap/servers/slapd/daemon.c            |    3 +-
 ldap/servers/slapd/fe.h                |    2 +
 ldap/servers/slapd/operation.c         |    3 ++
 ldap/servers/slapd/plugin.c            |   21 ++++++++++++----
 ldap/servers/slapd/psearch.c           |    7 ++---
 7 files changed, 67 insertions(+), 11 deletions(-)

diff --git a/ldap/servers/plugins/retrocl/retrocl.c b/ldap/servers/plugins/retrocl/retrocl.c
index 1b77ecf..d21b085 100644
--- a/ldap/servers/plugins/retrocl/retrocl.c
+++ b/ldap/servers/plugins/retrocl/retrocl.c
@@ -427,7 +427,9 @@ static int retrocl_stop (Slapi_PBlock *pb)
   int rc = 0;
 
   slapi_ch_array_free(retrocl_attributes);
+  retrocl_attributes = NULL;
   slapi_ch_array_free(retrocl_aliases);
+  retrocl_aliases = NULL;
 
   retrocl_stop_trimming();  
   retrocl_be_changelog = NULL;
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index 2d8c91a..529a3b1 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -120,6 +120,8 @@ static void
 destroy_work_q(struct Slapi_work_q **work_q)
 {
 	if (work_q && *work_q) {
+		(*work_q)->op_stack_obj = NULL;
+		(*work_q)->work_item = NULL;
 		PR_StackPush(work_q_stack, (PRStackElem *)*work_q);
 		PR_AtomicIncrement(&work_q_stack_size);
 		if (work_q_stack_size > work_q_stack_size_max) {
@@ -2730,7 +2732,8 @@ op_thread_cleanup()
 	interval = PR_SecondsToInterval(3);
 #endif	
 	LDAPDebug( LDAP_DEBUG_ANY,
-		"slapd shutting down - signaling operation threads\n", 0, 0, 0);
+		   "slapd shutting down - signaling operation threads - op stack size %d max work q size %d max work q stack size %d\n",
+		   op_stack_size, work_q_size_max, work_q_stack_size_max);
 
 	PR_AtomicIncrement(&op_shutdown);
 	PR_Lock( work_q_lock );
@@ -2749,6 +2752,41 @@ op_thread_cleanup()
 #endif
 }
 
+/* do this after all worker threads have terminated */
+void
+connection_post_shutdown_cleanup()
+{
+	struct Slapi_op_stack *stack_obj;
+	int stack_cnt = 0;
+	struct Slapi_work_q *work_q;
+	int work_cnt = 0;
+
+	while ((work_q = (struct Slapi_work_q *)PR_StackPop(work_q_stack))) {
+		Connection *conn = (Connection *)work_q->work_item;
+		stack_obj = work_q->op_stack_obj;
+		if (stack_obj) {
+			if (conn) {
+				connection_remove_operation(conn, stack_obj->op);
+			}
+			connection_done_operation(conn, stack_obj);
+		}
+		slapi_ch_free((void **)&work_q);
+		work_cnt++;
+	}
+	PR_DestroyStack(work_q_stack);
+	work_q_stack = NULL;
+	while ((stack_obj = (struct Slapi_op_stack *)PR_StackPop(op_stack))) {
+		operation_free(&stack_obj->op, NULL);
+		slapi_ch_free((void **)&stack_obj);
+		stack_cnt++;
+	}
+	PR_DestroyStack(op_stack);
+	op_stack = NULL;
+	LDAPDebug2Args( LDAP_DEBUG_ANY,
+		   	"slapd shutting down - freed %d work q stack objects - freed %d op stack objects\n",
+		   	work_cnt, stack_cnt);
+}
+
 static void
 connection_add_operation(Connection* conn,Operation* op)
 {
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
index aed76ed..e7262dc 100644
--- a/ldap/servers/slapd/daemon.c
+++ b/ldap/servers/slapd/daemon.c
@@ -1353,7 +1353,8 @@ void slapd_daemon( daemon_ports_t *ports )
 	connection_table_free(the_connection_table);
 	the_connection_table= NULL;
 
-	be_cleanupall (); 
+	be_cleanupall ();
+	connection_post_shutdown_cleanup();
 	LDAPDebug( LDAP_DEBUG_TRACE, "slapd shutting down - backends closed down\n",
 			0, 0, 0 );
 	referrals_free();
diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
index bdab151..2504a4b 100644
--- a/ldap/servers/slapd/fe.h
+++ b/ldap/servers/slapd/fe.h
@@ -95,6 +95,8 @@ int handle_bad_certificate (void* clientData, PRFileDesc *prfd);
  * connection.c
  */
 void op_thread_cleanup();
+/* do this after all worker threads have terminated */
+void connection_post_shutdown_cleanup();
 
 /*
  * ntuserpin.c - Prompts for the key database passphrase.
diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
index ddbc512..ea7c5cc 100644
--- a/ldap/servers/slapd/operation.c
+++ b/ldap/servers/slapd/operation.c
@@ -236,12 +236,15 @@ operation_done( Slapi_Operation **op, Connection *conn )
 		slapi_ch_free_string( &(*op)->o_authtype );
 		if ( (*op)->o_searchattrs != NULL ) {
 			charray_free( (*op)->o_searchattrs );
+			(*op)->o_searchattrs = NULL;
 		}
 		if ( NULL != (*op)->o_params.request_controls ) {
 			ldap_controls_free( (*op)->o_params.request_controls );
+			(*op)->o_params.request_controls = NULL;
 		}
 		if ( NULL != (*op)->o_results.result_controls ) {
 			ldap_controls_free( (*op)->o_results.result_controls );
+			(*op)->o_results.result_controls = NULL;
 		}
 		slapi_ch_free_string(&(*op)->o_results.result_matched);
 #if defined(USE_OPENLDAP)
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index de9c01b..6781c30 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -1190,11 +1190,6 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int operation)
 					Slapi_Entry *newe;
 
 					pblock_init(&newpb);
-					/* 
-					 * config[plugin_index].e is freed up by
-					 * below function calls, but we may need
-					 * it later, so create a copy
-					 */
 					newe = slapi_entry_dup( config[plugin_index].e );
 					slapi_add_entry_internal_set_pb(&newpb, newe, NULL,
 									plugin_get_default_component_id(), plugin_actions);
@@ -1256,6 +1251,10 @@ plugin_dependency_startall(int argc, char** argv, char *errmsg, int operation)
 							index++;
 						}	
 					}
+				} else {
+					pblock_done(&(config[plugin_index].pb));
+					slapi_entry_free(config[plugin_index].e);
+					config[plugin_index].e = NULL;
 				}
 
 				/* decrement the type counter for this plugin type */
@@ -1375,6 +1374,8 @@ plugin_dependency_closeall()
 		    /* set plg_closed to 1 to prevent any further plugin pre/post op function calls */
 		    global_plugin_shutdown_order[index].plugin->plg_closed = 1;
 			plugins_closed++;
+			slapi_entry_free(global_plugin_shutdown_order[index].e);
+			global_plugin_shutdown_order[index].e = NULL;
 		}
 
 		index++;
@@ -1414,7 +1415,17 @@ plugin_startall(int argc, char** argv, int start_backends, int start_global)
 void 
 plugin_closeall(int close_backends, int close_globals)
 {
+	entry_and_plugin_t *iterp, *nextp;
+
 	plugin_dependency_closeall();
+	/* free the plugin dependency entry list */
+	iterp = dep_plugin_entries;
+	while (iterp) {
+		nextp = iterp->next;
+		slapi_entry_free(iterp->e);
+		slapi_ch_free((void **)&iterp);
+		iterp = nextp;
+	}
 }
 
 
diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c
index 0793348..b059a36 100644
--- a/ldap/servers/slapd/psearch.c
+++ b/ldap/servers/slapd/psearch.c
@@ -72,7 +72,6 @@ typedef struct _ps_entry_queue_node {
 typedef struct _psearch {
     Slapi_PBlock	*ps_pblock;
     PRLock		*ps_lock;
-    PRThread		*ps_tid;
     PRInt32		ps_complete;
     PSEQNode		*ps_eq_head;
     PSEQNode		*ps_eq_tail;
@@ -188,6 +187,7 @@ void
 ps_add( Slapi_PBlock *pb, ber_int_t changetypes, int send_entchg_controls )
 {
     PSearch	*ps;
+    PRThread		*ps_tid;
 
     if ( PS_IS_INITIALIZED() && NULL != pb ) {
 	/* Create the new node */
@@ -200,7 +200,7 @@ ps_add( Slapi_PBlock *pb, ber_int_t changetypes, int send_entchg_controls )
 	ps_add_ps( ps );
 
 	/* Start a thread to send the results */
-	ps->ps_tid = PR_CreateThread( PR_USER_THREAD, ps_send_results,
+	ps_tid = PR_CreateThread( PR_USER_THREAD, ps_send_results,
 		(void *) ps, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
 		PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE );
 
@@ -208,7 +208,7 @@ ps_add( Slapi_PBlock *pb, ber_int_t changetypes, int send_entchg_controls )
          * if the thread is not created succesfully.... we send 
          * error messages to the Log file 
          */ 
-       if(NULL == (ps->ps_tid)){ 
+       if(NULL == ps_tid){
             int prerr;
             prerr = PR_GetError(); 
             LDAPDebug(LDAP_DEBUG_ANY,"persistent search PR_CreateThread()failed in the " 
@@ -472,7 +472,6 @@ psearch_alloc()
 	slapi_ch_free((void **)&ps);
 	return( NULL );
     }
-    ps->ps_tid = (PRThread *) NULL;
     ps->ps_complete = 0;
     ps->ps_eq_head = ps->ps_eq_tail = (PSEQNode *) NULL;
     ps->ps_lasttime = (time_t) 0L;
-- 
1.7.1

