|
|
6b9042 |
From 2df48b57adb666112cab22e62750dd984fc7450a Mon Sep 17 00:00:00 2001
|
|
|
6b9042 |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
6b9042 |
Date: Wed, 23 Dec 2015 14:57:03 +0200
|
|
|
6b9042 |
Subject: [PATCH 05/12] slapi-nis: populate data trees asynchronously after
|
|
|
6b9042 |
LDAP server startup
|
|
|
6b9042 |
|
|
|
6b9042 |
Currently slapi-nis design assumes the map cache is populated by
|
|
|
6b9042 |
scanning the original trees on plugin start up. This has few
|
|
|
6b9042 |
consequences:
|
|
|
6b9042 |
- LDAP server cannot serve LDAP clients until all plugins are
|
|
|
6b9042 |
initialized
|
|
|
6b9042 |
|
|
|
6b9042 |
- slapi-nis cannot ask SSSD to resolve external identities at
|
|
|
6b9042 |
this point as SSSD will need to talk to the LDAP server which
|
|
|
6b9042 |
is at this point not listening for connections. SSSD will put
|
|
|
6b9042 |
whole IPA domain into offline and always will respond
|
|
|
6b9042 |
with negative result
|
|
|
6b9042 |
|
|
|
6b9042 |
To solve these issues, schedule tree scan after LDAP server startup.
|
|
|
6b9042 |
The problem here is that it is not possible to reliably detect when
|
|
|
6b9042 |
389-ds starts to listen to the incoming connections. However, it is
|
|
|
6b9042 |
possible to schedule an event into 389-ds event queue that will run
|
|
|
6b9042 |
shortly after start of the event loop. Given that the call back function
|
|
|
6b9042 |
which is registered to be called is called within the event loop thread,
|
|
|
6b9042 |
one can fire off another thread and wait in the thread function some
|
|
|
6b9042 |
time until the LDAP server is ready for connections.
|
|
|
6b9042 |
|
|
|
6b9042 |
The time interval is something that would depend on a specific
|
|
|
6b9042 |
deployment profile but experiments show that having 5 seconds delay
|
|
|
6b9042 |
should be enough as event queue is created just before starting the
|
|
|
6b9042 |
listeners.
|
|
|
6b9042 |
---
|
|
|
6b9042 |
src/back-shr.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++---------
|
|
|
6b9042 |
src/plug-sch.c | 4 +--
|
|
|
6b9042 |
2 files changed, 96 insertions(+), 18 deletions(-)
|
|
|
6b9042 |
|
|
|
6b9042 |
diff --git a/src/back-shr.c b/src/back-shr.c
|
|
|
6b9042 |
index c68640a..36ecc0b 100644
|
|
|
6b9042 |
--- a/src/back-shr.c
|
|
|
6b9042 |
+++ b/src/back-shr.c
|
|
|
6b9042 |
@@ -664,40 +664,56 @@ backend_shr_get_vattr_sdnlist(struct plugin_state *state,
|
|
|
6b9042 |
return ret;
|
|
|
6b9042 |
}
|
|
|
6b9042 |
|
|
|
6b9042 |
-/* Scan for the list of configured groups and sets. */
|
|
|
6b9042 |
-void
|
|
|
6b9042 |
-backend_shr_startup(struct plugin_state *state,
|
|
|
6b9042 |
- Slapi_PBlock *parent_pb,
|
|
|
6b9042 |
- const char *filter)
|
|
|
6b9042 |
+struct backend_shr_data_init_cbdata {
|
|
|
6b9042 |
+ Slapi_PBlock *parent_pb;
|
|
|
6b9042 |
+ struct plugin_state *state;
|
|
|
6b9042 |
+ const char *filter;
|
|
|
6b9042 |
+};
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+#define PLUGIN_SCAN_DELAY 5
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+static void
|
|
|
6b9042 |
+backend_shr_data_initialize_thread_cb(void *arg)
|
|
|
6b9042 |
{
|
|
|
6b9042 |
- Slapi_PBlock *pb;
|
|
|
6b9042 |
+ struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg;
|
|
|
6b9042 |
+ Slapi_PBlock *pb = NULL;
|
|
|
6b9042 |
struct backend_set_config_entry_add_cbdata set_cbdata;
|
|
|
6b9042 |
+ int result = 0;
|
|
|
6b9042 |
+ if (cbdata == NULL) {
|
|
|
6b9042 |
+ return;
|
|
|
6b9042 |
+ }
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ /* Scan may require consulting SSSD for external identities
|
|
|
6b9042 |
+ * therefore, we need to make sure the scan starts after ns-slapd
|
|
|
6b9042 |
+ * started to serve LDAP clients. There is no a signal for this,
|
|
|
6b9042 |
+ * so we just wait some time. */
|
|
|
6b9042 |
+ DS_Sleep(PR_SecondsToInterval(PLUGIN_SCAN_DELAY));
|
|
|
6b9042 |
|
|
|
6b9042 |
- backend_update_params(parent_pb, state);
|
|
|
6b9042 |
+ backend_update_params(cbdata->parent_pb, cbdata->state);
|
|
|
6b9042 |
|
|
|
6b9042 |
slapi_log_error(SLAPI_LOG_PLUGIN,
|
|
|
6b9042 |
- state->plugin_desc->spd_id,
|
|
|
6b9042 |
+ cbdata->state->plugin_desc->spd_id,
|
|
|
6b9042 |
"searching under \"%s\" for configuration\n",
|
|
|
6b9042 |
- state->plugin_base);
|
|
|
6b9042 |
- pb = wrap_pblock_new(parent_pb);
|
|
|
6b9042 |
+ cbdata->state->plugin_base);
|
|
|
6b9042 |
+ pb = wrap_pblock_new(cbdata->parent_pb);
|
|
|
6b9042 |
slapi_search_internal_set_pb(pb,
|
|
|
6b9042 |
- state->plugin_base,
|
|
|
6b9042 |
+ cbdata->state->plugin_base,
|
|
|
6b9042 |
LDAP_SCOPE_ONELEVEL,
|
|
|
6b9042 |
- filter,
|
|
|
6b9042 |
+ cbdata->filter,
|
|
|
6b9042 |
NULL, FALSE,
|
|
|
6b9042 |
NULL,
|
|
|
6b9042 |
NULL,
|
|
|
6b9042 |
- state->plugin_identity,
|
|
|
6b9042 |
+ cbdata->state->plugin_identity,
|
|
|
6b9042 |
0);
|
|
|
6b9042 |
if (map_wrlock() != 0) {
|
|
|
6b9042 |
slapi_log_error(SLAPI_LOG_PLUGIN,
|
|
|
6b9042 |
- state->plugin_desc->spd_id,
|
|
|
6b9042 |
+ cbdata->state->plugin_desc->spd_id,
|
|
|
6b9042 |
"failed to search under \"%s\" for "
|
|
|
6b9042 |
"configuration: failed to acquire a lock\n",
|
|
|
6b9042 |
- state->plugin_base);
|
|
|
6b9042 |
+ cbdata->state->plugin_base);
|
|
|
6b9042 |
goto done_with_lock;
|
|
|
6b9042 |
}
|
|
|
6b9042 |
- set_cbdata.state = state;
|
|
|
6b9042 |
+ set_cbdata.state = cbdata->state;
|
|
|
6b9042 |
set_cbdata.pb = pb;
|
|
|
6b9042 |
slapi_search_internal_callback_pb(pb, &set_cbdata,
|
|
|
6b9042 |
NULL,
|
|
|
6b9042 |
@@ -706,6 +722,68 @@ backend_shr_startup(struct plugin_state *state,
|
|
|
6b9042 |
map_unlock();
|
|
|
6b9042 |
done_with_lock:
|
|
|
6b9042 |
slapi_pblock_destroy(pb);
|
|
|
6b9042 |
+ if (cbdata) {
|
|
|
6b9042 |
+ slapi_ch_free((void**)&cbdata);
|
|
|
6b9042 |
+ }
|
|
|
6b9042 |
+}
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+static void
|
|
|
6b9042 |
+backend_shr_data_initialize_thread(time_t when, void *arg)
|
|
|
6b9042 |
+{
|
|
|
6b9042 |
+ struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg;
|
|
|
6b9042 |
+ PRThread *thread = NULL;
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ /* start data import as a separate thread */
|
|
|
6b9042 |
+ thread = PR_CreateThread(PR_USER_THREAD, backend_shr_data_initialize_thread_cb,
|
|
|
6b9042 |
+ (void *)arg, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
|
|
|
6b9042 |
+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
|
|
|
6b9042 |
+ if (thread == NULL) {
|
|
|
6b9042 |
+ slapi_log_error(SLAPI_LOG_FATAL,
|
|
|
6b9042 |
+ cbdata->state->plugin_desc->spd_id,
|
|
|
6b9042 |
+ "unable to create compatibility tree scan thread!\n");
|
|
|
6b9042 |
+ } else {
|
|
|
6b9042 |
+ slapi_log_error(SLAPI_LOG_FATAL,
|
|
|
6b9042 |
+ cbdata->state->plugin_desc->spd_id,
|
|
|
6b9042 |
+ "%s tree scan will start in about %d seconds!\n",
|
|
|
6b9042 |
+ cbdata->state->plugin_desc->spd_id, PLUGIN_SCAN_DELAY);
|
|
|
6b9042 |
+ }
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+}
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+/* Scan for the list of configured groups and sets. */
|
|
|
6b9042 |
+void
|
|
|
6b9042 |
+backend_shr_startup(struct plugin_state *state,
|
|
|
6b9042 |
+ Slapi_PBlock *parent_pb,
|
|
|
6b9042 |
+ const char *filter)
|
|
|
6b9042 |
+{
|
|
|
6b9042 |
+ struct backend_shr_data_init_cbdata *cbdata = NULL;
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ cbdata = (struct backend_shr_data_init_cbdata *)
|
|
|
6b9042 |
+ slapi_ch_malloc(sizeof(struct backend_shr_data_init_cbdata));
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ if (cbdata == NULL) {
|
|
|
6b9042 |
+ slapi_log_error(SLAPI_LOG_FATAL,
|
|
|
6b9042 |
+ state->plugin_desc->spd_id,
|
|
|
6b9042 |
+ "failed to create a task for populating "
|
|
|
6b9042 |
+ "compatibility tree\n");
|
|
|
6b9042 |
+ return;
|
|
|
6b9042 |
+ }
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ cbdata->state = state;
|
|
|
6b9042 |
+ cbdata->parent_pb = parent_pb;
|
|
|
6b9042 |
+ cbdata->filter = filter;
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ /* Schedule running a callback that will create a thread */
|
|
|
6b9042 |
+ slapi_eq_once(backend_shr_data_initialize_thread,
|
|
|
6b9042 |
+ cbdata, PR_SecondsToInterval(PLUGIN_SCAN_DELAY));
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ slapi_log_error(SLAPI_LOG_FATAL,
|
|
|
6b9042 |
+ cbdata->state->plugin_desc->spd_id,
|
|
|
6b9042 |
+ "scheduled %s tree scan in about %d seconds after the server startup!\n",
|
|
|
6b9042 |
+ state->plugin_desc->spd_id, PLUGIN_SCAN_DELAY);
|
|
|
6b9042 |
+
|
|
|
6b9042 |
+ return;
|
|
|
6b9042 |
+
|
|
|
6b9042 |
}
|
|
|
6b9042 |
|
|
|
6b9042 |
/* Process a set configuration directory entry. Pull out the group and set
|
|
|
6b9042 |
diff --git a/src/plug-sch.c b/src/plug-sch.c
|
|
|
6b9042 |
index f132e6d..95a4fd8 100644
|
|
|
6b9042 |
--- a/src/plug-sch.c
|
|
|
6b9042 |
+++ b/src/plug-sch.c
|
|
|
6b9042 |
@@ -109,8 +109,6 @@ plugin_startup(Slapi_PBlock *pb)
|
|
|
6b9042 |
state->plugin_base ? "\"" : "",
|
|
|
6b9042 |
state->plugin_base ? state->plugin_base : "NULL",
|
|
|
6b9042 |
state->plugin_base ? "\"" : "");
|
|
|
6b9042 |
- /* Populate the tree of fake entries. */
|
|
|
6b9042 |
- backend_startup(pb, state);
|
|
|
6b9042 |
state->pam_lock = wrap_new_rwlock();
|
|
|
6b9042 |
backend_nss_init_context((struct nss_ops_ctx**) &state->nss_context);
|
|
|
6b9042 |
if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
|
|
|
6b9042 |
@@ -123,6 +121,8 @@ plugin_startup(Slapi_PBlock *pb)
|
|
|
6b9042 |
wrap_rwlock_wrlock(state->cached_entries_lock);
|
|
|
6b9042 |
state->cached_entries = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareValues, 0, 0);
|
|
|
6b9042 |
wrap_rwlock_unlock(state->cached_entries_lock);
|
|
|
6b9042 |
+ /* Populate the tree of fake entries. */
|
|
|
6b9042 |
+ backend_startup(pb, state);
|
|
|
6b9042 |
/* Note that the plugin is ready to go. */
|
|
|
6b9042 |
slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id,
|
|
|
6b9042 |
"plugin startup completed\n");
|
|
|
6b9042 |
--
|
|
|
6b9042 |
2.5.0
|
|
|
6b9042 |
|