Skip to content

Commit

Permalink
Issue 6080 - ns-slapd crash in referint_get_config
Browse files Browse the repository at this point in the history
Bug description:
	Referential integrity plugin spawn a thread to run
	integrity check/update in a deferred way. It uses a log
	file to pipe changes to check. The name of the file,
	stored in the config, is read periodically.
	At shutdown, referint plugin close callback notifies
	the thread to stop and free the config.
	The problem is that the thread may check the config
	while it was notify to stop.

Fix description:
	synchronize the plugin close function (referint_postop_close)
	and the batch thread (referint_thread_func).
	When the batch thread starts it set 'batch_thread_running'
	and reset it when it stops.
	The plugin close function notifes the batch thread to stop
	(via keeprunning==0) and then wait 'batch_thread_running' is
	reset

relates: 389ds#6080

Reviewed by: Pierre Rogier (thanks !)
  • Loading branch information
tbordaz committed Mar 18, 2024
1 parent 4fe22ec commit dacd464
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion ldap/servers/plugins/referint/referint.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static pthread_mutex_t keeprunning_mutex;
static pthread_cond_t keeprunning_cv;

static int keeprunning = 0;
static uint64_t batch_thread_running = 0;
static referint_config *config = NULL;
static Slapi_DN *_ConfigAreaDN = NULL;
static Slapi_DN *_pluginDN = NULL;
Expand Down Expand Up @@ -1360,14 +1361,26 @@ referint_postop_start(Slapi_PBlock *pb)
int
referint_postop_close(Slapi_PBlock *pb __attribute__((unused)))
{
/* signal the thread to exit */
/* signal the batch thread to exit */
if (referint_get_delay() > 0) {
pthread_mutex_lock(&keeprunning_mutex);
keeprunning = 0;
pthread_cond_signal(&keeprunning_cv);
pthread_mutex_unlock(&keeprunning_mutex);
}

/* waiting for the batch thread to exit */
while (1) {
if (slapi_atomic_load_64(&batch_thread_running, __ATOMIC_ACQUIRE) == 0) {
/* batch thread exited */
break;
}

DS_Sleep(PR_MillisecondsToInterval(1000));
}



slapi_destroy_rwlock(config_rwlock);
config_rwlock = NULL;

Expand Down Expand Up @@ -1395,10 +1408,23 @@ referint_thread_func(void *arg __attribute__((unused)))
int delay;
int no_changes;

slapi_atomic_store_64(&batch_thread_running, 1, __ATOMIC_RELEASE);

/*
* keep running this thread until plugin is signaled to close
*/
while (1) {
/*
* In case of shutdown, plugin close function (referint_postop_close)
* is waiting for the end of that thread to do the cleanup
*/
pthread_mutex_lock(&keeprunning_mutex);
if (keeprunning == 0) {
pthread_mutex_unlock(&keeprunning_mutex);
break;
}
pthread_mutex_unlock(&keeprunning_mutex);

/* refresh the config */
slapi_ch_free_string(&logfilename);
referint_get_config(&delay, &logfilename);
Expand Down Expand Up @@ -1498,6 +1524,8 @@ referint_thread_func(void *arg __attribute__((unused)))
pthread_mutex_unlock(&keeprunning_mutex);
}

slapi_atomic_store_64(&batch_thread_running, 0, __ATOMIC_RELEASE);

/* cleanup resources allocated in start */
pthread_mutex_destroy(&keeprunning_mutex);
pthread_cond_destroy(&keeprunning_cv);
Expand Down

0 comments on commit dacd464

Please sign in to comment.