ldap/servers/plugins/replication/repl5_replica_config.c | 28 +++++++++++-----
1 file changed, 20 insertions(+), 8 deletions(-)
New commits:
commit a5fdcddd4acc0811faa4a0152218a9702c979115
Author: Noriko Hosoi <nhosoi(a)jiji.usersys.redhat.com>
Date: Thu Jul 28 17:08:22 2011 -0700
Bug 663752 - Cert renewal for attrcrypt and encchangelog
https://bugzilla.redhat.com/show_bug.cgi?id=663752
Description: Replica config modify callback replica_config_post_
modify (repl5_replica_config.c) calls an internal modify API with
s_configLock held. The modify ends up calling a replica config
callback, in which it tries to acquire the same s_configLock and
it hangs there since the locking function PR_Lock is not re-entrant.
This patch avoids calling the internal modify API inside of s_configLock.
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c
b/ldap/servers/plugins/replication/repl5_replica_config.c
index 2caa94f..e31078f 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -79,6 +79,11 @@ static int replica_task_done(Replica *replica);
static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry
*e);
+/*
+ * Note: internal add/modify/delete operations should not be run while
+ * s_configLock is held. E.g., slapi_modify_internal_pb via replica_task_done
+ * in replica_config_post_modify.
+ */
static PRLock *s_configLock;
static int
@@ -480,6 +485,7 @@ replica_config_post_modify(Slapi_PBlock *pb,
char *config_attr, *config_attr_value;
Slapi_Operation *op;
void *identity;
+ int flag_need_cleanup = 0;
if (returntext)
{
@@ -569,23 +575,29 @@ replica_config_post_modify(Slapi_PBlock *pb,
if (strcasecmp (config_attr, TASK_ATTR) == 0)
{
- *returncode = replica_cleanup_task(mtnode_ext->replica,
- config_attr_value,
- errortext, apply_mods);
+ flag_need_cleanup = 1;
}
}
}
}
done:
- if (mtnode_ext->replica)
- object_release (mtnode_ext->replica);
-
+ PR_Unlock (s_configLock);
+
/* slapi_ch_free accepts NULL pointer */
- slapi_ch_free ((void**)&replica_root);
+ slapi_ch_free_string (&replica_root);
- PR_Unlock (s_configLock);
+ /* Call replica_cleanup_task after s_configLock is reliesed */
+ if (flag_need_cleanup)
+ {
+ *returncode = replica_cleanup_task(mtnode_ext->replica,
+ config_attr_value,
+ errortext, apply_mods);
+ }
+ if (mtnode_ext->replica)
+ object_release (mtnode_ext->replica);
+
if (*returncode != LDAP_SUCCESS)
{
return SLAPI_DSE_CALLBACK_ERROR;