From 755c3f433a53a20c9ff2162e28a1f8d1129ec1d3 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 30 May 2016 14:52:52 +0300 Subject: [PATCH] Add support for properly shutdown priming thread --- ...-0001-wrap-add-wrapped-mutex-support.patch | 145 ++++++++++ ...backend-shutdown-for-priming-thread-.patch | 268 ++++++++++++++++++ ...shutdown-support-to-stop-priming-thr.patch | 92 ++++++ ...d-backend-shutdown-support-for-primi.patch | 99 +++++++ slapi-nis.spec | 11 + 5 files changed, 615 insertions(+) create mode 100644 slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch create mode 100644 slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch create mode 100644 slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch create mode 100644 slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch diff --git a/slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch b/slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch new file mode 100644 index 0000000..2b5f6fc --- /dev/null +++ b/slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch @@ -0,0 +1,145 @@ +From 43ea9a5c6cf7f2022f1e586bb4514564fd7826cb Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Tue, 26 Apr 2016 12:44:56 +0300 +Subject: [PATCH 1/4] wrap: add wrapped mutex support + +--- + src/wrap.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + src/wrap.h | 6 +++++ + 2 files changed, 96 insertions(+) + +diff --git a/src/wrap.c b/src/wrap.c +index c89638f..f8056a4 100644 +--- a/src/wrap.c ++++ b/src/wrap.c +@@ -79,6 +79,18 @@ struct wrapped_rwlock { + #endif + }; + ++struct wrapped_mutex { ++#if defined(USE_SLAPI_LOCKS) ++ Slapi_Mutex *mutex; ++#elif defined(USE_PTHREAD_LOCKS) ++ pthread_mutex_t mutex; ++#elif defined(USE_NSPR_LOCKS) ++ PRLock *mutex; ++#else ++#error "Unknown thread-safe locking model!" ++#endif ++}; ++ + #ifdef USE_NSPR_THREADS + static void + wrap_pthread_starter(void *p) +@@ -169,6 +181,84 @@ wrap_thread_stopfd(struct wrapped_thread *t) + return ret; + } + ++struct wrapped_mutex * ++wrap_new_mutex(void) ++{ ++ struct wrapped_mutex *mutex; ++ mutex = malloc(sizeof(*mutex)); ++ if (mutex == NULL) { ++ return NULL; ++ } ++#ifdef USE_SLAPI_LOCKS ++ mutex->mutex = slapi_new_mutex(); ++ if (mutex->mutex == NULL) { ++ free(mutex); ++ return NULL; ++ } ++#endif ++#ifdef USE_PTHREAD_LOCKS ++ if (pthread_mutex_init(&mutex->mutex, NULL) != 0) { ++ free(mutex); ++ return NULL; ++ } ++#endif ++#ifdef USE_NSPR_LOCKS ++ mutex->mutex = PR_NewLock(); ++ if (mutex->mutex == NULL) { ++ free(mutex); ++ return NULL; ++ } ++#endif ++ return mutex; ++} ++ ++void ++wrap_free_mutex(struct wrapped_mutex *mutex) ++{ ++#ifdef USE_SLAPI_LOCKS ++ slapi_destroy_mutex(mutex->mutex); ++#endif ++#ifdef USE_PTHREAD_LOCKS ++ pthread_mutex_destroy(&mutex->mutex); ++#endif ++#ifdef USE_NSPR_LOCKS ++ PR_DestroyLock(mutex->mutex); ++#endif ++ free(mutex); ++} ++ ++int ++wrap_mutex_lock(struct wrapped_mutex *mutex) ++{ ++#ifdef USE_SLAPI_LOCKS ++ slapi_lock_mutex(mutex->mutex); ++ return 0; ++#endif ++#ifdef USE_PTHREAD_LOCKS ++ return pthread_mutex_lock(&mutex->mutex); ++#endif ++#ifdef USE_NSPR_LOCKS ++ PR_Lock(mutex->mutex); ++ return 0; ++#endif ++} ++ ++int ++wrap_mutex_unlock(struct wrapped_mutex *mutex) ++{ ++#ifdef USE_SLAPI_LOCKS ++ return slapi_unlock_mutex(mutex->mutex); ++#endif ++#ifdef USE_PTHREAD_LOCKS ++ return pthread_mutex_unlock(&mutex->mutex); ++#endif ++#ifdef USE_NSPR_LOCKS ++ PR_Unlock(mutex->mutex); ++ return 0; ++#endif ++} ++ ++ + struct wrapped_rwlock * + wrap_new_rwlock(void) + { +diff --git a/src/wrap.h b/src/wrap.h +index 71bd326..2b797f7 100644 +--- a/src/wrap.h ++++ b/src/wrap.h +@@ -23,6 +23,7 @@ + #define wrap_h + + struct wrapped_thread; ++struct wrapped_mutex; + struct wrapped_rwlock; + + struct wrapped_thread * wrap_start_thread(void * (*fn)(struct wrapped_thread *), +@@ -31,6 +32,11 @@ void *wrap_stop_thread(struct wrapped_thread *t); + void *wrap_thread_arg(struct wrapped_thread *t); + int wrap_thread_stopfd(struct wrapped_thread *t); + ++struct wrapped_mutex *wrap_new_mutex(void); ++void wrap_free_mutex(struct wrapped_mutex *mutex); ++int wrap_mutex_lock(struct wrapped_mutex *mutex); ++int wrap_mutex_unlock(struct wrapped_mutex *mutex); ++ + struct wrapped_rwlock *wrap_new_rwlock(void); + void wrap_free_rwlock(struct wrapped_rwlock *rwlock); + int wrap_rwlock_rdlock(struct wrapped_rwlock *rwlock); +-- +2.7.4 + diff --git a/slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch b/slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch new file mode 100644 index 0000000..22550e0 --- /dev/null +++ b/slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch @@ -0,0 +1,268 @@ +From c5e89132f2ee017aa026f7b8009a2976b627fa3a Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Tue, 26 Apr 2016 13:00:44 +0300 +Subject: [PATCH 2/4] backend: support backend shutdown for priming thread + cancellation + +Launching a separate thread to populate map cache has a side effect that +the thread could be scheduled to execute over a shutdown time. If LDAP server +received the request to shutdown, we need to stop processing the +original source and shut the priming thread. + +Resolves: rhbz#1327197 +--- + src/back-shr.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++---------- + src/back-shr.h | 1 + + src/backend.h | 1 + + src/plugin.h | 3 ++ + 4 files changed, 92 insertions(+), 17 deletions(-) + +diff --git a/src/back-shr.c b/src/back-shr.c +index 0157582..7842e05 100644 +--- a/src/back-shr.c ++++ b/src/back-shr.c +@@ -665,25 +665,34 @@ backend_shr_get_vattr_sdnlist(struct plugin_state *state, + } + + struct backend_shr_data_init_cbdata { +- Slapi_PBlock *parent_pb; + struct plugin_state *state; + const char *filter; + }; + + #define PLUGIN_SCAN_DELAY 5 + +-static void +-backend_shr_data_initialize_thread_cb(void *arg) ++static void * ++backend_shr_data_initialize_thread_cb(struct wrapped_thread *t) + { +- struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; ++ struct backend_shr_data_init_cbdata *cbdata = wrap_thread_arg(t); + Slapi_PBlock *pb = NULL; + struct backend_set_config_entry_add_cbdata set_cbdata; + int result = 0, i = 0; + Slapi_Entry **entries = NULL; + struct plugin_state *state = NULL; + ++ /* We have to be cautious here as the thread can be executed after ++ * the plugin received a shutdown request, thus a number of checks here. */ ++ if (slapi_is_shutting_down()) { ++ return NULL; ++ } ++ + if (cbdata == NULL) { +- return; ++ return NULL; ++ } ++ ++ if ((cbdata->state == NULL) || (cbdata->state->plugin_base == NULL)) { ++ return NULL; + } + + state = cbdata->state; +@@ -694,13 +703,23 @@ backend_shr_data_initialize_thread_cb(void *arg) + * so we just wait some time. */ + DS_Sleep(PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); + +- backend_update_params(cbdata->parent_pb, state); ++ if (slapi_is_shutting_down()) { ++ return NULL; ++ } ++ ++ if (state->plugin_base == NULL) { ++ return NULL; ++ } ++ ++ pb = wrap_pblock_new(NULL); ++ backend_update_params(pb, state); ++ slapi_pblock_destroy(pb); + + slapi_log_error(SLAPI_LOG_PLUGIN, + state->plugin_desc->spd_id, + "searching under \"%s\" for configuration\n", + state->plugin_base); +- pb = wrap_pblock_new(cbdata->parent_pb); ++ pb = wrap_pblock_new(NULL); + slapi_search_internal_set_pb(pb, + state->plugin_base, + LDAP_SCOPE_ONELEVEL, +@@ -717,10 +736,10 @@ backend_shr_data_initialize_thread_cb(void *arg) + /* Do a search and collect found entries to avoid locking the backends */ + if (slapi_search_internal_pb(pb) == 0) { + if (map_wrlock() != 0) { +- slapi_log_error(SLAPI_LOG_PLUGIN, ++ slapi_log_error(SLAPI_LOG_FATAL, + state->plugin_desc->spd_id, + "failed to search under \"%s\" for " +- "configuration: failed to acquire a lock\n", ++ "configuration: failed to acquire a write lock to a map\n", + state->plugin_base); + goto done_with_lock; + } +@@ -728,6 +747,11 @@ backend_shr_data_initialize_thread_cb(void *arg) + if (result == 0) { + slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + for (i = 0; entries[i] != NULL; i++) { ++ /* We may be scheduled to run over shutdown time, exit early */ ++ if (slapi_is_shutting_down()) { ++ map_unlock(); ++ goto done_with_lock; ++ } + backend_set_config_entry_add_cb(entries[i], &set_cbdata); + } + } +@@ -746,6 +770,7 @@ done_with_lock: + } + + PR_AtomicSet(&state->ready_to_serve, 1); ++ return NULL; + } + + static void +@@ -754,11 +779,28 @@ backend_shr_data_initialize_thread(time_t when, void *arg) + struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; + PRThread *thread = NULL; + +- /* start data import as a separate thread */ +- thread = PR_CreateThread(PR_USER_THREAD, backend_shr_data_initialize_thread_cb, +- (void *)arg, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, +- PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); +- if (thread == NULL) { ++ if (slapi_is_shutting_down()) { ++ return; ++ } ++ ++ if (cbdata->state->priming_mutex == NULL) { ++ /* This mutex is allocated at plugin startup ++ * Without this mutex we can not enforce that shutdown wait for priming completion ++ * This is better to skip the priming ++ */ ++ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, "priming_mutex not initialized. Priming fails\n"); ++ return; ++ } ++ wrap_mutex_lock(cbdata->state->priming_mutex); ++ ++ if (!cbdata->state->start_priming_thread) { ++ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, ++ "Likely a shutdown occurred before we started \n"); ++ goto done; ++ } ++ ++ cbdata->state->priming_tid = wrap_start_thread(&backend_shr_data_initialize_thread_cb, arg); ++ if (cbdata->state->priming_tid == NULL) { + slapi_log_error(SLAPI_LOG_FATAL, + cbdata->state->plugin_desc->spd_id, + "unable to create compatibility tree scan thread!\n"); +@@ -769,6 +811,8 @@ backend_shr_data_initialize_thread(time_t when, void *arg) + cbdata->state->plugin_desc->spd_id, PLUGIN_SCAN_DELAY); + } + ++done: ++ wrap_mutex_unlock(cbdata->state->priming_mutex); + } + + /* Scan for the list of configured groups and sets. */ +@@ -779,6 +823,14 @@ backend_shr_startup(struct plugin_state *state, + { + struct backend_shr_data_init_cbdata *cbdata = NULL; + ++ if (slapi_is_shutting_down()) { ++ slapi_log_error(SLAPI_LOG_FATAL, ++ state->plugin_desc->spd_id, ++ "task for populating compatibility tree will " ++ "not be created due to upcoming server shutdown\n"); ++ return; ++ } ++ + cbdata = (struct backend_shr_data_init_cbdata *) + slapi_ch_malloc(sizeof(struct backend_shr_data_init_cbdata)); + +@@ -792,10 +844,10 @@ backend_shr_startup(struct plugin_state *state, + + PR_AtomicSet(&state->ready_to_serve, 0); + cbdata->state = state; +- cbdata->parent_pb = parent_pb; + cbdata->filter = filter; + +- /* Schedule running a callback that will create a thread */ ++ /* Schedule running a callback that will create a thread ++ * but make sure it is called a first thing when event loop is created */ + slapi_eq_once(backend_shr_data_initialize_thread, + cbdata, PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); + +@@ -808,6 +860,24 @@ backend_shr_startup(struct plugin_state *state, + + } + ++void ++backend_shr_shutdown(struct plugin_state *state) ++{ ++ /* Make sure the priming thread is stopped or will not start ++ * Note: priming_mutex will not be freed because the priming thread ++ * may access it independently of the server/plugin shutdown ++ */ ++ wrap_mutex_lock(state->priming_mutex); ++ state->start_priming_thread = 0; /* prevent spawing of priming thread */ ++ if (state->priming_tid == NULL) { ++ /* priming thread has not yet started or failed to start */ ++ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, ++ "At shutdown, priming thread not yet started or failed to start\n"); ++ } else { ++ wrap_stop_thread(state->priming_tid); ++ } ++ wrap_mutex_unlock(state->priming_mutex); ++} + /* Process a set configuration directory entry. Pull out the group and set + * names which are specified in the entry and delete each in turn. */ + int +@@ -2336,7 +2406,7 @@ backend_shr_modify_cb(Slapi_PBlock *pb) + backend_set_config_entry_add_cb(cbdata.e_post, &set_cbdata); + } + /* Lastly, if the entry is our own entry, re-read parameters. */ +- sdn = slapi_sdn_new_dn_byref(cbdata.state->plugin_base); ++ sdn = slapi_sdn_new_dn_byval(cbdata.state->plugin_base); + if (sdn != NULL) { + if ((strcmp(slapi_entry_get_ndn(cbdata.e_pre), + slapi_sdn_get_ndn(sdn)) == 0) || +diff --git a/src/back-shr.h b/src/back-shr.h +index 44c25fe..2caea5d 100644 +--- a/src/back-shr.h ++++ b/src/back-shr.h +@@ -39,6 +39,7 @@ void backend_shr_free_sdnlist(const Slapi_DN **sdnlist); + + void backend_shr_startup(struct plugin_state *state, + Slapi_PBlock *pb, const char *set_filter); ++void backend_shr_shutdown(struct plugin_state *state); + int backend_shr_betxn_postop_init(Slapi_PBlock *pb, + struct plugin_state *state); + int backend_shr_postop_init(Slapi_PBlock *pb, struct plugin_state *state); +diff --git a/src/backend.h b/src/backend.h +index 7974aae..4608d2d 100644 +--- a/src/backend.h ++++ b/src/backend.h +@@ -58,6 +58,7 @@ struct backend_shr_set_data { + + /* Startup/initialization functions called through the map. */ + void backend_startup(struct slapi_pblock *pb, struct plugin_state *state); ++void backend_shutdown(struct plugin_state *state); + int backend_init_preop(struct slapi_pblock *pb, struct plugin_state *state); + int backend_init_betxn_preop(struct slapi_pblock *pb, + struct plugin_state *state); +diff --git a/src/plugin.h b/src/plugin.h +index 7a89ac7..56d672f 100644 +--- a/src/plugin.h ++++ b/src/plugin.h +@@ -34,6 +34,9 @@ struct plugin_state { + Slapi_PluginDesc *plugin_desc; + unsigned int use_be_txns: 1; + PRInt32 ready_to_serve; ++ struct wrapped_mutex *priming_mutex; ++ unsigned int start_priming_thread: 1; /* flag to allow spawning of the priming thread */ ++ struct wrapped_thread *priming_tid; /* priming thread pid. use to join */ + + /* NIS-specific data. */ + struct wrapped_thread *tid; +-- +2.7.4 + diff --git a/slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch b/slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch new file mode 100644 index 0000000..f3122b8 --- /dev/null +++ b/slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch @@ -0,0 +1,92 @@ +From 63212ccae673e46334b874688741bf96d996fd36 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Tue, 26 Apr 2016 13:17:03 +0300 +Subject: [PATCH 3/4] nis: add backend shutdown support to stop priming thread + +Resolves: rhbz#1327197 +--- + src/back-nis.c | 6 ++++++ + src/plug-nis.c | 34 +++++++++++++++++++++++++++------- + 2 files changed, 33 insertions(+), 7 deletions(-) + +diff --git a/src/back-nis.c b/src/back-nis.c +index b9379c0..7fb191d 100644 +--- a/src/back-nis.c ++++ b/src/back-nis.c +@@ -1021,6 +1021,12 @@ backend_startup(Slapi_PBlock *pb, struct plugin_state *state) + backend_shr_startup(state, pb, NIS_MAP_CONFIGURATION_FILTER); + } + ++void ++backend_shutdown(struct plugin_state *state) ++{ ++ backend_shr_shutdown(state); ++} ++ + /* Set up our post-op callbacks. */ + #ifdef SLAPI_NIS_SUPPORT_BE_TXNS + int +diff --git a/src/plug-nis.c b/src/plug-nis.c +index a1bdf89..ee90c37 100644 +--- a/src/plug-nis.c ++++ b/src/plug-nis.c +@@ -81,14 +81,31 @@ plugin_startup(Slapi_PBlock *pb) + struct plugin_state *state; + const char *pname; + int i, protocol; ++ Slapi_DN *pluginsdn = NULL; ++ + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); +- slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); +- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, +- "configuration entry is %s%s%s\n", +- state->plugin_base ? "\"" : "", +- state->plugin_base ? state->plugin_base : "NULL", +- state->plugin_base ? "\"" : ""); ++ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &pluginsdn); ++ /* plugin base need to be duplicated because it will be destroyed ++ * when pblock is destroyed but we need to use it in a separate thread */ ++ if (NULL == pluginsdn || 0 == slapi_sdn_get_ndn_len(pluginsdn)) { ++ slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, ++ "nis plugin_startup: unable to retrieve plugin DN\n"); ++ return -1; ++ ++ } else { ++ state->plugin_base = slapi_ch_strdup(slapi_sdn_get_dn(pluginsdn)); ++ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, ++ "configuration entry is %s%s%s\n", ++ state->plugin_base ? "\"" : "", ++ state->plugin_base ? state->plugin_base : "NULL", ++ state->plugin_base ? "\"" : ""); ++ } ++ + /* Populate the maps and data. */ ++ if (state->priming_mutex == NULL) { ++ state->priming_mutex = wrap_new_mutex(); ++ state->start_priming_thread = 1; ++ } + backend_startup(pb, state); + /* Start a new listening thread to handle incoming traffic. */ + state->tid = wrap_start_thread(&dispatch_thread, state); +@@ -177,6 +194,7 @@ plugin_shutdown(Slapi_PBlock *pb) + struct plugin_state *state; + int i, protocol; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); ++ backend_shutdown(state); + for (i = 0; i < state->n_listeners; i++) { + if (state->pmap_client_socket != -1) { + switch (state->listener[i].type) { +@@ -217,7 +235,9 @@ plugin_shutdown(Slapi_PBlock *pb) + #ifdef HAVE_TCPD_H + free(state->request_info); + #endif +- state->plugin_base = NULL; ++ if (state->plugin_base != NULL) { ++ slapi_ch_free((void **)&state->plugin_base); ++ } + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "plugin shutdown completed\n"); + return 0; +-- +2.7.4 + diff --git a/slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch b/slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch new file mode 100644 index 0000000..7772689 --- /dev/null +++ b/slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch @@ -0,0 +1,99 @@ +From 02e32192779994cab254c548291c24d89429b335 Mon Sep 17 00:00:00 2001 +From: Thierry Bordaz +Date: Tue, 26 Apr 2016 13:17:46 +0300 +Subject: [PATCH 4/4] schema-compat: add backend shutdown support for priming + thread + +Resolves: rhbz#1327197 +--- + src/back-sch.c | 6 ++++++ + src/plug-sch.c | 34 +++++++++++++++++++++++++++------- + 2 files changed, 33 insertions(+), 7 deletions(-) + +diff --git a/src/back-sch.c b/src/back-sch.c +index 9a0e96b..32b1d9e 100644 +--- a/src/back-sch.c ++++ b/src/back-sch.c +@@ -2280,6 +2280,12 @@ backend_startup(Slapi_PBlock *pb, struct plugin_state *state) + backend_shr_startup(state, pb, SCH_CONTAINER_CONFIGURATION_FILTER); + } + ++void ++backend_shutdown(struct plugin_state *state) ++{ ++ backend_shr_shutdown(state); ++} ++ + int + backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state) + { +diff --git a/src/plug-sch.c b/src/plug-sch.c +index 95a4fd8..7af8480 100644 +--- a/src/plug-sch.c ++++ b/src/plug-sch.c +@@ -102,13 +102,26 @@ plugin_startup(Slapi_PBlock *pb) + /* Populate the maps and data. */ + struct plugin_state *state; + Slapi_Entry *plugin_entry = NULL; ++ Slapi_DN *pluginsdn = NULL; ++ + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); +- slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); +- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, +- "configuration entry is %s%s%s\n", +- state->plugin_base ? "\"" : "", +- state->plugin_base ? state->plugin_base : "NULL", +- state->plugin_base ? "\"" : ""); ++ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &pluginsdn); ++ /* plugin base need to be duplicated because it will be destroyed ++ * when pblock is destroyed but we need to use it in a separate thread */ ++ if (NULL == pluginsdn || 0 == slapi_sdn_get_ndn_len(pluginsdn)) { ++ slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, ++ "scheman compat plugin_startup: unable to retrieve plugin DN\n"); ++ return -1; ++ ++ } else { ++ state->plugin_base = slapi_ch_strdup(slapi_sdn_get_dn(pluginsdn)); ++ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, ++ "configuration entry is %s%s%s\n", ++ state->plugin_base ? "\"" : "", ++ state->plugin_base ? state->plugin_base : "NULL", ++ state->plugin_base ? "\"" : ""); ++ } ++ + state->pam_lock = wrap_new_rwlock(); + backend_nss_init_context((struct nss_ops_ctx**) &state->nss_context); + if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) && +@@ -122,6 +135,10 @@ plugin_startup(Slapi_PBlock *pb) + state->cached_entries = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareValues, 0, 0); + wrap_rwlock_unlock(state->cached_entries_lock); + /* Populate the tree of fake entries. */ ++ if (state->priming_mutex == NULL) { ++ state->priming_mutex = wrap_new_mutex(); ++ state->start_priming_thread = 1; ++ } + backend_startup(pb, state); + /* Note that the plugin is ready to go. */ + slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, +@@ -147,6 +164,7 @@ plugin_shutdown(Slapi_PBlock *pb) + { + struct plugin_state *state; + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); ++ backend_shutdown(state); + map_done(state); + wrap_free_rwlock(state->pam_lock); + state->pam_lock = NULL; +@@ -160,7 +178,9 @@ plugin_shutdown(Slapi_PBlock *pb) + wrap_free_rwlock(state->cached_entries_lock); + state->cached_entries_lock = NULL; + } +- state->plugin_base = NULL; ++ if (state->plugin_base != NULL) { ++ slapi_ch_free((void **)&state->plugin_base); ++ } + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "plugin shutdown completed\n"); + return 0; +-- +2.7.4 + diff --git a/slapi-nis.spec b/slapi-nis.spec index ff78134..167eb29 100644 --- a/slapi-nis.spec +++ b/slapi-nis.spec @@ -18,6 +18,10 @@ License: GPLv2 URL: http://slapi-nis.fedorahosted.org/ Source0: https://fedorahosted.org/releases/s/l/slapi-nis/slapi-nis-%{version}.tar.gz Source1: https://fedorahosted.org/releases/s/l/slapi-nis/slapi-nis-%{version}.tar.gz.sig +Patch1: slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch +Patch2: slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch +Patch3: slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch +Patch4: slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: 389-ds-base-devel, %{ldap_impl}-devel BuildRequires: nspr-devel, nss-devel, /usr/bin/rpcgen @@ -55,6 +59,10 @@ for attributes from multiple entries in the tree. %prep %setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 %build %configure --disable-static --with-tcp-wrappers --with-ldap=%{ldap_impl} \ @@ -85,6 +93,9 @@ rm -rf $RPM_BUILD_ROOT %{_sbindir}/nisserver-plugin-defs %changelog +* Mon May 30 2016 Alexander Bokovoy - 0.55-3 +- Add support to properly shutdown priming cache from RHEL 7.2.4 + * Fri Feb 05 2016 Fedora Release Engineering - 0.55-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild