From c5e9bd7acc8b3fef57ee040b43217e9ba04410e7 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Dec 19 2013 02:44:45 +0000 Subject: Ticket #47645 reset stack, op fields to NULL - clean up stacks at shutdown - free unused plugin config entries https://fedorahosted.org/389/ticket/47645 Reviewed by: nhosoi (Thanks!) Branch: master Fix Description: description Platforms tested: RHEL6 x86_64 Flag Day: no Doc impact: no --- 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..617909d 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,18 @@ 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; + } + dep_plugin_entries = NULL; } 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;