|
|
55ff7e |
From 8b10ea485f7964ea53fb9ab1bd71105a2da96f84 Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
Date: Wed, 13 Sep 2017 12:39:08 +0200
|
|
|
55ff7e |
Subject: [PATCH 01/13] Bug 1435663: deadlock between write and search
|
|
|
55ff7e |
operation in schema-compat plugin
|
|
|
55ff7e |
|
|
|
55ff7e |
Problem description:
|
|
|
55ff7e |
Schema compat is a betxn pre/post op plugin managing maps.
|
|
|
55ff7e |
The maps are protected by a RW lock.
|
|
|
55ff7e |
A typical deadlock scenario is when a read thread (SRCH) holding
|
|
|
55ff7e |
the map lock needs a ressource (DB page) acquired by an
|
|
|
55ff7e |
write thread (MOD/ADD/DEL..) and that write thread needs to update
|
|
|
55ff7e |
the map and so acquire the map lock.
|
|
|
55ff7e |
|
|
|
55ff7e |
So far we have been able to reduce the frequency of those scenarios
|
|
|
55ff7e |
(but not eliminate them) by restricting the scope of operations
|
|
|
55ff7e |
that need to acquire the lock.
|
|
|
55ff7e |
|
|
|
55ff7e |
But scoping is not systematically possible like described in
|
|
|
55ff7e |
https://bugzilla.redhat.com/show_bug.cgi?id=1435663#c16
|
|
|
55ff7e |
|
|
|
55ff7e |
Fix description:
|
|
|
55ff7e |
The fix implements a plugin RW reentrant lock 'plugin_lock'.
|
|
|
55ff7e |
To do this it uses a thread private variables (thread_plugin_lock_status and
|
|
|
55ff7e |
thread_plugin_lock_count to remember the current status of the lock
|
|
|
55ff7e |
(free, read_acquired, write_acquired).
|
|
|
55ff7e |
|
|
|
55ff7e |
Then for write operations (even if it is out of the scope of SC), the lock is acquired in write
|
|
|
55ff7e |
in the BE_preop operation (note not in BETXN_preop) and only released
|
|
|
55ff7e |
in the BE_postop (postop/bepostop).
|
|
|
55ff7e |
So a write operation acquires (exclusive) the maps lock before acquiring DB pages.
|
|
|
55ff7e |
So read and write operation will acquire locks in the same order.
|
|
|
55ff7e |
|
|
|
55ff7e |
Design is https://www.freeipa.org/page/V4_slapi_nis_locking
|
|
|
55ff7e |
|
|
|
55ff7e |
Signed-off-by: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/back-sch.c | 221 ++++++++++++++++++++++++++++++++++++++++
|
|
|
55ff7e |
src/back-shr.c | 94 +++++++++++++++++
|
|
|
55ff7e |
src/back-shr.h | 16 +++
|
|
|
55ff7e |
src/map.c | 271 +++++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
55ff7e |
src/map.h | 3 +
|
|
|
55ff7e |
src/plug-sch.c | 52 ++++++++++
|
|
|
55ff7e |
6 files changed, 651 insertions(+), 6 deletions(-)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
55ff7e |
index 4612051..9313cd5 100644
|
|
|
55ff7e |
--- a/src/back-sch.c
|
|
|
55ff7e |
+++ b/src/back-sch.c
|
|
|
55ff7e |
@@ -2304,6 +2304,157 @@ backend_betxn_pre_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
return state->use_be_txns ? backend_write_cb(pb, state) : 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
+static int
|
|
|
55ff7e |
+backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
+ int ret;
|
|
|
55ff7e |
+ int lock_status;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
+ struct plugin_state *state;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (wrap_get_call_level() > 0) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (state->ready_to_serve == 0) {
|
|
|
55ff7e |
+ /* No data to serve yet */
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ wrap_inc_call_level();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_FREE) {
|
|
|
55ff7e |
+ set_plugin_monitor_count(1);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (plugin_wrlock() == 0) {
|
|
|
55ff7e |
+ ret = 0;
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: unable to acquire write lock\n");
|
|
|
55ff7e |
+ ret = -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: (%p) MAP_RWLOCK_FREE -> MAP_WLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD": "MAP_RLOCK_HELD",
|
|
|
55ff7e |
+ lock_count + 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ ret = 0;
|
|
|
55ff7e |
+ if (lock_status == MAP_RLOCK_HELD) {
|
|
|
55ff7e |
+ /* lock is already acquired in read */
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map backend_be_pre_write_cb: weird situation map lock is held in read and now required in write mode\n");
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ /* First free the lock held in read */
|
|
|
55ff7e |
+ ret = plugin_unlock();
|
|
|
55ff7e |
+ if (ret) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: fail to unlock plugin lock (%d)\n", ret);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ /* Second acquire it in write */
|
|
|
55ff7e |
+ ret = plugin_wrlock();
|
|
|
55ff7e |
+ if (ret) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: fail to write lock plugin lock (%d)\n", ret);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_WLOCK_HELD);
|
|
|
55ff7e |
+ wrap_dec_call_level();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ return ret;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+static int
|
|
|
55ff7e |
+backend_be_post_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int ret;
|
|
|
55ff7e |
+ int lock_status;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
+ struct plugin_state *state;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (wrap_get_call_level() > 0) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (state->ready_to_serve == 0) {
|
|
|
55ff7e |
+ /* No data to serve yet */
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ wrap_inc_call_level();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (lock_count == 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_RWLOCK_FREE);
|
|
|
55ff7e |
+ if (plugin_unlock() == 0) {
|
|
|
55ff7e |
+ ret = 0;
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "backend_be_post_write_cb: unable to release write lock\n");
|
|
|
55ff7e |
+ ret = -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ 0);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (lock_count >= 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count - 1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ if (lock_count > 1) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ wrap_dec_call_level();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ return ret;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
#ifdef USE_PAM
|
|
|
55ff7e |
static int
|
|
|
55ff7e |
backend_bind_cb_pam(Slapi_PBlock *pb, const char *username, char *ndn)
|
|
|
55ff7e |
@@ -2814,6 +2965,42 @@ backend_init_betxn_preop(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+backend_init_be_preop(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "hooking up bet preoperation callbacks\n");
|
|
|
55ff7e |
+ /* Intercept write requests and return an insufficient-access error for
|
|
|
55ff7e |
+ * attempts to write to anything we're managing. */
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN,
|
|
|
55ff7e |
+ backend_be_pre_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn pre add callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_MODIFY_FN,
|
|
|
55ff7e |
+ backend_be_pre_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn pre modify callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_MODRDN_FN,
|
|
|
55ff7e |
+ backend_be_pre_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn pre modrdn callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN,
|
|
|
55ff7e |
+ backend_be_pre_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn pre delete callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ /* We don't hook abandonment requests. */
|
|
|
55ff7e |
+ /* We don't hook unbind requests. */
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
int
|
|
|
55ff7e |
backend_init_betxn_postop(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
@@ -2821,6 +3008,40 @@ backend_init_betxn_postop(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
"hooking up betxn postoperation callbacks\n");
|
|
|
55ff7e |
return backend_shr_betxn_postop_init(pb, state);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+backend_init_be_postop(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_ADD_FN,
|
|
|
55ff7e |
+ backend_be_post_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn post add callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_MODIFY_FN,
|
|
|
55ff7e |
+ backend_be_post_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn post modify "
|
|
|
55ff7e |
+ "callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_MODRDN_FN,
|
|
|
55ff7e |
+ backend_be_post_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn post modrdn "
|
|
|
55ff7e |
+ "callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_DELETE_FN,
|
|
|
55ff7e |
+ backend_be_post_write_cb) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error hooking up betxn post delete "
|
|
|
55ff7e |
+ "callback\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
diff --git a/src/back-shr.c b/src/back-shr.c
|
|
|
55ff7e |
index a7ea92f..a227b0a 100644
|
|
|
55ff7e |
--- a/src/back-shr.c
|
|
|
55ff7e |
+++ b/src/back-shr.c
|
|
|
55ff7e |
@@ -2866,3 +2866,97 @@ backend_shr_internal_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+static unsigned int thread_dummy;
|
|
|
55ff7e |
+static unsigned int thread_plugin_lock_status;
|
|
|
55ff7e |
+static int thread_plugin_lock_count;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+void
|
|
|
55ff7e |
+init_map_lock(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ /* The plugin lock is initialized as free */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "init_plugin_lock",
|
|
|
55ff7e |
+ "thread_id = %p\n", PR_GetCurrentThread());
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ PR_NewThreadPrivateIndex (&thread_dummy, NULL);
|
|
|
55ff7e |
+ PR_NewThreadPrivateIndex(&thread_plugin_lock_status, NULL);
|
|
|
55ff7e |
+ PR_NewThreadPrivateIndex(&thread_plugin_lock_count, NULL);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "init_plugin_lock",
|
|
|
55ff7e |
+ "thread_plugin_lock_status = %d\n", thread_plugin_lock_status);
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "init_map_lock",
|
|
|
55ff7e |
+ "thread_plugin_lock_count = %d\n", thread_plugin_lock_count);
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+rw_monitor_enabled(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ if (thread_plugin_lock_status)
|
|
|
55ff7e |
+ return (int) MAP_MONITOR_ENABLED;
|
|
|
55ff7e |
+ else
|
|
|
55ff7e |
+ return (int) MAP_MONITOR_DISABLED;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+get_plugin_monitor_status(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int ret;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (thread_plugin_lock_status)
|
|
|
55ff7e |
+ ret = (int) PR_GetThreadPrivate(thread_plugin_lock_status);
|
|
|
55ff7e |
+ else
|
|
|
55ff7e |
+ ret = (int) MAP_RWLOCK_UNINIT;
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "get_plugin_monitor_status",
|
|
|
55ff7e |
+ "lock_status = %d (%p)\n", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ return ret;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+void
|
|
|
55ff7e |
+set_plugin_monitor_status(int lock_status)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "set_plugin_monitor_status",
|
|
|
55ff7e |
+ "lock_status = %d --> %d (%p)\n", get_plugin_monitor_status(), (int) lock_status, PR_GetCurrentThread());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (thread_plugin_lock_status)
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_status, (void *) lock_status);
|
|
|
55ff7e |
+ else
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_status, (void *) MAP_RWLOCK_UNINIT);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+get_plugin_monitor_count(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int ret;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (thread_plugin_lock_count)
|
|
|
55ff7e |
+ ret = (int) PR_GetThreadPrivate(thread_plugin_lock_count);
|
|
|
55ff7e |
+ else
|
|
|
55ff7e |
+ ret = (int) MAP_RWLOCK_UNINIT;
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "get_plugin_monitor_count",
|
|
|
55ff7e |
+ "lock_count = %d (%p)\n", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ return ret;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+void
|
|
|
55ff7e |
+set_plugin_monitor_count(int lock_count)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "set_plugin_monitor_count",
|
|
|
55ff7e |
+ "lock_count = %d --> %d (%p)\n", get_plugin_monitor_count(), (int) lock_count, PR_GetCurrentThread());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (thread_plugin_lock_count)
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_count, (void *) lock_count);
|
|
|
55ff7e |
+ else
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_count, (void *) MAP_RWLOCK_UNINIT);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
diff --git a/src/back-shr.h b/src/back-shr.h
|
|
|
55ff7e |
index 2caea5d..8c68b4f 100644
|
|
|
55ff7e |
--- a/src/back-shr.h
|
|
|
55ff7e |
+++ b/src/back-shr.h
|
|
|
55ff7e |
@@ -22,6 +22,22 @@
|
|
|
55ff7e |
#ifndef back_shr_h
|
|
|
55ff7e |
#define back_shr_h
|
|
|
55ff7e |
|
|
|
55ff7e |
+#define DEBUG_MAP_LOCK 0
|
|
|
55ff7e |
+#define MAP_MONITOR_DISABLED 0
|
|
|
55ff7e |
+#define MAP_MONITOR_ENABLED 1
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+#define MAP_RWLOCK_UNINIT 3
|
|
|
55ff7e |
+#define MAP_WLOCK_HELD 2
|
|
|
55ff7e |
+#define MAP_RLOCK_HELD 1
|
|
|
55ff7e |
+#define MAP_RWLOCK_FREE 0
|
|
|
55ff7e |
+int rw_monitor_enabled(void);
|
|
|
55ff7e |
+int get_plugin_monitor_status(void);
|
|
|
55ff7e |
+void set_plugin_monitor_status(int lock_status);
|
|
|
55ff7e |
+int get_plugin_monitor_count(void);
|
|
|
55ff7e |
+void set_plugin_monitor_count(int lock_count);
|
|
|
55ff7e |
+void init_map_lock(void);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
struct plugin_state;
|
|
|
55ff7e |
|
|
|
55ff7e |
void backend_shr_free_server_name(struct plugin_state *state, char *master);
|
|
|
55ff7e |
diff --git a/src/map.c b/src/map.c
|
|
|
55ff7e |
index ff18fcf..db9e093 100644
|
|
|
55ff7e |
--- a/src/map.c
|
|
|
55ff7e |
+++ b/src/map.c
|
|
|
55ff7e |
@@ -45,6 +45,7 @@
|
|
|
55ff7e |
#include "map.h"
|
|
|
55ff7e |
#include "portmap.h"
|
|
|
55ff7e |
#include "wrap.h"
|
|
|
55ff7e |
+#include "back-shr.h"
|
|
|
55ff7e |
|
|
|
55ff7e |
/* The singleton for the cache. */
|
|
|
55ff7e |
static struct {
|
|
|
55ff7e |
@@ -91,6 +92,7 @@ static struct {
|
|
|
55ff7e |
} *domains;
|
|
|
55ff7e |
int n_domains;
|
|
|
55ff7e |
struct wrapped_rwlock *lock;
|
|
|
55ff7e |
+ struct wrapped_rwlock *plugin_lock;
|
|
|
55ff7e |
} map_data;
|
|
|
55ff7e |
|
|
|
55ff7e |
static void *
|
|
|
55ff7e |
@@ -1155,6 +1157,10 @@ map_init(struct slapi_pblock *pb, struct plugin_state *state)
|
|
|
55ff7e |
if (map_data.lock == NULL) {
|
|
|
55ff7e |
return -1;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+ map_data.plugin_lock = wrap_new_rwlock();
|
|
|
55ff7e |
+ if (map_data.plugin_lock == NULL) {
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
@@ -1193,6 +1199,8 @@ map_done(struct plugin_state *state)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
wrap_free_rwlock(map_data.lock);
|
|
|
55ff7e |
map_data.lock = NULL;
|
|
|
55ff7e |
+ wrap_free_rwlock(map_data.plugin_lock);
|
|
|
55ff7e |
+ map_data.plugin_lock = NULL;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
@@ -1219,19 +1227,270 @@ map_data_get_map_size(struct plugin_state *state,
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
-map_rdlock(void)
|
|
|
55ff7e |
+plugin_rdlock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
- return wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
+ return wrap_rwlock_rdlock(map_data.plugin_lock);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
-map_wrlock(void)
|
|
|
55ff7e |
+plugin_wrlock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
- return wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
+ return wrap_rwlock_wrlock(map_data.plugin_lock);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
-map_unlock(void)
|
|
|
55ff7e |
+plugin_unlock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
- return wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
+ return wrap_rwlock_unlock(map_data.plugin_lock);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+map_rdlock(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int lock_status;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
+ int rc = 0;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
+ /* This is not initialized used the old way */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: old way MAP_MONITOR_DISABLED\n");
|
|
|
55ff7e |
+ return wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "map_rdlock",
|
|
|
55ff7e |
+ "thread_id = %p (call level = %d)\n", PR_GetCurrentThread(), wrap_get_call_level());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
+ /* This is not initialized used the old way */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: old way lock_status == MAP_RWLOCK_UNINIT\n");
|
|
|
55ff7e |
+ return wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_FREE) {
|
|
|
55ff7e |
+ /* The plugin lock is free, acquire it */
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: current lock_status == MAP_RWLOCK_FREE\n");
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_RLOCK_HELD);
|
|
|
55ff7e |
+ set_plugin_monitor_count(1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ if (lock_count != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) ALERT !!! count was %d -> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ /* Acquire the slapi plugin in read */
|
|
|
55ff7e |
+ rc = plugin_rdlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ rc = wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "Fail to acquire map lock in read (%d)\n", rc);
|
|
|
55ff7e |
+ plugin_unlock();
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) was already hold %s : count=%d > %d!!!\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD": "MAP_RLOCK_HELD",
|
|
|
55ff7e |
+ lock_count, lock_count + 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+map_wrlock(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int lock_status;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
+ int rc = 0;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
+ /* This is not initialized used the old way */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: old way MAP_MONITOR_DISABLED\n");
|
|
|
55ff7e |
+ return wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "map wrlock",
|
|
|
55ff7e |
+ "thread_id = %p (call level = %d)\n", PR_GetCurrentThread(), wrap_get_call_level());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
+ /* This is not initialized used the old way */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: old way lock_status == MAP_LOCK_UNINIT\n");
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ return wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_FREE) {
|
|
|
55ff7e |
+ /* The lock is free, acquire it */
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: current lock_status == MAP_LOCK_FREE\n");
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ set_plugin_monitor_count(1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ if (lock_count != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) ALERT !!! count was %d --> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ /* Acquire the slapi plugin in write */
|
|
|
55ff7e |
+ rc = plugin_wrlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ rc = wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ plugin_unlock();
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD": "MAP_RLOCK_HELD",
|
|
|
55ff7e |
+ lock_count + 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (lock_status == MAP_RLOCK_HELD) {
|
|
|
55ff7e |
+ /* lock is already acquired in read */
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: weird situation map lock is held in read and now required in write mode\n");
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ /* First free the lock held in read */
|
|
|
55ff7e |
+ rc = plugin_unlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: fail to unlock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ /* Second acquire it in write */
|
|
|
55ff7e |
+ rc = plugin_wrlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: fail to write lock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+common:
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_WLOCK_HELD);
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
+map_unlock(void)
|
|
|
55ff7e |
+ {
|
|
|
55ff7e |
+ int lock_status;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
+ int rc = 0;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
+ /* This is not initialized used the old way */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: old way MAP_MONITOR_DISABLED\n");
|
|
|
55ff7e |
+ return wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "map_unlock",
|
|
|
55ff7e |
+ "thread_id = %p (call level = %d)\n", PR_GetCurrentThread(), wrap_get_call_level());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
+ /* This is not initialized used the old way */
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: old way lock_status == MAP_RWLOCK_UNINIT\n");
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ return wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ if (lock_count == 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_RWLOCK_FREE);
|
|
|
55ff7e |
+ rc = plugin_unlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map unlock: fail to unlock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ 0);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ rc = wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: fail to unlock map lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (lock_count >= 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count - 1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ if (lock_count > 1) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+common:
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
diff --git a/src/map.h b/src/map.h
|
|
|
55ff7e |
index f5b0405..4d7cb8c 100644
|
|
|
55ff7e |
--- a/src/map.h
|
|
|
55ff7e |
+++ b/src/map.h
|
|
|
55ff7e |
@@ -115,6 +115,9 @@ int map_data_get_domain_size(struct plugin_state *state,
|
|
|
55ff7e |
const char *domain_name);
|
|
|
55ff7e |
int map_data_get_map_size(struct plugin_state *state,
|
|
|
55ff7e |
const char *domain_name, const char *map_name);
|
|
|
55ff7e |
+int plugin_rdlock(void);
|
|
|
55ff7e |
+int plugin_wrlock(void);
|
|
|
55ff7e |
+int plugin_unlock(void);
|
|
|
55ff7e |
int map_rdlock(void);
|
|
|
55ff7e |
int map_wrlock(void);
|
|
|
55ff7e |
int map_unlock(void);
|
|
|
55ff7e |
diff --git a/src/plug-sch.c b/src/plug-sch.c
|
|
|
55ff7e |
index 0c20a07..2d9c75b 100644
|
|
|
55ff7e |
--- a/src/plug-sch.c
|
|
|
55ff7e |
+++ b/src/plug-sch.c
|
|
|
55ff7e |
@@ -62,6 +62,8 @@
|
|
|
55ff7e |
#define PLUGIN_ID "schema-compat-plugin"
|
|
|
55ff7e |
#define PLUGIN_PREOP_ID PLUGIN_ID "-preop"
|
|
|
55ff7e |
#define PLUGIN_BETXN_PREOP_ID PLUGIN_ID "-betxn_preop"
|
|
|
55ff7e |
+#define PLUGIN_BE_POSTOP_ID PLUGIN_ID "-be_postop"
|
|
|
55ff7e |
+#define PLUGIN_BE_PREOP_ID PLUGIN_ID "-be_preop"
|
|
|
55ff7e |
#define PLUGIN_BETXN_POSTOP_ID PLUGIN_ID "-betxn_postop"
|
|
|
55ff7e |
#define PLUGIN_POSTOP_ID PLUGIN_ID "-postop"
|
|
|
55ff7e |
#define PLUGIN_INTERNAL_POSTOP_ID PLUGIN_ID "-internal-postop"
|
|
|
55ff7e |
@@ -258,6 +260,35 @@ schema_compat_plugin_init_betxn_postop(Slapi_PBlock *pb)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+static int
|
|
|
55ff7e |
+schema_compat_plugin_init_bepreop(Slapi_PBlock *pb)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
|
|
|
55ff7e |
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &plugin_description);
|
|
|
55ff7e |
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, global_plugin_state);
|
|
|
55ff7e |
+ if (backend_init_be_preop(pb, global_plugin_state) == -1) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN,
|
|
|
55ff7e |
+ global_plugin_state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error registering be preoperation hooks\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+static int
|
|
|
55ff7e |
+schema_compat_plugin_init_bepostop(Slapi_PBlock *pb)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
|
|
|
55ff7e |
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &plugin_description);
|
|
|
55ff7e |
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, global_plugin_state);
|
|
|
55ff7e |
+ if (backend_init_be_postop(pb, global_plugin_state) == -1) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN,
|
|
|
55ff7e |
+ global_plugin_state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error registering be postoperation "
|
|
|
55ff7e |
+ "hooks\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
static int
|
|
|
55ff7e |
schema_compat_plugin_init_postop(Slapi_PBlock *pb)
|
|
|
55ff7e |
@@ -300,6 +331,9 @@ schema_compat_plugin_init(Slapi_PBlock *pb)
|
|
|
55ff7e |
"error setting up plugin\n");
|
|
|
55ff7e |
return -1;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ init_map_lock();
|
|
|
55ff7e |
+
|
|
|
55ff7e |
/* Read global configuration. */
|
|
|
55ff7e |
if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY,
|
|
|
55ff7e |
&plugin_entry) == 0) &&
|
|
|
55ff7e |
@@ -341,6 +375,15 @@ schema_compat_plugin_init(Slapi_PBlock *pb)
|
|
|
55ff7e |
"error registering betxn preoperation plugin\n");
|
|
|
55ff7e |
return -1;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+ if (slapi_register_plugin("bepreoperation", TRUE,
|
|
|
55ff7e |
+ "schema_compat_plugin_init_bepreop",
|
|
|
55ff7e |
+ schema_compat_plugin_init_bepreop,
|
|
|
55ff7e |
+ PLUGIN_BE_PREOP_ID, NULL,
|
|
|
55ff7e |
+ state->plugin_identity) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error registering betxn preoperation plugin\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (slapi_register_plugin("postoperation", TRUE,
|
|
|
55ff7e |
"schema_compat_plugin_init_postop",
|
|
|
55ff7e |
@@ -370,6 +413,15 @@ schema_compat_plugin_init(Slapi_PBlock *pb)
|
|
|
55ff7e |
"error registering betxn postoperation plugin\n");
|
|
|
55ff7e |
return -1;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+ if (slapi_register_plugin("bepostoperation", TRUE,
|
|
|
55ff7e |
+ "schema_compat_plugin_init_bepostop",
|
|
|
55ff7e |
+ schema_compat_plugin_init_bepostop,
|
|
|
55ff7e |
+ PLUGIN_BE_POSTOP_ID, NULL,
|
|
|
55ff7e |
+ state->plugin_identity) != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "error registering betxn postoperation plugin\n");
|
|
|
55ff7e |
+ return -1;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (slapi_register_plugin("preextendedop", TRUE,
|
|
|
55ff7e |
"schema_compat_plugin_init_extop",
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From 1ccbfe23576ac78f81d85bcce246e4d72cfc4db8 Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
Date: Wed, 3 Apr 2019 10:55:38 +0200
|
|
|
55ff7e |
Subject: [PATCH 07/13] Bug 1694263: Fix thread private variable initialization
|
|
|
55ff7e |
|
|
|
55ff7e |
Fix description:
|
|
|
55ff7e |
The initialization of the thread private variable was buggy.
|
|
|
55ff7e |
The private variable required an allocated struct (per thread).
|
|
|
55ff7e |
The struct is allocated on demand (during get/set) when the
|
|
|
55ff7e |
retrieved (PR_GetThreadPrivate) struct is NULL.
|
|
|
55ff7e |
|
|
|
55ff7e |
Signed-off-by: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/back-sch.c | 85 ++++++++---------
|
|
|
55ff7e |
src/back-shr.c | 138 ++++++++++++++++++++++------
|
|
|
55ff7e |
src/map.c | 244 ++++++++++++++++++++++++-------------------------
|
|
|
55ff7e |
3 files changed, 274 insertions(+), 193 deletions(-)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
55ff7e |
index 9313cd5..2d0bad0 100644
|
|
|
55ff7e |
--- a/src/back-sch.c
|
|
|
55ff7e |
+++ b/src/back-sch.c
|
|
|
55ff7e |
@@ -2306,7 +2306,7 @@ backend_betxn_pre_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
|
|
|
55ff7e |
static int
|
|
|
55ff7e |
backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
- int ret;
|
|
|
55ff7e |
+ int ret = 0;
|
|
|
55ff7e |
int lock_status;
|
|
|
55ff7e |
int lock_count;
|
|
|
55ff7e |
struct plugin_state *state;
|
|
|
55ff7e |
@@ -2334,6 +2334,7 @@ backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
if (lock_status == MAP_RWLOCK_FREE) {
|
|
|
55ff7e |
+ /* This thread does not hold the map lock */
|
|
|
55ff7e |
set_plugin_monitor_count(1);
|
|
|
55ff7e |
|
|
|
55ff7e |
if (plugin_wrlock() == 0) {
|
|
|
55ff7e |
@@ -2389,12 +2390,12 @@ backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
static int
|
|
|
55ff7e |
backend_be_post_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
- int ret;
|
|
|
55ff7e |
- int lock_status;
|
|
|
55ff7e |
- int lock_count;
|
|
|
55ff7e |
- struct plugin_state *state;
|
|
|
55ff7e |
+ int ret = 0;
|
|
|
55ff7e |
+ int lock_status;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
+ struct plugin_state *state;
|
|
|
55ff7e |
|
|
|
55ff7e |
- slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
|
|
|
55ff7e |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
|
|
|
55ff7e |
|
|
|
55ff7e |
if (wrap_get_call_level() > 0) {
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
@@ -2409,47 +2410,47 @@ backend_be_post_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
|
|
|
55ff7e |
wrap_inc_call_level();
|
|
|
55ff7e |
|
|
|
55ff7e |
- lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
- lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
- if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
- return 0;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (lock_count == 1) {
|
|
|
55ff7e |
- set_plugin_monitor_status(MAP_RWLOCK_FREE);
|
|
|
55ff7e |
- if (plugin_unlock() == 0) {
|
|
|
55ff7e |
- ret = 0;
|
|
|
55ff7e |
- } else {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
- "backend_be_post_write_cb: unable to release write lock\n");
|
|
|
55ff7e |
- ret = -1;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
-#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "backend_be_post_write_cb: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
- 0);
|
|
|
55ff7e |
-#endif
|
|
|
55ff7e |
+ if (lock_count == 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_RWLOCK_FREE);
|
|
|
55ff7e |
+ if (plugin_unlock() == 0) {
|
|
|
55ff7e |
+ ret = 0;
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
+ "backend_be_post_write_cb: unable to release write lock\n");
|
|
|
55ff7e |
+ ret = -1;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
- if (lock_count >= 1) {
|
|
|
55ff7e |
- set_plugin_monitor_count(lock_count - 1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- if (lock_count > 1) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "backend_be_post_write_cb: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
- lock_count - 1);
|
|
|
55ff7e |
- } else {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "backend_be_post_write_cb: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
- lock_count - 1);
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ 0);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (lock_count >= 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count - 1);
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ if (lock_count > 1) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
wrap_dec_call_level();
|
|
|
55ff7e |
|
|
|
55ff7e |
return ret;
|
|
|
55ff7e |
diff --git a/src/back-shr.c b/src/back-shr.c
|
|
|
55ff7e |
index a227b0a..920c135 100644
|
|
|
55ff7e |
--- a/src/back-shr.c
|
|
|
55ff7e |
+++ b/src/back-shr.c
|
|
|
55ff7e |
@@ -37,6 +37,7 @@
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
#include <rpc/xdr.h>
|
|
|
55ff7e |
+#include <nspr4/prtypes.h>
|
|
|
55ff7e |
#include "../yp/yp.h"
|
|
|
55ff7e |
|
|
|
55ff7e |
#ifdef HAVE_TCPD_H
|
|
|
55ff7e |
@@ -2867,31 +2868,61 @@ backend_shr_internal_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
-static unsigned int thread_dummy;
|
|
|
55ff7e |
+PRBool use_lock_status = PR_FALSE;
|
|
|
55ff7e |
static unsigned int thread_plugin_lock_status;
|
|
|
55ff7e |
-static int thread_plugin_lock_count;
|
|
|
55ff7e |
+PRBool use_lock_count = PR_FALSE;
|
|
|
55ff7e |
+static unsigned int thread_plugin_lock_count;
|
|
|
55ff7e |
+/*
|
|
|
55ff7e |
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR/Reference/PR_NewThreadPrivateIndex
|
|
|
55ff7e |
+ * It is called each time:
|
|
|
55ff7e |
+ * - PR_SetThreadPrivate is call with a not NULL private value
|
|
|
55ff7e |
+ * - on thread exit
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+static void
|
|
|
55ff7e |
+lock_status_free(void *ptr)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int *lock_status = ptr;
|
|
|
55ff7e |
+ if (lock_status) {
|
|
|
55ff7e |
+ slapi_ch_free((void **)&lock_status);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+static void
|
|
|
55ff7e |
+lock_count_free(void *ptr)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ int *lock_count = ptr;
|
|
|
55ff7e |
+ if (lock_count) {
|
|
|
55ff7e |
+ slapi_ch_free((void **)&lock_count);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
|
|
|
55ff7e |
void
|
|
|
55ff7e |
init_map_lock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
/* The plugin lock is initialized as free */
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "init_plugin_lock",
|
|
|
55ff7e |
"thread_id = %p\n", PR_GetCurrentThread());
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
- PR_NewThreadPrivateIndex (&thread_dummy, NULL);
|
|
|
55ff7e |
- PR_NewThreadPrivateIndex(&thread_plugin_lock_status, NULL);
|
|
|
55ff7e |
- PR_NewThreadPrivateIndex(&thread_plugin_lock_count, NULL);
|
|
|
55ff7e |
+ if (PR_NewThreadPrivateIndex(&thread_plugin_lock_status, lock_status_free) == PR_SUCCESS) {
|
|
|
55ff7e |
+ use_lock_status = PR_TRUE;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (PR_NewThreadPrivateIndex(&thread_plugin_lock_count, lock_count_free) == PR_SUCCESS) {
|
|
|
55ff7e |
+ use_lock_count = PR_TRUE;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "init_plugin_lock",
|
|
|
55ff7e |
"thread_plugin_lock_status = %d\n", thread_plugin_lock_status);
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "init_map_lock",
|
|
|
55ff7e |
"thread_plugin_lock_count = %d\n", thread_plugin_lock_count);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
rw_monitor_enabled(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
- if (thread_plugin_lock_status)
|
|
|
55ff7e |
+ if (use_lock_status)
|
|
|
55ff7e |
return (int) MAP_MONITOR_ENABLED;
|
|
|
55ff7e |
else
|
|
|
55ff7e |
return (int) MAP_MONITOR_DISABLED;
|
|
|
55ff7e |
@@ -2902,13 +2933,27 @@ get_plugin_monitor_status(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
int ret;
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (thread_plugin_lock_status)
|
|
|
55ff7e |
- ret = (int) PR_GetThreadPrivate(thread_plugin_lock_status);
|
|
|
55ff7e |
- else
|
|
|
55ff7e |
+ if (use_lock_status) {
|
|
|
55ff7e |
+ int *lock_status_p;
|
|
|
55ff7e |
+ lock_status_p = (int *) PR_GetThreadPrivate(thread_plugin_lock_status);
|
|
|
55ff7e |
+ if (lock_status_p == NULL) {
|
|
|
55ff7e |
+ /* if it was not initialized then allocates a structure
|
|
|
55ff7e |
+ * that will be private to that thread.
|
|
|
55ff7e |
+ * Later when the structure is retrieved (PR_GetThreadPrivate), the
|
|
|
55ff7e |
+ * content of the structure can be read/write without allocating
|
|
|
55ff7e |
+ * this private structure PR_SetThreadPrivate.
|
|
|
55ff7e |
+ * So this branch is processed one time per each thread
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+ lock_status_p = (int *) slapi_ch_calloc(1, sizeof (int));
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_status, (void *) lock_status_p);
|
|
|
55ff7e |
+ *lock_status_p = MAP_RWLOCK_FREE;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ ret = *lock_status_p;
|
|
|
55ff7e |
+ } else
|
|
|
55ff7e |
ret = (int) MAP_RWLOCK_UNINIT;
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "get_plugin_monitor_status",
|
|
|
55ff7e |
- "lock_status = %d (%p)\n", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_status = %d (%p)\n", use_lock_status ? "TRUE" : "FALSE", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
return ret;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
@@ -2918,15 +2963,26 @@ set_plugin_monitor_status(int lock_status)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "set_plugin_monitor_status",
|
|
|
55ff7e |
- "lock_status = %d --> %d (%p)\n", get_plugin_monitor_status(), (int) lock_status, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_status = %d --> %d (%p)\n", use_lock_status ? "TRUE" : "FALSE", get_plugin_monitor_status(), (int) lock_status, PR_GetCurrentThread());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (thread_plugin_lock_status)
|
|
|
55ff7e |
- PR_SetThreadPrivate(thread_plugin_lock_status, (void *) lock_status);
|
|
|
55ff7e |
- else
|
|
|
55ff7e |
- PR_SetThreadPrivate(thread_plugin_lock_status, (void *) MAP_RWLOCK_UNINIT);
|
|
|
55ff7e |
-
|
|
|
55ff7e |
-
|
|
|
55ff7e |
+ if (use_lock_status) {
|
|
|
55ff7e |
+ int *lock_status_p;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_status_p = (int *) PR_GetThreadPrivate(thread_plugin_lock_status);
|
|
|
55ff7e |
+ if (lock_status_p == NULL) {
|
|
|
55ff7e |
+ /* if it was not initialized then allocates a structure
|
|
|
55ff7e |
+ * that will be private to that thread.
|
|
|
55ff7e |
+ * Later when the structure is retrieved (PR_GetThreadPrivate), the
|
|
|
55ff7e |
+ * content of the structure can be read/write without allocating
|
|
|
55ff7e |
+ * this private structure PR_SetThreadPrivate.
|
|
|
55ff7e |
+ * So this branch is processed one time per each thread
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+ lock_status_p = (int *) slapi_ch_calloc(1, sizeof (int));
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_status, (void *) lock_status_p);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ *lock_status_p = lock_status;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
int
|
|
|
55ff7e |
@@ -2934,13 +2990,27 @@ get_plugin_monitor_count(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
int ret;
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (thread_plugin_lock_count)
|
|
|
55ff7e |
- ret = (int) PR_GetThreadPrivate(thread_plugin_lock_count);
|
|
|
55ff7e |
- else
|
|
|
55ff7e |
+ if (use_lock_count) {
|
|
|
55ff7e |
+ int *lock_count;
|
|
|
55ff7e |
+ lock_count = (int *) PR_GetThreadPrivate(thread_plugin_lock_count);
|
|
|
55ff7e |
+ if (lock_count == NULL) {
|
|
|
55ff7e |
+ /* if it was not initialized then allocates a structure
|
|
|
55ff7e |
+ * that will be private to that thread.
|
|
|
55ff7e |
+ * Later when the structure is retrieved (PR_GetThreadPrivate), the
|
|
|
55ff7e |
+ * content of the structure can be read/write without allocating
|
|
|
55ff7e |
+ * this private structure PR_SetThreadPrivate.
|
|
|
55ff7e |
+ * So this branch is processed one time per each thread
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+ lock_count = (int *) slapi_ch_calloc(1, sizeof (int));
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_count, (void *) lock_count);
|
|
|
55ff7e |
+ *lock_count = 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ ret = *lock_count;
|
|
|
55ff7e |
+ } else
|
|
|
55ff7e |
ret = (int) MAP_RWLOCK_UNINIT;
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "get_plugin_monitor_count",
|
|
|
55ff7e |
- "lock_count = %d (%p)\n", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_count = %d (%p)\n", use_lock_count ? "TRUE" : "FALSE", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
return ret;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
@@ -2950,13 +3020,23 @@ set_plugin_monitor_count(int lock_count)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "set_plugin_monitor_count",
|
|
|
55ff7e |
- "lock_count = %d --> %d (%p)\n", get_plugin_monitor_count(), (int) lock_count, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_count = %d --> %d (%p)\n", use_lock_count ? "TRUE" : "FALSE", get_plugin_monitor_count(), (int) lock_count, PR_GetCurrentThread());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
-
|
|
|
55ff7e |
- if (thread_plugin_lock_count)
|
|
|
55ff7e |
- PR_SetThreadPrivate(thread_plugin_lock_count, (void *) lock_count);
|
|
|
55ff7e |
- else
|
|
|
55ff7e |
- PR_SetThreadPrivate(thread_plugin_lock_count, (void *) MAP_RWLOCK_UNINIT);
|
|
|
55ff7e |
-
|
|
|
55ff7e |
-
|
|
|
55ff7e |
+ if (use_lock_count) {
|
|
|
55ff7e |
+ int *lock_count_p;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ lock_count_p = (int *) PR_GetThreadPrivate(thread_plugin_lock_count);
|
|
|
55ff7e |
+ if (lock_count_p == NULL) {
|
|
|
55ff7e |
+ /* if it was not initialized then allocates a structure
|
|
|
55ff7e |
+ * that will be private to that thread.
|
|
|
55ff7e |
+ * Later when the structure is retrieved (PR_GetThreadPrivate), the
|
|
|
55ff7e |
+ * content of the structure can be read/write without allocating
|
|
|
55ff7e |
+ * this private structure PR_SetThreadPrivate.
|
|
|
55ff7e |
+ * So this branch is processed one time per each thread
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+ lock_count_p = (int *) slapi_ch_calloc(1, sizeof (int));
|
|
|
55ff7e |
+ PR_SetThreadPrivate(thread_plugin_lock_count, (void *) lock_count_p);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ *lock_count_p = lock_count;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
}
|
|
|
55ff7e |
diff --git a/src/map.c b/src/map.c
|
|
|
55ff7e |
index db9e093..e953925 100644
|
|
|
55ff7e |
--- a/src/map.c
|
|
|
55ff7e |
+++ b/src/map.c
|
|
|
55ff7e |
@@ -1248,7 +1248,7 @@ int
|
|
|
55ff7e |
map_rdlock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
int lock_status;
|
|
|
55ff7e |
- int lock_count;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
int rc = 0;
|
|
|
55ff7e |
|
|
|
55ff7e |
if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
@@ -1260,7 +1260,7 @@ map_rdlock(void)
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
- lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map_rdlock",
|
|
|
55ff7e |
@@ -1271,52 +1271,52 @@ map_rdlock(void)
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
"map rdlock: old way lock_status == MAP_RWLOCK_UNINIT\n");
|
|
|
55ff7e |
return wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (lock_status == MAP_RWLOCK_FREE) {
|
|
|
55ff7e |
- /* The plugin lock is free, acquire it */
|
|
|
55ff7e |
+ if (lock_status == MAP_RWLOCK_FREE) {
|
|
|
55ff7e |
+ /* The plugin lock is free, acquire it */
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: current lock_status == MAP_RWLOCK_FREE\n");
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: current lock_status == MAP_RWLOCK_FREE\n");
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
- set_plugin_monitor_status(MAP_RLOCK_HELD);
|
|
|
55ff7e |
- set_plugin_monitor_count(1);
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_RLOCK_HELD);
|
|
|
55ff7e |
+ set_plugin_monitor_count(1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- if (lock_count != 0) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) ALERT !!! count was %d -> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ if (lock_count != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) ALERT !!! count was %d -> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
- /* Acquire the slapi plugin in read */
|
|
|
55ff7e |
- rc = plugin_rdlock();
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
- return rc;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ /* Acquire the slapi plugin in read */
|
|
|
55ff7e |
+ rc = plugin_rdlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
- rc = wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "Fail to acquire map lock in read (%d)\n", rc);
|
|
|
55ff7e |
- plugin_unlock();
|
|
|
55ff7e |
- return rc;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
- return 0;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ rc = wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "Fail to acquire map lock in read (%d)\n", rc);
|
|
|
55ff7e |
+ plugin_unlock();
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) was already hold %s : count=%d > %d!!!\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD": "MAP_RLOCK_HELD",
|
|
|
55ff7e |
- lock_count, lock_count + 1);
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map rdlock: (%p) was already hold %s : count=%d > %d!!!\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : "MAP_RLOCK_HELD",
|
|
|
55ff7e |
+ lock_count, lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
- set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
@@ -1324,7 +1324,7 @@ int
|
|
|
55ff7e |
map_wrlock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
int lock_status;
|
|
|
55ff7e |
- int lock_count;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
int rc = 0;
|
|
|
55ff7e |
|
|
|
55ff7e |
if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
@@ -1335,7 +1335,7 @@ map_wrlock(void)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
- lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map wrlock",
|
|
|
55ff7e |
@@ -1356,65 +1356,65 @@ map_wrlock(void)
|
|
|
55ff7e |
"map wrlock: current lock_status == MAP_LOCK_FREE\n");
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
- set_plugin_monitor_count(1);
|
|
|
55ff7e |
+ set_plugin_monitor_count(1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- if (lock_count != 0) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) ALERT !!! count was %d --> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ if (lock_count != 0) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) ALERT !!! count was %d --> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
- /* Acquire the slapi plugin in write */
|
|
|
55ff7e |
- rc = plugin_wrlock();
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
- return rc;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ /* Acquire the slapi plugin in write */
|
|
|
55ff7e |
+ rc = plugin_wrlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ return rc;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
- rc = wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
- plugin_unlock();
|
|
|
55ff7e |
- goto common;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
- } else {
|
|
|
55ff7e |
- set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
+ rc = wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ plugin_unlock();
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD": "MAP_RLOCK_HELD",
|
|
|
55ff7e |
- lock_count + 1);
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : "MAP_RLOCK_HELD",
|
|
|
55ff7e |
+ lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (lock_status == MAP_RLOCK_HELD) {
|
|
|
55ff7e |
- /* lock is already acquired in read */
|
|
|
55ff7e |
+ if (lock_status == MAP_RLOCK_HELD) {
|
|
|
55ff7e |
+ /* lock is already acquired in read */
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: weird situation map lock is held in read and now required in write mode\n");
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: weird situation map lock is held in read and now required in write mode\n");
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
- /* First free the lock held in read */
|
|
|
55ff7e |
- rc = plugin_unlock();
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: fail to unlock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
- goto common;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ /* First free the lock held in read */
|
|
|
55ff7e |
+ rc = plugin_unlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: fail to unlock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
- /* Second acquire it in write */
|
|
|
55ff7e |
- rc = plugin_wrlock();
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: fail to write lock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
- goto common;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ /* Second acquire it in write */
|
|
|
55ff7e |
+ rc = plugin_wrlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map wrlock: fail to write lock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
common:
|
|
|
55ff7e |
set_plugin_monitor_status(MAP_WLOCK_HELD);
|
|
|
55ff7e |
@@ -1425,7 +1425,7 @@ int
|
|
|
55ff7e |
map_unlock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
int lock_status;
|
|
|
55ff7e |
- int lock_count;
|
|
|
55ff7e |
+ int lock_count;
|
|
|
55ff7e |
int rc = 0;
|
|
|
55ff7e |
|
|
|
55ff7e |
if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
@@ -1436,7 +1436,7 @@ map_unlock(void)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
lock_status = get_plugin_monitor_status();
|
|
|
55ff7e |
- lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
+ lock_count = get_plugin_monitor_count();
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map_unlock",
|
|
|
55ff7e |
@@ -1448,48 +1448,48 @@ map_unlock(void)
|
|
|
55ff7e |
"map_unlock: old way lock_status == MAP_RWLOCK_UNINIT\n");
|
|
|
55ff7e |
|
|
|
55ff7e |
return wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
- if (lock_count == 1) {
|
|
|
55ff7e |
- set_plugin_monitor_status(MAP_RWLOCK_FREE);
|
|
|
55ff7e |
- rc = plugin_unlock();
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map unlock: fail to unlock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
- goto common;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
-#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ if (lock_count == 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_status(MAP_RWLOCK_FREE);
|
|
|
55ff7e |
+ rc = plugin_unlock();
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map_unlock: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
- 0);
|
|
|
55ff7e |
+ "map unlock: fail to unlock plugin lock (%d)\n", rc);
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ 0);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
- rc = wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
- if (rc) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ rc = wrap_rwlock_unlock(map_data.lock);
|
|
|
55ff7e |
+ if (rc) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"map_unlock: fail to unlock map lock (%d)\n", rc);
|
|
|
55ff7e |
- goto common;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ goto common;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
- if (lock_count >= 1) {
|
|
|
55ff7e |
- set_plugin_monitor_count(lock_count - 1);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (lock_count >= 1) {
|
|
|
55ff7e |
+ set_plugin_monitor_count(lock_count - 1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
- if (lock_count > 1) {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map_unlock: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
- lock_count - 1);
|
|
|
55ff7e |
- } else {
|
|
|
55ff7e |
- slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map_unlock: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
- "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
- lock_count - 1);
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
-#endif
|
|
|
55ff7e |
+ if (lock_count > 1) {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
+ } else {
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
+ "map_unlock: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
+ PR_GetCurrentThread(),
|
|
|
55ff7e |
+ "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
+ lock_count - 1);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
common:
|
|
|
55ff7e |
return rc;
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From 5e6953c1d4e776f5e084ea69a4f6e6b485362b3d Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
Date: Wed, 10 Apr 2019 15:54:16 +0200
|
|
|
55ff7e |
Subject: [PATCH 08/13] Bug 1694263: improve debug msg to match pstack threadId
|
|
|
55ff7e |
|
|
|
55ff7e |
Description:
|
|
|
55ff7e |
|
|
|
55ff7e |
A pstack is showing threadId that differs from the
|
|
|
55ff7e |
the thread pointer. To match logs with pstack
|
|
|
55ff7e |
better to display the threadId
|
|
|
55ff7e |
|
|
|
55ff7e |
https://bugzilla.redhat.com/show_bug.cgi?id=1694263
|
|
|
55ff7e |
Signed-off-by: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/back-sch.c | 10 +++++-----
|
|
|
55ff7e |
src/back-shr.c | 15 +++++++++++----
|
|
|
55ff7e |
src/back-shr.h | 1 +
|
|
|
55ff7e |
src/map.c | 30 +++++++++++++++---------------
|
|
|
55ff7e |
4 files changed, 32 insertions(+), 24 deletions(-)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
55ff7e |
index 2d0bad0..4cacb28 100644
|
|
|
55ff7e |
--- a/src/back-sch.c
|
|
|
55ff7e |
+++ b/src/back-sch.c
|
|
|
55ff7e |
@@ -2346,14 +2346,14 @@ backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "backend_be_pre_write_cb: (%p) MAP_RWLOCK_FREE -> MAP_WLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: (%p) MAP_RWLOCK_FREE -> MAP_WLOCK_HELD : count=%d\n", (void *) PR_MyThreadId(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
} else {
|
|
|
55ff7e |
set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"backend_be_pre_write_cb: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD": "MAP_RLOCK_HELD",
|
|
|
55ff7e |
lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
@@ -2428,7 +2428,7 @@ backend_be_post_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"backend_be_post_write_cb: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
0);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
@@ -2439,13 +2439,13 @@ backend_be_post_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
if (lock_count > 1) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"backend_be_post_write_cb: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
lock_count - 1);
|
|
|
55ff7e |
} else {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"backend_be_post_write_cb: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
"MAP_RWLOCK_FREE",
|
|
|
55ff7e |
lock_count - 1);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
diff --git a/src/back-shr.c b/src/back-shr.c
|
|
|
55ff7e |
index 920c135..2bfdf52 100644
|
|
|
55ff7e |
--- a/src/back-shr.c
|
|
|
55ff7e |
+++ b/src/back-shr.c
|
|
|
55ff7e |
@@ -2868,6 +2868,13 @@ backend_shr_internal_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
+static int
|
|
|
55ff7e |
+PR_MyThreadId(void)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ PRThread *thr = PR_GetCurrentThread();
|
|
|
55ff7e |
+ PRUint32 myself = PR_GetThreadID(thr);
|
|
|
55ff7e |
+ return myself;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
PRBool use_lock_status = PR_FALSE;
|
|
|
55ff7e |
static unsigned int thread_plugin_lock_status;
|
|
|
55ff7e |
PRBool use_lock_count = PR_FALSE;
|
|
|
55ff7e |
@@ -2953,7 +2960,7 @@ get_plugin_monitor_status(void)
|
|
|
55ff7e |
ret = (int) MAP_RWLOCK_UNINIT;
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "get_plugin_monitor_status",
|
|
|
55ff7e |
- "(%s) lock_status = %d (%p)\n", use_lock_status ? "TRUE" : "FALSE", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_status = %d (%p)\n", use_lock_status ? "TRUE" : "FALSE", ret, (void *) PR_MyThreadId());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
return ret;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
@@ -2963,7 +2970,7 @@ set_plugin_monitor_status(int lock_status)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "set_plugin_monitor_status",
|
|
|
55ff7e |
- "(%s) lock_status = %d --> %d (%p)\n", use_lock_status ? "TRUE" : "FALSE", get_plugin_monitor_status(), (int) lock_status, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_status = %d --> %d (%p)\n", use_lock_status ? "TRUE" : "FALSE", get_plugin_monitor_status(), (int) lock_status, (void *) PR_MyThreadId());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
if (use_lock_status) {
|
|
|
55ff7e |
@@ -3010,7 +3017,7 @@ get_plugin_monitor_count(void)
|
|
|
55ff7e |
ret = (int) MAP_RWLOCK_UNINIT;
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "get_plugin_monitor_count",
|
|
|
55ff7e |
- "(%s) lock_count = %d (%p)\n", use_lock_count ? "TRUE" : "FALSE", ret, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_count = %d (%p)\n", use_lock_count ? "TRUE" : "FALSE", ret, (void *) PR_MyThreadId());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
return ret;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
@@ -3020,7 +3027,7 @@ set_plugin_monitor_count(int lock_count)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "set_plugin_monitor_count",
|
|
|
55ff7e |
- "(%s) lock_count = %d --> %d (%p)\n", use_lock_count ? "TRUE" : "FALSE", get_plugin_monitor_count(), (int) lock_count, PR_GetCurrentThread());
|
|
|
55ff7e |
+ "(%s) lock_count = %d --> %d (%p)\n", use_lock_count ? "TRUE" : "FALSE", get_plugin_monitor_count(), (int) lock_count, (void *) PR_MyThreadId());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (use_lock_count) {
|
|
|
55ff7e |
int *lock_count_p;
|
|
|
55ff7e |
diff --git a/src/back-shr.h b/src/back-shr.h
|
|
|
55ff7e |
index 8c68b4f..5d72ad9 100644
|
|
|
55ff7e |
--- a/src/back-shr.h
|
|
|
55ff7e |
+++ b/src/back-shr.h
|
|
|
55ff7e |
@@ -30,6 +30,7 @@
|
|
|
55ff7e |
#define MAP_WLOCK_HELD 2
|
|
|
55ff7e |
#define MAP_RLOCK_HELD 1
|
|
|
55ff7e |
#define MAP_RWLOCK_FREE 0
|
|
|
55ff7e |
+static int PR_MyThreadId(void);
|
|
|
55ff7e |
int rw_monitor_enabled(void);
|
|
|
55ff7e |
int get_plugin_monitor_status(void);
|
|
|
55ff7e |
void set_plugin_monitor_status(int lock_status);
|
|
|
55ff7e |
diff --git a/src/map.c b/src/map.c
|
|
|
55ff7e |
index e953925..f80f465 100644
|
|
|
55ff7e |
--- a/src/map.c
|
|
|
55ff7e |
+++ b/src/map.c
|
|
|
55ff7e |
@@ -1264,7 +1264,7 @@ map_rdlock(void)
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map_rdlock",
|
|
|
55ff7e |
- "thread_id = %p (call level = %d)\n", PR_GetCurrentThread(), wrap_get_call_level());
|
|
|
55ff7e |
+ "thread_id = %p (call level = %d)\n", (void *) PR_MyThreadId(), wrap_get_call_level());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
/* This is not initialized used the old way */
|
|
|
55ff7e |
@@ -1284,7 +1284,7 @@ map_rdlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
if (lock_count != 0) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) ALERT !!! count was %d -> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
+ "map rdlock: (%p) ALERT !!! count was %d -> 1\n", (void *) PR_MyThreadId(), lock_count);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
@@ -1292,12 +1292,12 @@ map_rdlock(void)
|
|
|
55ff7e |
rc = plugin_rdlock();
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", (void *) PR_MyThreadId(), rc);
|
|
|
55ff7e |
return rc;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+ "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", (void *) PR_MyThreadId(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
rc = wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
@@ -1312,7 +1312,7 @@ map_rdlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
"map rdlock: (%p) was already hold %s : count=%d > %d!!!\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : "MAP_RLOCK_HELD",
|
|
|
55ff7e |
lock_count, lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
@@ -1339,7 +1339,7 @@ map_wrlock(void)
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map wrlock",
|
|
|
55ff7e |
- "thread_id = %p (call level = %d)\n", PR_GetCurrentThread(), wrap_get_call_level());
|
|
|
55ff7e |
+ "thread_id = %p (call level = %d)\n", (void *) PR_MyThreadId(), wrap_get_call_level());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
/* This is not initialized used the old way */
|
|
|
55ff7e |
@@ -1360,25 +1360,25 @@ map_wrlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
if (lock_count != 0) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) ALERT !!! count was %d --> 1\n", PR_GetCurrentThread(), lock_count);
|
|
|
55ff7e |
+ "map wrlock: (%p) ALERT !!! count was %d --> 1\n", (void *) PR_MyThreadId(), lock_count);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
/* Acquire the slapi plugin in write */
|
|
|
55ff7e |
rc = plugin_wrlock();
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", (void *) PR_MyThreadId(), rc);
|
|
|
55ff7e |
return rc;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", PR_GetCurrentThread(), 1);
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", (void *) PR_MyThreadId(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
rc = wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", PR_GetCurrentThread(), rc);
|
|
|
55ff7e |
+ "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", (void *) PR_MyThreadId(), rc);
|
|
|
55ff7e |
plugin_unlock();
|
|
|
55ff7e |
goto common;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
@@ -1387,7 +1387,7 @@ map_wrlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"map wrlock: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : "MAP_RLOCK_HELD",
|
|
|
55ff7e |
lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
@@ -1440,7 +1440,7 @@ map_unlock(void)
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map_unlock",
|
|
|
55ff7e |
- "thread_id = %p (call level = %d)\n", PR_GetCurrentThread(), wrap_get_call_level());
|
|
|
55ff7e |
+ "thread_id = %p (call level = %d)\n", (void *) PR_MyThreadId(), wrap_get_call_level());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
/* This is not initialized used the old way */
|
|
|
55ff7e |
@@ -1461,7 +1461,7 @@ map_unlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"map_unlock: (%p) %s --> MAP_RWLOCK_FREE : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
0);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
@@ -1478,13 +1478,13 @@ map_unlock(void)
|
|
|
55ff7e |
if (lock_count > 1) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"map_unlock: (%p) keep %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : (lock_status == MAP_RLOCK_HELD) ? "MAP_RLOCK_HELD" : "MAP_RWLOCK_FREE",
|
|
|
55ff7e |
lock_count - 1);
|
|
|
55ff7e |
} else {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
"map_unlock: (%p) is now %s : count=%d\n",
|
|
|
55ff7e |
- PR_GetCurrentThread(),
|
|
|
55ff7e |
+ (void *) PR_MyThreadId(),
|
|
|
55ff7e |
"MAP_RWLOCK_FREE",
|
|
|
55ff7e |
lock_count - 1);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From 52fd1595699ea9859c2f4c41ae7ff425d65ae3cf Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
Date: Wed, 10 Apr 2019 18:40:02 +0200
|
|
|
55ff7e |
Subject: [PATCH 09/13] Bug 1694263: On some 'cn=config' updates bepost_op are
|
|
|
55ff7e |
not called that leads to lock leak
|
|
|
55ff7e |
|
|
|
55ff7e |
Description:
|
|
|
55ff7e |
The true cause of the hang was that some updates on 'cn=config'
|
|
|
55ff7e |
can skip the BEPOST phase. (in this bug it was the maxbersize setting).
|
|
|
55ff7e |
The consequence is that the slapi-nis map lock was acquired but not released.
|
|
|
55ff7e |
The fix consist to ignore (not lock slapi-nis map) write operation done
|
|
|
55ff7e |
on 'cn=config' and 'cn=schema'
|
|
|
55ff7e |
|
|
|
55ff7e |
https://bugzilla.redhat.com/show_bug.cgi?id=1694263
|
|
|
55ff7e |
Signed-off-by: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/back-sch.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
|
|
|
55ff7e |
src/back-shr.c | 22 ++++++++++++++++++++--
|
|
|
55ff7e |
src/back-shr.h | 3 ++-
|
|
|
55ff7e |
src/plug-sch.c | 7 +++++++
|
|
|
55ff7e |
4 files changed, 74 insertions(+), 6 deletions(-)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
55ff7e |
index 4cacb28..9201c2e 100644
|
|
|
55ff7e |
--- a/src/back-sch.c
|
|
|
55ff7e |
+++ b/src/back-sch.c
|
|
|
55ff7e |
@@ -2303,6 +2303,33 @@ backend_betxn_pre_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
|
|
|
55ff7e |
return state->use_be_txns ? backend_write_cb(pb, state) : 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+static PRBool
|
|
|
55ff7e |
+backend_be_write_ignore(Slapi_PBlock *pb)
|
|
|
55ff7e |
+{
|
|
|
55ff7e |
+ char *dn = NULL;
|
|
|
55ff7e |
+ Slapi_DN *target_sdn = NULL;
|
|
|
55ff7e |
+ int check;
|
|
|
55ff7e |
+ int i = 0;
|
|
|
55ff7e |
+ PRBool ignore = PR_FALSE;
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ /* Check if the target DN is a subordinates of
|
|
|
55ff7e |
+ * on of the ignored containers
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+ slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET, &dn;;
|
|
|
55ff7e |
+ target_sdn = slapi_sdn_new_dn_byval(dn);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ for (i = 0; ignored_containers_sdn[i]; i++) {
|
|
|
55ff7e |
+ check = slapi_sdn_issuffix(target_sdn, ignored_containers_sdn[i]);
|
|
|
55ff7e |
+ if (check != 0) {
|
|
|
55ff7e |
+ /* This entry is an ignored container */
|
|
|
55ff7e |
+ ignore = PR_TRUE;
|
|
|
55ff7e |
+ break;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ slapi_sdn_free(&target_sdn);
|
|
|
55ff7e |
+ return ignore;
|
|
|
55ff7e |
+}
|
|
|
55ff7e |
+
|
|
|
55ff7e |
|
|
|
55ff7e |
static int
|
|
|
55ff7e |
backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
@@ -2323,6 +2350,14 @@ backend_be_pre_write_cb(Slapi_PBlock *pb) {
|
|
|
55ff7e |
if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+ if (backend_be_write_ignore(pb)) {
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "backend_be_pre_write_cb: (%p) operation is not impacting schema compat\n", PR_MyThreadId(), 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
wrap_inc_call_level();
|
|
|
55ff7e |
@@ -2404,9 +2439,16 @@ backend_be_post_write_cb(Slapi_PBlock *pb)
|
|
|
55ff7e |
/* No data to serve yet */
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
- if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
- return 0;
|
|
|
55ff7e |
- }
|
|
|
55ff7e |
+ if (rw_monitor_enabled() == MAP_MONITOR_DISABLED) {
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ if (backend_be_write_ignore(pb)) {
|
|
|
55ff7e |
+#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
+ slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
+ "backend_be_post_write_cb: (%p) operation was not impacting schema compat\n", PR_MyThreadId(), 1);
|
|
|
55ff7e |
+#endif
|
|
|
55ff7e |
+ return 0;
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
wrap_inc_call_level();
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-shr.c b/src/back-shr.c
|
|
|
55ff7e |
index 2bfdf52..b348869 100644
|
|
|
55ff7e |
--- a/src/back-shr.c
|
|
|
55ff7e |
+++ b/src/back-shr.c
|
|
|
55ff7e |
@@ -2868,7 +2868,7 @@ backend_shr_internal_postop_init(Slapi_PBlock *pb, struct plugin_state *state)
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
-static int
|
|
|
55ff7e |
+int
|
|
|
55ff7e |
PR_MyThreadId(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
PRThread *thr = PR_GetCurrentThread();
|
|
|
55ff7e |
@@ -2902,14 +2902,32 @@ lock_count_free(void *ptr)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
+/* This is used to ignore some write operations
|
|
|
55ff7e |
+ * if they target subordinates entry of ignored containers
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+Slapi_DN **ignored_containers_sdn = NULL;
|
|
|
55ff7e |
void
|
|
|
55ff7e |
init_map_lock(void)
|
|
|
55ff7e |
{
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
/* The plugin lock is initialized as free */
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "init_plugin_lock",
|
|
|
55ff7e |
- "thread_id = %p\n", PR_GetCurrentThread());
|
|
|
55ff7e |
+ "thread_id = %p\n", PR_MyThreadId());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
+ if (ignored_containers_sdn == NULL) {
|
|
|
55ff7e |
+ /* allocates ignored_containers_sdn of Slapi_DN* only once
|
|
|
55ff7e |
+ * It will be used later in be_pre/post_write_cb
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+ int cnt;
|
|
|
55ff7e |
+ char *ignored_containers[3] = { "cn=config", "cn=schema", NULL};
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ for (cnt = 0; ignored_containers[cnt]; cnt++);
|
|
|
55ff7e |
+ ignored_containers_sdn = (Slapi_DN **) slapi_ch_calloc(cnt + 1, sizeof(Slapi_DN *));
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+ for (cnt = 0; ignored_containers[cnt]; cnt++) {
|
|
|
55ff7e |
+ ignored_containers_sdn[cnt] = slapi_sdn_new_dn_byval(ignored_containers[cnt]);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
|
|
|
55ff7e |
if (PR_NewThreadPrivateIndex(&thread_plugin_lock_status, lock_status_free) == PR_SUCCESS) {
|
|
|
55ff7e |
use_lock_status = PR_TRUE;
|
|
|
55ff7e |
diff --git a/src/back-shr.h b/src/back-shr.h
|
|
|
55ff7e |
index 5d72ad9..d01b999 100644
|
|
|
55ff7e |
--- a/src/back-shr.h
|
|
|
55ff7e |
+++ b/src/back-shr.h
|
|
|
55ff7e |
@@ -30,13 +30,14 @@
|
|
|
55ff7e |
#define MAP_WLOCK_HELD 2
|
|
|
55ff7e |
#define MAP_RLOCK_HELD 1
|
|
|
55ff7e |
#define MAP_RWLOCK_FREE 0
|
|
|
55ff7e |
-static int PR_MyThreadId(void);
|
|
|
55ff7e |
+int PR_MyThreadId(void);
|
|
|
55ff7e |
int rw_monitor_enabled(void);
|
|
|
55ff7e |
int get_plugin_monitor_status(void);
|
|
|
55ff7e |
void set_plugin_monitor_status(int lock_status);
|
|
|
55ff7e |
int get_plugin_monitor_count(void);
|
|
|
55ff7e |
void set_plugin_monitor_count(int lock_count);
|
|
|
55ff7e |
void init_map_lock(void);
|
|
|
55ff7e |
+Slapi_DN **ignored_containers_sdn;
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
struct plugin_state;
|
|
|
55ff7e |
diff --git a/src/plug-sch.c b/src/plug-sch.c
|
|
|
55ff7e |
index 2d9c75b..913abe2 100644
|
|
|
55ff7e |
--- a/src/plug-sch.c
|
|
|
55ff7e |
+++ b/src/plug-sch.c
|
|
|
55ff7e |
@@ -197,6 +197,13 @@ plugin_shutdown(Slapi_PBlock *pb)
|
|
|
55ff7e |
if (state->plugin_base != NULL) {
|
|
|
55ff7e |
slapi_ch_free((void **)&state->plugin_base);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
+ if (ignored_containers_sdn) {
|
|
|
55ff7e |
+ int i;
|
|
|
55ff7e |
+ for (i = 0; ignored_containers_sdn[i]; i++) {
|
|
|
55ff7e |
+ slapi_sdn_free(&ignored_containers_sdn[i]);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
+ slapi_ch_free((void **)&ignored_containers_sdn);
|
|
|
55ff7e |
+ }
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
|
|
|
55ff7e |
"plugin shutdown completed\n");
|
|
|
55ff7e |
return 0;
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From c44f9ca81afa6cbf817159d37b0695d6462866eb Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
55ff7e |
Date: Tue, 23 Apr 2019 09:39:08 +0300
|
|
|
55ff7e |
Subject: [PATCH 10/13] Cast callbacks passed to xdrrec_create to a right type
|
|
|
55ff7e |
|
|
|
55ff7e |
With newer compilers there are stricter checks on callback type
|
|
|
55ff7e |
validation. As result, we need to cast the callback signatures even
|
|
|
55ff7e |
though it makes no practical difference in our test case.
|
|
|
55ff7e |
---
|
|
|
55ff7e |
tests/clients/yp.c | 6 ++++--
|
|
|
55ff7e |
1 file changed, 4 insertions(+), 2 deletions(-)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/tests/clients/yp.c b/tests/clients/yp.c
|
|
|
55ff7e |
index 200d591..bc2da1f 100644
|
|
|
55ff7e |
--- a/tests/clients/yp.c
|
|
|
55ff7e |
+++ b/tests/clients/yp.c
|
|
|
55ff7e |
@@ -34,6 +34,8 @@
|
|
|
55ff7e |
#include <rpc/rpc.h>
|
|
|
55ff7e |
#include "../../yp/yp.h"
|
|
|
55ff7e |
|
|
|
55ff7e |
+typedef int (*xdrrec_proc_t)(void *, void *, int);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
static struct sockaddr_in server;
|
|
|
55ff7e |
static int connected;
|
|
|
55ff7e |
|
|
|
55ff7e |
@@ -189,7 +191,7 @@ all(CLIENT *client, FILE *output, int argc, char **argv)
|
|
|
55ff7e |
}
|
|
|
55ff7e |
|
|
|
55ff7e |
memset(&s, 0, sizeof(s));
|
|
|
55ff7e |
- xdrrec_create(&s, 0, 0, (char *) &sock, &readjunk, &writejunk);
|
|
|
55ff7e |
+ xdrrec_create(&s, 0, 0, (char *) &sock, (xdrrec_proc_t) &readjunk, (xdrrec_proc_t) &writejunk);
|
|
|
55ff7e |
s.x_op = XDR_ENCODE;
|
|
|
55ff7e |
|
|
|
55ff7e |
memset(&req, 0, sizeof(req));
|
|
|
55ff7e |
@@ -218,7 +220,7 @@ all(CLIENT *client, FILE *output, int argc, char **argv)
|
|
|
55ff7e |
xdr_destroy(&s);
|
|
|
55ff7e |
|
|
|
55ff7e |
memset(&s, 0, sizeof(s));
|
|
|
55ff7e |
- xdrrec_create(&s, 0, 0, (char *) &sock, &readjunk, &writejunk);
|
|
|
55ff7e |
+ xdrrec_create(&s, 0, 0, (char *) &sock, (xdrrec_proc_t) &readjunk, (xdrrec_proc_t) &writejunk);
|
|
|
55ff7e |
s.x_op = XDR_DECODE;
|
|
|
55ff7e |
xdrrec_skiprecord(&s);
|
|
|
55ff7e |
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From a4f645e09d92a8b8f7a80f939091689075d53de1 Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
55ff7e |
Date: Tue, 23 Apr 2019 09:40:59 +0300
|
|
|
55ff7e |
Subject: [PATCH 11/13] Define send_ldap_result as an external function
|
|
|
55ff7e |
prototype
|
|
|
55ff7e |
|
|
|
55ff7e |
389-ds does not expose send_ldap_result() as a public API. However,
|
|
|
55ff7e |
we depend on it because slapi_send_ldap_result() is not usable for
|
|
|
55ff7e |
the specific use case of the schema compatibility plugin.
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/back-sch.c | 6 ++++++
|
|
|
55ff7e |
1 file changed, 6 insertions(+)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-sch.c b/src/back-sch.c
|
|
|
55ff7e |
index 9201c2e..f6211bc 100644
|
|
|
55ff7e |
--- a/src/back-sch.c
|
|
|
55ff7e |
+++ b/src/back-sch.c
|
|
|
55ff7e |
@@ -55,6 +55,12 @@
|
|
|
55ff7e |
#include "map.h"
|
|
|
55ff7e |
#include "back-sch.h"
|
|
|
55ff7e |
|
|
|
55ff7e |
+/*
|
|
|
55ff7e |
+ * This is not a public function in 389-ds but we need to use it in backend_search_cb(),
|
|
|
55ff7e |
+ * see a comment there on the difference between slapi_send_ldap_result() and send_ldap_result().
|
|
|
55ff7e |
+ */
|
|
|
55ff7e |
+extern void send_ldap_result(Slapi_PBlock *pb, int err, char *matched, char *text, int nentries, struct berval **urls);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
static int backend_passwdmod_extop(Slapi_PBlock *pb);
|
|
|
55ff7e |
backend_extop_handlers_t extop_handlers[] = {{EXTOP_PASSWD_OID, (IFP) backend_passwdmod_extop},
|
|
|
55ff7e |
{NULL, NULL}};
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From dc3c95cf5b5a2c2d5e7f81ed02f2d9bf3c9acb9f Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
55ff7e |
Date: Tue, 23 Apr 2019 09:42:41 +0300
|
|
|
55ff7e |
Subject: [PATCH 12/13] Declare transaction-aware callbacks for schema compat
|
|
|
55ff7e |
plugin
|
|
|
55ff7e |
|
|
|
55ff7e |
Schema compatibility plugin provides two transaction-aware
|
|
|
55ff7e |
callbacks. The functions need to be declared as they are defined and
|
|
|
55ff7e |
used in different compilation units.
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/backend.h | 5 +++++
|
|
|
55ff7e |
1 file changed, 5 insertions(+)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/backend.h b/src/backend.h
|
|
|
55ff7e |
index f0a5bbb..4034704 100644
|
|
|
55ff7e |
--- a/src/backend.h
|
|
|
55ff7e |
+++ b/src/backend.h
|
|
|
55ff7e |
@@ -68,6 +68,11 @@ int backend_init_postop(struct slapi_pblock *pb, struct plugin_state *state);
|
|
|
55ff7e |
int backend_init_internal_postop(struct slapi_pblock *pb,
|
|
|
55ff7e |
struct plugin_state *state);
|
|
|
55ff7e |
|
|
|
55ff7e |
+/* Only used for schema compatibility plugin*/
|
|
|
55ff7e |
+int backend_init_be_preop(Slapi_PBlock *pb, struct plugin_state *state);
|
|
|
55ff7e |
+int backend_init_be_postop(Slapi_PBlock *pb, struct plugin_state *state);
|
|
|
55ff7e |
+
|
|
|
55ff7e |
+
|
|
|
55ff7e |
/* Read the server's name. */
|
|
|
55ff7e |
int backend_read_master_name(struct plugin_state *state,
|
|
|
55ff7e |
struct slapi_pblock *pb,
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|
|
|
55ff7e |
|
|
|
55ff7e |
From 1d9e79557df660f4556edb59bedead00eda9b757 Mon Sep 17 00:00:00 2001
|
|
|
55ff7e |
From: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
55ff7e |
Date: Tue, 23 Apr 2019 09:44:48 +0300
|
|
|
55ff7e |
Subject: [PATCH 13/13] Use portable definitions for printing PRUint32 values
|
|
|
55ff7e |
|
|
|
55ff7e |
Also include proper headers for NSPR thread-local variable handling.
|
|
|
55ff7e |
Fixes covscan warnings.
|
|
|
55ff7e |
---
|
|
|
55ff7e |
src/back-shr.c | 4 +++-
|
|
|
55ff7e |
src/map.c | 28 ++++++++++++++++------------
|
|
|
55ff7e |
2 files changed, 19 insertions(+), 13 deletions(-)
|
|
|
55ff7e |
|
|
|
55ff7e |
diff --git a/src/back-shr.c b/src/back-shr.c
|
|
|
55ff7e |
index b348869..472846a 100644
|
|
|
55ff7e |
--- a/src/back-shr.c
|
|
|
55ff7e |
+++ b/src/back-shr.c
|
|
|
55ff7e |
@@ -37,7 +37,9 @@
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
#include <rpc/xdr.h>
|
|
|
55ff7e |
-#include <nspr4/prtypes.h>
|
|
|
55ff7e |
+#include <prtypes.h>
|
|
|
55ff7e |
+/* NSPR private API for thread-local variables */
|
|
|
55ff7e |
+#include <private/prpriv.h>
|
|
|
55ff7e |
#include "../yp/yp.h"
|
|
|
55ff7e |
|
|
|
55ff7e |
#ifdef HAVE_TCPD_H
|
|
|
55ff7e |
diff --git a/src/map.c b/src/map.c
|
|
|
55ff7e |
index f80f465..3be60b4 100644
|
|
|
55ff7e |
--- a/src/map.c
|
|
|
55ff7e |
+++ b/src/map.c
|
|
|
55ff7e |
@@ -23,6 +23,7 @@
|
|
|
55ff7e |
#include "config.h"
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
+#include <inttypes.h>
|
|
|
55ff7e |
#include <sys/types.h>
|
|
|
55ff7e |
#include <search.h>
|
|
|
55ff7e |
#include <stdlib.h>
|
|
|
55ff7e |
@@ -40,6 +41,9 @@
|
|
|
55ff7e |
|
|
|
55ff7e |
#include <rpc/rpc.h>
|
|
|
55ff7e |
|
|
|
55ff7e |
+/* NSPR private API for thread-local variables */
|
|
|
55ff7e |
+#include <private/prpriv.h>
|
|
|
55ff7e |
+
|
|
|
55ff7e |
#include "backend.h"
|
|
|
55ff7e |
#include "disp-nis.h"
|
|
|
55ff7e |
#include "map.h"
|
|
|
55ff7e |
@@ -1264,7 +1268,7 @@ map_rdlock(void)
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "map_rdlock",
|
|
|
55ff7e |
- "thread_id = %p (call level = %d)\n", (void *) PR_MyThreadId(), wrap_get_call_level());
|
|
|
55ff7e |
+ "thread_id = %"PRIx32" (call level = %d)\n", PR_MyThreadId(), wrap_get_call_level());
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
if (lock_status == MAP_RWLOCK_UNINIT) {
|
|
|
55ff7e |
/* This is not initialized used the old way */
|
|
|
55ff7e |
@@ -1284,7 +1288,7 @@ map_rdlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
if (lock_count != 0) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) ALERT !!! count was %d -> 1\n", (void *) PR_MyThreadId(), lock_count);
|
|
|
55ff7e |
+ "map rdlock: (%"PRIx32") ALERT !!! count was %d -> 1\n", PR_MyThreadId(), lock_count);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
@@ -1292,12 +1296,12 @@ map_rdlock(void)
|
|
|
55ff7e |
rc = plugin_rdlock();
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", (void *) PR_MyThreadId(), rc);
|
|
|
55ff7e |
+ "map rdlock: (%"PRIx32") MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_MyThreadId(), rc);
|
|
|
55ff7e |
return rc;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", (void *) PR_MyThreadId(), 1);
|
|
|
55ff7e |
+ "map rdlock: (%"PRIx32") MAP_RWLOCK_FREE -> MAP_RLOCK_HELD : count=%d\n", PR_MyThreadId(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
rc = wrap_rwlock_rdlock(map_data.lock);
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
@@ -1311,8 +1315,8 @@ map_rdlock(void)
|
|
|
55ff7e |
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map rdlock: (%p) was already hold %s : count=%d > %d!!!\n",
|
|
|
55ff7e |
- (void *) PR_MyThreadId(),
|
|
|
55ff7e |
+ "map rdlock: (%x"PRIx32") was already hold %s : count=%d > %d!!!\n",
|
|
|
55ff7e |
+ PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : "MAP_RLOCK_HELD",
|
|
|
55ff7e |
lock_count, lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
@@ -1360,25 +1364,25 @@ map_wrlock(void)
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
if (lock_count != 0) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) ALERT !!! count was %d --> 1\n", (void *) PR_MyThreadId(), lock_count);
|
|
|
55ff7e |
+ "map wrlock: (%"PRIx32") ALERT !!! count was %d --> 1\n", PR_MyThreadId(), lock_count);
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
/* Acquire the slapi plugin in write */
|
|
|
55ff7e |
rc = plugin_wrlock();
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schemacompat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", (void *) PR_MyThreadId(), rc);
|
|
|
55ff7e |
+ "map wrlock: (%"PRIx32") MAP_RWLOCK_FREE -> MAP_RLOCK_HELD: fail to read lock plugin lock (%d)\n", PR_MyThreadId(), rc);
|
|
|
55ff7e |
return rc;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", (void *) PR_MyThreadId(), 1);
|
|
|
55ff7e |
+ "map wrlock: (%"PRIx32") MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : count=%d\n", PR_MyThreadId(), 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
|
|
|
55ff7e |
rc = wrap_rwlock_wrlock(map_data.lock);
|
|
|
55ff7e |
if (rc) {
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", (void *) PR_MyThreadId(), rc);
|
|
|
55ff7e |
+ "map wrlock: (%"PRIx32") MAP_RWLOCK_FREE --> MAP_WLOCK_HELD : fail to write lock map lock (%d)\n", PR_MyThreadId(), rc);
|
|
|
55ff7e |
plugin_unlock();
|
|
|
55ff7e |
goto common;
|
|
|
55ff7e |
}
|
|
|
55ff7e |
@@ -1386,8 +1390,8 @@ map_wrlock(void)
|
|
|
55ff7e |
set_plugin_monitor_count(lock_count + 1);
|
|
|
55ff7e |
#if DEBUG_MAP_LOCK
|
|
|
55ff7e |
slapi_log_error(SLAPI_LOG_FATAL, "schema-compat",
|
|
|
55ff7e |
- "map wrlock: (%p) %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
- (void *) PR_MyThreadId(),
|
|
|
55ff7e |
+ "map wrlock: (%"PRIx32") %s --> MAP_WLOCK_HELD : count=%d\n",
|
|
|
55ff7e |
+ PR_MyThreadId(),
|
|
|
55ff7e |
(lock_status == MAP_WLOCK_HELD) ? "MAP_WLOCK_HELD" : "MAP_RLOCK_HELD",
|
|
|
55ff7e |
lock_count + 1);
|
|
|
55ff7e |
#endif
|
|
|
55ff7e |
--
|
|
|
55ff7e |
2.21.0
|
|
|
55ff7e |
|