ldap/servers
by Mark Reynolds
ldap/servers/plugins/automember/automember.c | 117 ++++++++++++++++++++-------
ldap/servers/slapd/back-ldbm/ldbm_add.c | 4
ldap/servers/slapd/back-ldbm/ldbm_delete.c | 5 +
ldap/servers/slapd/back-ldbm/ldbm_modify.c | 2
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 3
ldap/servers/slapd/plugin.c | 3
6 files changed, 102 insertions(+), 32 deletions(-)
New commits:
commit 67a076422c44f135048f8eac77c4b1f9fbcce3ee
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Dec 9 16:57:35 2013 -0500
Ticket 47622 - Automember betxnpreoperation - transaction not aborted when group entry does not exist
Bug Description: If the group defined in the automember plugin does not exist, than any add operation
that should trigger an update, succeeds even though the automember update failed.
Fix Description: Return an error if a automember post operation update fails - previously we always
returned success.
Updated plugin_call_func() to check the result of betxn postop plugins.
Also added return text to the result message when a betxn plugin fails. This is
useful for clients to explain why the operation failed.
https://fedorahosted.org/389/ticket/47622
Jenkins: passed
Valgrind: passed
Coverity: passed
Reviewed by: rmeggins(Thanks!)
diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
index e58eb1e..13ec13e 100644
--- a/ldap/servers/plugins/automember/automember.c
+++ b/ldap/servers/plugins/automember/automember.c
@@ -103,8 +103,8 @@ static struct automemberRegexRule *automember_parse_regex_rule(char *rule_string
static void automember_free_regex_rule(struct automemberRegexRule *rule);
static int automember_parse_grouping_attr(char *value, char **grouping_attr,
char **grouping_value);
-static void automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd);
-static void automember_add_member_value(Slapi_Entry *member_e, const char *group_dn,
+static int automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd);
+static int automember_add_member_value(Slapi_Entry *member_e, const char *group_dn,
char *grouping_attr, char *grouping_value, PRFileDesc *ldif_fd);
const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
@@ -1401,7 +1401,7 @@ automember_parse_grouping_attr(char *value, char **grouping_attr, char **groupin
* Determines which target groups need to be updated according to
* the rules in config, then performs the updates.
*/
-static void
+static int
automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd)
{
PRCList *rule = NULL;
@@ -1412,10 +1412,11 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
Slapi_DN *last = NULL;
PRCList *curr_exclusion = NULL;
char **vals = NULL;
+ int rc = 0;
int i = 0;
if (!config || !e) {
- return;
+ return -1;
}
slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
@@ -1555,15 +1556,23 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
if (PR_CLIST_IS_EMPTY(&targets)) {
/* Add to each default group. */
for (i = 0; config->default_groups && config->default_groups[i]; i++) {
- automember_add_member_value(e, config->default_groups[i],
- config->grouping_attr, config->grouping_value, ldif_fd);
+ if(automember_add_member_value(e, config->default_groups[i], config->grouping_attr,
+ config->grouping_value, ldif_fd))
+ {
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto out;
+ }
}
} else {
/* Update the target groups. */
dnitem = (struct automemberDNListItem *)PR_LIST_HEAD(&targets);
while ((PRCList *)dnitem != &targets) {
- automember_add_member_value(e, slapi_sdn_get_dn(dnitem->dn),
- config->grouping_attr, config->grouping_value, ldif_fd);
+ if(automember_add_member_value(e, slapi_sdn_get_dn(dnitem->dn),config->grouping_attr,
+ config->grouping_value, ldif_fd))
+ {
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto out;
+ }
dnitem = (struct automemberDNListItem *)PR_NEXT_LINK((PRCList *)dnitem);
}
}
@@ -1582,6 +1591,9 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
slapi_ch_free((void**)&dnitem);
}
+out:
+
+ return rc;
}
/*
@@ -1589,7 +1601,7 @@ automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileD
*
* Adds a member entry to a group.
*/
-static void
+static int
automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *grouping_attr,
char *grouping_value, PRFileDesc *ldif_fd)
{
@@ -1600,6 +1612,7 @@ automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *g
char *vals[2];
char *member_value = NULL;
int freeit = 0;
+ int rc = 0;
/* If grouping_value is dn, we need to fetch the dn instead. */
if (slapi_attr_type_cmp(grouping_value, "dn", SLAPI_TYPE_CMP_EXACT) == 0) {
@@ -1649,6 +1662,7 @@ automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *g
"a \"%s\" value to group \"%s\" (%s).\n",
member_value, grouping_attr, group_dn,
ldap_err2string(result));
+ rc = result;
}
} else {
slapi_log_error(SLAPI_LOG_FATAL, AUTOMEMBER_PLUGIN_SUBSYSTEM,
@@ -1662,8 +1676,9 @@ out:
if (freeit) {
slapi_ch_free_string(&member_value);
}
-
slapi_pblock_destroy(mod_pb);
+
+ return rc;
}
@@ -1833,6 +1848,7 @@ automember_add_post_op(Slapi_PBlock *pb)
Slapi_DN *sdn = NULL;
struct configEntry *config = NULL;
PRCList *list = NULL;
+ int rc = SLAPI_PLUGIN_SUCCESS;
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_add_post_op\n");
@@ -1848,8 +1864,9 @@ automember_add_post_op(Slapi_PBlock *pb)
}
} else {
slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
- "automember_add_post_op: Error "
- "retrieving dn\n");
+ "automember_add_post_op: Error retrieving dn\n");
+
+ rc = SLAPI_PLUGIN_FAILURE;
goto bail;
}
@@ -1863,12 +1880,11 @@ automember_add_post_op(Slapi_PBlock *pb)
if (e) {
/* If the entry is a tombstone, just bail. */
- Slapi_Value *tombstone =
- slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
- int rc = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
- tombstone);
+ Slapi_Value *tombstone = slapi_value_new_string(SLAPI_ATTR_VALUE_TOMBSTONE);
+ int is_tombstone = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS,
+ tombstone);
slapi_value_free(&tombstone);
- if (rc) {
+ if (is_tombstone) {
return SLAPI_PLUGIN_SUCCESS;
}
@@ -1891,7 +1907,10 @@ automember_add_post_op(Slapi_PBlock *pb)
if (slapi_dn_issuffix(slapi_sdn_get_dn(sdn), config->scope) &&
(slapi_filter_test_simple(e, config->filter) == 0)) {
/* Find out what membership changes are needed and make them. */
- automember_update_membership(config, e, NULL);
+ if(automember_update_membership(config, e, NULL)){
+ rc = SLAPI_PLUGIN_FAILURE;
+ break;
+ }
}
list = PR_NEXT_LINK(list);
@@ -1904,11 +1923,21 @@ automember_add_post_op(Slapi_PBlock *pb)
"automember_add_post_op: Error "
"retrieving post-op entry %s\n", slapi_sdn_get_dn(sdn));
}
+
bail:
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
- "<-- automember_add_post_op\n");
+ "<-- automember_add_post_op (%d)\n", rc);
- return SLAPI_PLUGIN_SUCCESS;
+ if(rc){
+ char errtxt[SLAPI_DSE_RETURNTEXT_SIZE];
+ int result = LDAP_UNWILLING_TO_PERFORM;
+
+ PR_snprintf(errtxt, SLAPI_DSE_RETURNTEXT_SIZE, "Automember Plugin update unexpectedly failed.\n");
+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, &errtxt);
+ }
+
+ return rc;
}
/*
@@ -2216,7 +2245,11 @@ void automember_rebuild_task_thread(void *arg){
if (slapi_dn_issuffix(slapi_entry_get_dn(entries[i]), config->scope) &&
(slapi_filter_test_simple(entries[i], config->filter) == 0))
{
- automember_update_membership(config, entries[i], NULL);
+ if(automember_update_membership(config, entries[i], NULL)){
+ result = SLAPI_PLUGIN_FAILURE;
+ automember_config_unlock();
+ goto out;
+ }
}
list = PR_NEXT_LINK(list);
}
@@ -2417,7 +2450,7 @@ void automember_export_task_thread(void *arg){
/* make sure the plugin is still up, as this loop could run for awhile */
if (!g_plugin_started) {
automember_config_unlock();
- result = -1;
+ result = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if (!PR_CLIST_IS_EMPTY(g_automember_config)) {
@@ -2427,7 +2460,11 @@ void automember_export_task_thread(void *arg){
if (slapi_dn_issuffix(slapi_sdn_get_dn(td->base_dn), config->scope) &&
(slapi_filter_test_simple(entries[i], config->filter) == 0))
{
- automember_update_membership(config, entries[i], ldif_fd);
+ if(automember_update_membership(config, entries[i], ldif_fd)){
+ result = SLAPI_DSE_CALLBACK_ERROR;
+ automember_config_unlock();
+ goto out;
+ }
}
list = PR_NEXT_LINK(list);
}
@@ -2627,7 +2664,13 @@ void automember_map_task_thread(void *arg){
if (slapi_dn_issuffix(slapi_entry_get_dn_const(e), config->scope) &&
(slapi_filter_test_simple(e, config->filter) == 0))
{
- automember_update_membership(config, e, ldif_fd_out);
+ if(automember_update_membership(config, e, ldif_fd_out)){
+ result = SLAPI_DSE_CALLBACK_ERROR;
+ slapi_entry_free(e);
+ slapi_ch_free_string(&entrystr);
+ automember_config_unlock();
+ goto out;
+ }
}
list = PR_NEXT_LINK(list);
}
@@ -2638,7 +2681,7 @@ void automember_map_task_thread(void *arg){
slapi_task_log_notice(task, "Automember map task, skipping invalid entry.");
slapi_task_log_status(task, "Automember map task, skipping invalid entry.");
}
- slapi_ch_free((void **)&entrystr);
+ slapi_ch_free_string(&entrystr);
}
automember_config_unlock();
@@ -2671,6 +2714,7 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
Slapi_DN *new_sdn = NULL;
struct configEntry *config = NULL;
PRCList *list = NULL;
+ int rc = SLAPI_PLUGIN_SUCCESS;
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"--> automember_modrdn_post_op\n");
@@ -2691,7 +2735,7 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"automember_modrdn_post_op: Error "
"retrieving post-op entry\n");
- return SLAPI_PLUGIN_SUCCESS;
+ return SLAPI_PLUGIN_FAILURE;
}
if ((old_sdn = automember_get_sdn(pb))) {
@@ -2702,7 +2746,7 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
slapi_log_error(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
"automember_modrdn_post_op: Error "
"retrieving dn\n");
- return SLAPI_PLUGIN_SUCCESS;
+ return SLAPI_PLUGIN_FAILURE;
}
/* If replication, just bail. */
@@ -2730,7 +2774,10 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
if (slapi_dn_issuffix(slapi_sdn_get_dn(new_sdn), config->scope) &&
(slapi_filter_test_simple(post_e, config->filter) == 0)) {
/* Find out what membership changes are needed and make them. */
- automember_update_membership(config, post_e, NULL);
+ if(automember_update_membership(config, post_e, NULL)){
+ rc = SLAPI_PLUGIN_FAILURE;
+ break;
+ }
}
list = PR_NEXT_LINK(list);
@@ -2739,9 +2786,19 @@ automember_modrdn_post_op(Slapi_PBlock *pb)
automember_config_unlock();
+ if(rc){
+ char errtxt[SLAPI_DSE_RETURNTEXT_SIZE];
+ int result = LDAP_UNWILLING_TO_PERFORM;
+
+ PR_snprintf(errtxt, SLAPI_DSE_RETURNTEXT_SIZE, "Automember Plugin update unexpectedly failed. "
+ "Please see the server errors log for more information.\n");
+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &result);
+ slapi_pblock_set(pb, SLAPI_PB_RESULT_TEXT, &errtxt);
+ }
+
slapi_log_error(SLAPI_LOG_TRACE, AUTOMEMBER_PLUGIN_SUBSYSTEM,
- "<-- automember_modrdn_post_op\n");
+ "<-- automember_modrdn_post_op (%d)\n", rc);
- return SLAPI_PLUGIN_SUCCESS;
+ return rc;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
index dbcc914..7834b40 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
@@ -357,7 +357,7 @@ ldbm_back_add( Slapi_PBlock *pb )
/* make sure opreturn is set for the postop plugins */
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &rc);
}
-
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
/*
@@ -795,6 +795,7 @@ ldbm_back_add( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
@@ -1046,6 +1047,7 @@ ldbm_back_add( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
index 42e26de..ce2a154 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
@@ -325,6 +325,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &rc );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
/* the flag could be set in a preop plugin (e.g., USN) */
@@ -354,6 +355,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
ldap_result_code ?
&ldap_result_code : &retval );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
@@ -603,6 +605,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
ldap_result_code ?
&ldap_result_code : &retval );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
}
@@ -633,6 +636,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
&ldap_result_code : &rc );
}
/* retval is -1 */
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
slapi_pblock_set( pb, SLAPI_DELETE_BEPREOP_ENTRY, orig_entry );
@@ -1105,6 +1109,7 @@ ldbm_back_delete( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, &retval );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
index def314e..92692f0 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
@@ -623,6 +623,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
@@ -793,6 +794,7 @@ ldbm_back_modify( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval);
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index fc66ae6..09f1cea 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -466,6 +466,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &rc );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
/*
@@ -890,6 +891,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
@@ -1130,6 +1132,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
if (!opreturn) {
slapi_pblock_set( pb, SLAPI_PLUGIN_OPRETURN, ldap_result_code ? &ldap_result_code : &retval );
}
+ slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
goto error_return;
}
diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c
index 66b011b..de9c01b 100644
--- a/ldap/servers/slapd/plugin.c
+++ b/ldap/servers/slapd/plugin.c
@@ -1476,7 +1476,8 @@ plugin_call_func (struct slapdplugin *list, int operation, Slapi_PBlock *pb, int
}
else if (SLAPI_PLUGIN_BEPREOPERATION == list->plg_type ||
SLAPI_PLUGIN_BETXNPREOPERATION == list->plg_type ||
- SLAPI_PLUGIN_BEPOSTOPERATION == list->plg_type)
+ SLAPI_PLUGIN_BEPOSTOPERATION == list->plg_type ||
+ SLAPI_PLUGIN_BETXNPOSTOPERATION == list->plg_type )
{
/*
* respect fatal error SLAPI_PLUGIN_FAILURE (-1);
10 years, 4 months
ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/pagedresults.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 98ccb602058270e97a3702ae2b81c17635af8d27
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Dec 9 17:00:32 2013 -0700
Ticket #47623 fix memleak caused by 47347
https://fedorahosted.org/389/ticket/47623
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Only need to create the mutex when creating a new PR object.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 78bd6b0..a835d6b 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -122,6 +122,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
sizeof(PagedResults) * maxlen);
}
*index = maxlen; /* the first position in the new area */
+ conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
@@ -131,7 +132,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
}
conn->c_pagedresults.prl_count++;
- conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
/* Repeated paged results request.
* PagedResults is already allocated. */
10 years, 4 months
Branch '389-ds-base-1.3.0' - ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/pagedresults.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 8968e078caacf1021a11c19546c448a4b65db098
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Dec 9 17:00:32 2013 -0700
Ticket #47623 fix memleak caused by 47347
https://fedorahosted.org/389/ticket/47623
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.0
Fix Description: Only need to create the mutex when creating a new PR object.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 98ccb602058270e97a3702ae2b81c17635af8d27)
(cherry picked from commit 65c51555c0ecc94c5d93f09124168697ba1db6b3)
(cherry picked from commit 8a2c666df491b7c8666f8a70a5038b35c43fbc3b)
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 78bd6b0..a835d6b 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -122,6 +122,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
sizeof(PagedResults) * maxlen);
}
*index = maxlen; /* the first position in the new area */
+ conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
@@ -131,7 +132,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
}
conn->c_pagedresults.prl_count++;
- conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
/* Repeated paged results request.
* PagedResults is already allocated. */
10 years, 4 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/pagedresults.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 65c51555c0ecc94c5d93f09124168697ba1db6b3
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Dec 9 17:00:32 2013 -0700
Ticket #47623 fix memleak caused by 47347
https://fedorahosted.org/389/ticket/47623
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.2
Fix Description: Only need to create the mutex when creating a new PR object.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 98ccb602058270e97a3702ae2b81c17635af8d27)
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 78bd6b0..a835d6b 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -122,6 +122,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
sizeof(PagedResults) * maxlen);
}
*index = maxlen; /* the first position in the new area */
+ conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
@@ -131,7 +132,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
}
conn->c_pagedresults.prl_count++;
- conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
/* Repeated paged results request.
* PagedResults is already allocated. */
10 years, 4 months
Branch '389-ds-base-1.2.11' - ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/pagedresults.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 1ad3604b8bfbd5c2a3c4ca8f55b8690a2098f3df
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Dec 9 17:00:32 2013 -0700
Ticket #47623 fix memleak caused by 47347
https://fedorahosted.org/389/ticket/47623
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.2.11
Fix Description: Only need to create the mutex when creating a new PR object.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 98ccb602058270e97a3702ae2b81c17635af8d27)
(cherry picked from commit 65c51555c0ecc94c5d93f09124168697ba1db6b3)
(cherry picked from commit 8a2c666df491b7c8666f8a70a5038b35c43fbc3b)
(cherry picked from commit 8968e078caacf1021a11c19546c448a4b65db098)
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 78bd6b0..a835d6b 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -122,6 +122,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
sizeof(PagedResults) * maxlen);
}
*index = maxlen; /* the first position in the new area */
+ conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
@@ -131,7 +132,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
}
conn->c_pagedresults.prl_count++;
- conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
/* Repeated paged results request.
* PagedResults is already allocated. */
10 years, 4 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Richard Allen Megginson
ldap/servers/slapd/pagedresults.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 8a2c666df491b7c8666f8a70a5038b35c43fbc3b
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Mon Dec 9 17:00:32 2013 -0700
Ticket #47623 fix memleak caused by 47347
https://fedorahosted.org/389/ticket/47623
Reviewed by: nhosoi (Thanks!)
Branch: 389-ds-base-1.3.1
Fix Description: Only need to create the mutex when creating a new PR object.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 98ccb602058270e97a3702ae2b81c17635af8d27)
(cherry picked from commit 65c51555c0ecc94c5d93f09124168697ba1db6b3)
diff --git a/ldap/servers/slapd/pagedresults.c b/ldap/servers/slapd/pagedresults.c
index 78bd6b0..a835d6b 100644
--- a/ldap/servers/slapd/pagedresults.c
+++ b/ldap/servers/slapd/pagedresults.c
@@ -122,6 +122,7 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
sizeof(PagedResults) * maxlen);
}
*index = maxlen; /* the first position in the new area */
+ conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
for (i = 0; i < conn->c_pagedresults.prl_maxlen; i++) {
if (!conn->c_pagedresults.prl_list[i].pr_current_be) {
@@ -131,7 +132,6 @@ pagedresults_parse_control_value( Slapi_PBlock *pb,
}
}
conn->c_pagedresults.prl_count++;
- conn->c_pagedresults.prl_list[*index].pr_mutex = PR_NewLock();
} else {
/* Repeated paged results request.
* PagedResults is already allocated. */
10 years, 4 months
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/ssl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 4ae764558fba2b175d71f319e39ddc83dcd20ea1
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Dec 9 09:38:48 2013 -0800
Ticket #605 - support TLS 1.1 - Fixing "Coverity 12415 - Logically dead code"
Description: The return value from SSL_VersionRangeSet was not assigned
to "sslStatus" which was used to evaluate the API worked correctly or not.
https://fedorahosted.org/389/ticket/605
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index addf6b1..48c3fe9 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -1590,7 +1590,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
myNSSVersions.min = NSSVersionMin;
myNSSVersions.max = NSSVersionMax;
restrict_SSLVersionRange(&myNSSVersions, enableSSL3, enableTLS1);
- SSL_VersionRangeSet(pr_sock, &myNSSVersions);
+ sslStatus = SSL_VersionRangeSet(pr_sock, &myNSSVersions);
if (sslStatus == SECSuccess) {
/* Set the restricted value to the cn=encryption entry */
} else {
10 years, 4 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5.h | 12 ++-
ldap/servers/plugins/replication/repl5_agmt.c | 54 ++++++++++++----
ldap/servers/plugins/replication/repl5_agmtlist.c | 27 ++++++--
ldap/servers/plugins/replication/repl5_inc_protocol.c | 23 +++++-
ldap/servers/plugins/replication/repl5_prot_private.h | 1
ldap/servers/plugins/replication/repl5_protocol.c | 13 +--
ldap/servers/plugins/replication/repl5_replica.c | 54 ++++++++++------
ldap/servers/plugins/replication/repl5_replica_config.c | 25 +++++++
ldap/servers/plugins/replication/repl5_tot_protocol.c | 17 ++++-
9 files changed, 169 insertions(+), 57 deletions(-)
New commits:
commit 490360fd96121d06fa8813e182b44d045257be98
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 6 16:57:41 2013 -0500
Ticket 47620 - 389-ds rejects nsds5ReplicaProtocolTimeout attribute
Bug Description: Attempting to add/modify/delete nsds5ReplicaProtocolTimeout
results in an error 53 (unwilling to perform).
Fix Description: Allow nsds5ReplicaProtocolTimeout to be updated in agreements
and the replica configuration. Also, made the config timeout
setting dynamic.
https://fedorahosted.org/389/ticket/47620
Reviewed by: rmeggins(Thanks!)
(cherry picked from commit 58fca2c4e4f2120cb6e5fb249008be8f551e944c)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 92a9229..321a285 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -386,9 +386,15 @@ char **agmt_get_attrs_to_strip(Repl_Agmt *ra);
int agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e);
int agmt_set_timeout(Repl_Agmt *ra, long timeout);
void agmt_update_done(Repl_Agmt *ra, int is_total);
-int agmt_get_protocol_timeout(Repl_Agmt *agmt);
typedef struct replica Replica;
+PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt);
+void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout);
+void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn);
+void add_agmt_maxcsns(Slapi_Entry *e, Replica *r);
+void agmt_set_maxcsn(Repl_Agmt *ra);
+void agmt_remove_maxcsn(Repl_Agmt *ra);
+int agmt_maxcsn_to_smod (Replica *r, Slapi_Mod *smod);
/* In repl5_agmtlist.c */
int agmtlist_config_init();
@@ -494,7 +500,6 @@ void prot_notify_window_opened (Repl_Protocol *rp);
void prot_notify_window_closed (Repl_Protocol *rp);
Object *prot_get_replica_object(Repl_Protocol *rp);
void prot_replicate_now(Repl_Protocol *rp);
-int prot_get_timeout(Repl_Protocol *rp);
Repl_Protocol *agmt_get_protocol(Repl_Agmt *ra);
@@ -591,7 +596,8 @@ char *replica_get_dn(Replica *r);
void replica_check_for_tasks(Replica*r, Slapi_Entry *e);
void replica_update_state (time_t when, void *arg);
void replica_reset_csn_pl(Replica *r);
-int replica_get_protocol_timeout(Replica *r);
+PRUint64 replica_get_protocol_timeout(Replica *r);
+void replica_set_protocol_timeout(Replica *r, PRUint64 timeout);
int replica_get_backoff_min(Replica *r);
int replica_get_backoff_max(Replica *r);
void replica_set_backoff_min(Replica *r, int min);
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 90d94f8..b0da172 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -142,7 +142,9 @@ typedef struct repl5agmt {
char **attrs_to_strip; /* for fractional replication, if a "mod" is empty, strip out these attributes:
* modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */
int agreement_type;
- PRUint64 protocol_timeout;
+ Slapi_Counter *protocol_timeout;
+ char *maxcsn; /* agmt max csn */
+ Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */
} repl5agmt;
/* Forward declarations */
@@ -265,6 +267,14 @@ agmt_new_from_entry(Slapi_Entry *e)
slapi_entry_get_dn_const(e));
goto loser;
}
+ if ((ra->attr_lock = slapi_new_rwlock()) == NULL)
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Unable to create new attr lock "
+ "for replication agreement \"%s\" - agreement ignored.\n",
+ slapi_entry_get_dn_const(e));
+ goto loser;
+ }
+ ra->protocol_timeout = slapi_counter_new();
/* Find all the stuff we need for the agreement */
@@ -338,19 +348,14 @@ agmt_new_from_entry(Slapi_Entry *e)
tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaRoot);
if (NULL != tmpstr)
{
+ PRUint64 ptimeout = 0;
+
ra->replarea = slapi_sdn_new_dn_passin(tmpstr);
/* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */
- ra->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
- if(ra->protocol_timeout == 0){
- /* grab the replica protocol timeout */
- Object *replobj = replica_get_replica_from_dn(ra->replarea);
- if(replobj){
- Replica *replica =(Replica*)object_get_data (replobj);
- ra->protocol_timeout = replica_get_protocol_timeout(replica);
- } else {
- ra->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
- }
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
+ if(ptimeout){
+ slapi_counter_set_value(ra->protocol_timeout, ptimeout);
}
}
@@ -613,6 +618,17 @@ agmt_delete(void **rap)
if(ra->attrs_to_strip){
slapi_ch_array_free(ra->attrs_to_strip);
}
+ if(ra->maxcsn){
+ slapi_ch_free_string(&ra->maxcsn);
+ }
+ schedule_destroy(ra->schedule);
+ slapi_ch_free_string(&ra->long_name);
+
+ slapi_counter_destroy(&ra->protocol_timeout);
+
+ /* free the locks */
+ PR_DestroyLock(ra->lock);
+ slapi_destroy_rwlock(ra->attr_lock);
schedule_destroy(ra->schedule);
slapi_ch_free((void **)&ra->long_name);
@@ -2663,9 +2679,21 @@ agmt_update_done(Repl_Agmt *agmt, int is_total)
windows_update_done(agmt, is_total);
}
-int
+PRUint64
agmt_get_protocol_timeout(Repl_Agmt *agmt)
{
- return (int)agmt->protocol_timeout;
+ if(agmt){
+ return slapi_counter_get_value(agmt->protocol_timeout);
+ } else {
+ return 0;
+ }
+}
+
+void
+agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout)
+{
+ if(agmt){
+ slapi_counter_set_value(agmt->protocol_timeout, timeout);
+ }
}
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index 1167b0c..04891b7 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -209,6 +209,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
LDAPMod **mods;
char buff [SLAPI_DSE_RETURNTEXT_SIZE];
char *errortext = returntext ? returntext : buff;
+ char *val = NULL;
int rc = SLAPI_DSE_CALLBACK_OK;
Slapi_Operation *op;
void *identity;
@@ -243,16 +244,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
for (i = 0; NULL != mods && NULL != mods[i]; i++)
{
+ slapi_ch_free_string(&val);
if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaInitialize))
{
/* we don't allow delete attribute operations unless it was issued by
the replication plugin - handled above */
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
- if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0){
+ if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0 ){
/* allow the deletion of cleanallruv agmt attr */
continue;
}
+ if(strcasecmp (mods[i]->mod_type, type_replicaProtocolTimeout) == 0){
+ agmt_set_protocol_timeout(agmt, 0);
+ continue;
+ }
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
"deletion of %s attribute is not allowed\n", type_nsds5ReplicaInitialize);
@@ -262,8 +268,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
}
else
{
- char *val;
-
if (mods[i]->mod_bvalues && mods[i]->mod_bvalues[0])
val = slapi_berval_get_string_copy (mods[i]->mod_bvalues[0]);
else
@@ -304,7 +308,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
val, mods[i]->mod_type);
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: %s\n", errortext);
}
- slapi_ch_free ((void**)&val);
}
}
else if (slapi_attr_types_equivalent(mods[i]->mod_type,
@@ -511,6 +514,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
rc = SLAPI_DSE_CALLBACK_ERROR;
}
}
+ else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_replicaProtocolTimeout)){
+ if (val){
+ long ptimeout = atol(val);
+
+ if(ptimeout <= 0){
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "attribute %s value (%s) is invalid, "
+ "must be a number greater than zero.\n",
+ type_replicaProtocolTimeout, val);
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ break;
+ }
+ agmt_set_protocol_timeout(agmt, ptimeout);
+ }
+ }
else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e))
{
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
@@ -561,6 +579,7 @@ done:
{
agmtlist_release_agmt(agmt);
}
+ slapi_ch_free_string(&val);
return rc;
}
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 612fe46..05074b0 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -1921,10 +1921,24 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
static int
repl5_inc_stop(Private_Repl_Protocol *prp)
{
- int return_value;
PRIntervalTime start, maxwait, now;
+ Replica *replica = NULL;
+ PRUint64 timeout;
+ int return_value;
+
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ if(prp->replica_object){
+ object_acquire(prp->replica_object);
+ replica = object_get_data(prp->replica_object);
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ }
+ object_release(prp->replica_object);
+ }
+ }
- maxwait = PR_SecondsToInterval(prp->timeout);
+ maxwait = PR_SecondsToInterval(timeout);
prp->terminate = 1;
event_notify(prp, EVENT_PROTOCOL_SHUTDOWN);
start = PR_IntervalNow();
@@ -1939,8 +1953,8 @@ repl5_inc_stop(Private_Repl_Protocol *prp)
/* Isn't listening. Do something drastic. */
return_value = -1;
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "%s: repl5_inc_stop: protocol does not stop after %d seconds\n",
- agmt_get_long_name(prp->agmt), (int)prp->timeout);
+ "%s: repl5_inc_stop: protocol does not stop after %llu seconds\n",
+ agmt_get_long_name(prp->agmt), (long long unsigned int)timeout);
}
else
{
@@ -2044,7 +2058,6 @@ Repl_5_Inc_Protocol_new(Repl_Protocol *rp)
prp->notify_window_closed = repl5_inc_notify_window_closed;
prp->update_now = repl5_inc_update_now;
prp->replica_object = prot_get_replica_object(rp);
- prp->timeout = prot_get_timeout(rp);
if ((prp->lock = PR_NewLock()) == NULL)
{
goto loser;
diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h
index 37072ee..586e1eb 100644
--- a/ldap/servers/plugins/replication/repl5_prot_private.h
+++ b/ldap/servers/plugins/replication/repl5_prot_private.h
@@ -75,7 +75,6 @@ typedef struct private_repl_protocol
int repl50consumer; /* Flag to tell us if this is a 5.0-style consumer we're talking to */
int repl71consumer; /* Flag to tell us if this is a 7.1-style consumer we're talking to */
int repl90consumer; /* Flag to tell us if this is a 9.0-style consumer we're talking to */
- PRUint64 timeout;
} Private_Repl_Protocol;
extern Private_Repl_Protocol *Repl_5_Inc_Protocol_new();
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index 34fe8a0..0e9668d 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -71,8 +71,7 @@ typedef struct repl_protocol
Object *replica_object; /* Local replica. If non-NULL, replica object is acquired */
int state;
int next_state;
- PRUint64 protocol_timeout;
- PRThread *agmt_thread;
+ PRThread *agmt_thread;
PRLock *lock;
} repl_protocol;
@@ -134,16 +133,17 @@ prot_new(Repl_Agmt *agmt, int protocol_state)
rp->prp_total = private_protocol_factory(rp, PROTOCOL_WINDOWS_TOTAL);
rp->delete_conn = windows_conn_delete;
}
- rp->protocol_timeout = agmt_get_protocol_timeout(agmt);
-
/* XXXggood register callback handlers for entries updated, and
schedule window enter/leave. */
goto done;
+
loser:
prot_delete(&rp);
+
done:
slapi_sdn_free(&replarea_sdn);
+
return rp;
}
@@ -593,8 +593,3 @@ private_protocol_factory(Repl_Protocol *rp, int type)
return prp;
}
-int
-prot_get_timeout(Repl_Protocol *rp)
-{
- return (int)rp->protocol_timeout;
-}
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 8a1c590..02d4e74 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -87,7 +87,7 @@ struct replica {
PRBool state_update_inprogress; /* replica state is being updated */
PRLock *agmt_lock; /* protects agreement creation, start and stop */
char *locking_purl; /* supplier who has exclusive access */
- PRUint64 protocol_timeout; /* protocol shutdown timeout */
+ Slapi_Counter *protocol_timeout; /* protocol shutdown timeout */
PRUint64 backoff_min; /* backoff retry minimum */
PRUint64 backoff_max; /* backoff retry maximum */
};
@@ -164,26 +164,26 @@ replica_new(const Slapi_DN *root)
Replica *
replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation)
{
- int rc = 0;
- Replica *r;
+ int rc = 0;
+ Replica *r;
char *repl_name = NULL;
- if (e == NULL)
- {
- if (NULL != errortext)
+ if (e == NULL)
+ {
+ if (NULL != errortext)
{
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
}
- return NULL;
- }
+ return NULL;
+ }
- r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
+ r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
- if (!r)
+ if (!r)
{
- if (NULL != errortext)
+ if (NULL != errortext)
{
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
}
rc = -1;
goto done;
@@ -208,6 +208,7 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
rc = -1;
goto done;
}
+ r->protocol_timeout = slapi_counter_new();
/* read parameters from the replica config entry */
rc = _replica_init_from_config (r, e, errortext);
@@ -403,6 +404,8 @@ replica_destroy(void **arg)
csnplFree(&r->min_csn_pl);;
}
+ slapi_counter_destroy(&r->protocol_timeout);
+
slapi_ch_free((void **)arg);
}
@@ -796,10 +799,22 @@ replica_get_type (const Replica *r)
return r->repl_type;
}
-int
+PRUint64
replica_get_protocol_timeout(Replica *r)
{
- return (int)r->protocol_timeout;
+ if(r){
+ return slapi_counter_get_value(r->protocol_timeout);
+ } else {
+ return 0;
+ }
+}
+
+void
+replica_set_protocol_timeout(Replica *r, PRUint64 timeout)
+{
+ if(r){
+ slapi_counter_set_value(r->protocol_timeout, timeout);
+ }
}
/*
@@ -1659,6 +1674,7 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
char *val;
int backoff_min;
int backoff_max;
+ int ptimeout = 0;
int rc;
PR_ASSERT (r && e);
@@ -1731,9 +1747,11 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
}
/* get the protocol timeout */
- r->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
- if(r->protocol_timeout == 0){
- r->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
+ if(ptimeout <= 0){
+ slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
+ } else {
+ slapi_counter_set_value(r->protocol_timeout, ptimeout);
}
/* get replica flags */
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index f9133a8..380ea4e 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -396,9 +396,16 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
else if (strcasecmp (config_attr, type_replicaCleanRUV) == 0 ||
strcasecmp (config_attr, type_replicaAbortCleanRUV) == 0)
{
- /* only allow the deletion of the cleanAllRUV config attributes */
+ /*
+ * Only allow the deletion of the cleanAllRUV config attributes, and the
+ * protocol timeout.
+ */
continue;
}
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 )
+ {
+ replica_set_protocol_timeout(r, DEFAULT_PROTOCOL_TIMEOUT);
+ }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
@@ -487,6 +494,22 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
{
*returncode = LDAP_SUCCESS;
}
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 ){
+ if (apply_mods && config_attr_value && config_attr_value[0])
+ {
+ long ptimeout = atol(config_attr_value);
+
+ if(ptimeout <= 0){
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE,
+ "attribute %s value (%s) is invalid, must be a number greater than zero.\n",
+ config_attr, config_attr_value);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n", errortext);
+ } else {
+ replica_set_protocol_timeout(r, ptimeout);
+ }
+ }
+ }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index 5bb203a..a241128 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -505,11 +505,22 @@ static int
repl5_tot_stop(Private_Repl_Protocol *prp)
{
int return_value;
- int seconds = 600;
PRIntervalTime start, maxwait, now;
+ PRUint64 timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ Replica *replica = NULL;
+
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ if(prp->replica_object){
+ replica = object_get_data(prp->replica_object);
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ }
+ }
+ }
prp->terminate = 1;
- maxwait = PR_SecondsToInterval(seconds);
+ maxwait = PR_SecondsToInterval(timeout);
start = PR_IntervalNow();
now = start;
while (!prp->stopped && ((now - start) < maxwait))
@@ -567,7 +578,6 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
prp->notify_window_opened = repl5_tot_noop;
prp->notify_window_closed = repl5_tot_noop;
prp->update_now = repl5_tot_noop;
- prp->timeout = DEFAULT_PROTOCOL_TIMEOUT;
if ((prp->lock = PR_NewLock()) == NULL)
{
goto loser;
@@ -588,6 +598,7 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
prp->repl50consumer = 0;
prp->repl71consumer = 0;
prp->repl90consumer = 0;
+ prp->replica_object = prot_get_replica_object(rp);
return prp;
loser:
repl5_tot_delete(&prp);
10 years, 4 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5.h | 12 ++-
ldap/servers/plugins/replication/repl5_agmt.c | 54 ++++++++++++----
ldap/servers/plugins/replication/repl5_agmtlist.c | 27 ++++++--
ldap/servers/plugins/replication/repl5_inc_protocol.c | 23 +++++-
ldap/servers/plugins/replication/repl5_prot_private.h | 1
ldap/servers/plugins/replication/repl5_protocol.c | 13 +--
ldap/servers/plugins/replication/repl5_replica.c | 54 ++++++++++------
ldap/servers/plugins/replication/repl5_replica_config.c | 25 +++++++
ldap/servers/plugins/replication/repl5_tot_protocol.c | 17 ++++-
9 files changed, 169 insertions(+), 57 deletions(-)
New commits:
commit 58fca2c4e4f2120cb6e5fb249008be8f551e944c
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 6 16:57:41 2013 -0500
Ticket 47620 - 389-ds rejects nsds5ReplicaProtocolTimeout attribute
Bug Description: Attempting to add/modify/delete nsds5ReplicaProtocolTimeout
results in an error 53 (unwilling to perform).
Fix Description: Allow nsds5ReplicaProtocolTimeout to be updated in agreements
and the replica configuration. Also, made the config timeout
setting dynamic.
https://fedorahosted.org/389/ticket/47620
Reviewed by: rmeggins(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 819abd9..988feca 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -390,9 +390,15 @@ char **agmt_get_attrs_to_strip(Repl_Agmt *ra);
int agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e);
int agmt_set_timeout(Repl_Agmt *ra, long timeout);
void agmt_update_done(Repl_Agmt *ra, int is_total);
-int agmt_get_protocol_timeout(Repl_Agmt *agmt);
typedef struct replica Replica;
+PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt);
+void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout);
+void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn);
+void add_agmt_maxcsns(Slapi_Entry *e, Replica *r);
+void agmt_set_maxcsn(Repl_Agmt *ra);
+void agmt_remove_maxcsn(Repl_Agmt *ra);
+int agmt_maxcsn_to_smod (Replica *r, Slapi_Mod *smod);
/* In repl5_agmtlist.c */
int agmtlist_config_init();
@@ -498,7 +504,6 @@ void prot_notify_window_opened (Repl_Protocol *rp);
void prot_notify_window_closed (Repl_Protocol *rp);
Object *prot_get_replica_object(Repl_Protocol *rp);
void prot_replicate_now(Repl_Protocol *rp);
-int prot_get_timeout(Repl_Protocol *rp);
Repl_Protocol *agmt_get_protocol(Repl_Agmt *ra);
@@ -596,7 +601,8 @@ char *replica_get_dn(Replica *r);
void replica_check_for_tasks(Replica*r, Slapi_Entry *e);
void replica_update_state (time_t when, void *arg);
void replica_reset_csn_pl(Replica *r);
-int replica_get_protocol_timeout(Replica *r);
+PRUint64 replica_get_protocol_timeout(Replica *r);
+void replica_set_protocol_timeout(Replica *r, PRUint64 timeout);
int replica_get_backoff_min(Replica *r);
int replica_get_backoff_max(Replica *r);
void replica_set_backoff_min(Replica *r, int min);
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index afb7f54..5aca5db 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -142,7 +142,9 @@ typedef struct repl5agmt {
char **attrs_to_strip; /* for fractional replication, if a "mod" is empty, strip out these attributes:
* modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */
int agreement_type;
- PRUint64 protocol_timeout;
+ Slapi_Counter *protocol_timeout;
+ char *maxcsn; /* agmt max csn */
+ Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */
} repl5agmt;
/* Forward declarations */
@@ -265,6 +267,14 @@ agmt_new_from_entry(Slapi_Entry *e)
slapi_entry_get_dn_const(e));
goto loser;
}
+ if ((ra->attr_lock = slapi_new_rwlock()) == NULL)
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Unable to create new attr lock "
+ "for replication agreement \"%s\" - agreement ignored.\n",
+ slapi_entry_get_dn_const(e));
+ goto loser;
+ }
+ ra->protocol_timeout = slapi_counter_new();
/* Find all the stuff we need for the agreement */
@@ -338,19 +348,14 @@ agmt_new_from_entry(Slapi_Entry *e)
tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaRoot);
if (NULL != tmpstr)
{
+ PRUint64 ptimeout = 0;
+
ra->replarea = slapi_sdn_new_dn_passin(tmpstr);
/* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */
- ra->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
- if(ra->protocol_timeout == 0){
- /* grab the replica protocol timeout */
- Object *replobj = replica_get_replica_from_dn(ra->replarea);
- if(replobj){
- Replica *replica =(Replica*)object_get_data (replobj);
- ra->protocol_timeout = replica_get_protocol_timeout(replica);
- } else {
- ra->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
- }
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
+ if(ptimeout){
+ slapi_counter_set_value(ra->protocol_timeout, ptimeout);
}
}
@@ -613,6 +618,17 @@ agmt_delete(void **rap)
if(ra->attrs_to_strip){
slapi_ch_array_free(ra->attrs_to_strip);
}
+ if(ra->maxcsn){
+ slapi_ch_free_string(&ra->maxcsn);
+ }
+ schedule_destroy(ra->schedule);
+ slapi_ch_free_string(&ra->long_name);
+
+ slapi_counter_destroy(&ra->protocol_timeout);
+
+ /* free the locks */
+ PR_DestroyLock(ra->lock);
+ slapi_destroy_rwlock(ra->attr_lock);
schedule_destroy(ra->schedule);
slapi_ch_free((void **)&ra->long_name);
@@ -2665,9 +2681,21 @@ agmt_update_done(Repl_Agmt *agmt, int is_total)
}
}
-int
+PRUint64
agmt_get_protocol_timeout(Repl_Agmt *agmt)
{
- return (int)agmt->protocol_timeout;
+ if(agmt){
+ return slapi_counter_get_value(agmt->protocol_timeout);
+ } else {
+ return 0;
+ }
+}
+
+void
+agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout)
+{
+ if(agmt){
+ slapi_counter_set_value(agmt->protocol_timeout, timeout);
+ }
}
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index e4ef66b..6c6b977 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -209,6 +209,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
LDAPMod **mods;
char buff [SLAPI_DSE_RETURNTEXT_SIZE];
char *errortext = returntext ? returntext : buff;
+ char *val = NULL;
int rc = SLAPI_DSE_CALLBACK_OK;
Slapi_Operation *op;
void *identity;
@@ -243,16 +244,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
for (i = 0; NULL != mods && NULL != mods[i]; i++)
{
+ slapi_ch_free_string(&val);
if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaInitialize))
{
/* we don't allow delete attribute operations unless it was issued by
the replication plugin - handled above */
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
- if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0){
+ if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0 ){
/* allow the deletion of cleanallruv agmt attr */
continue;
}
+ if(strcasecmp (mods[i]->mod_type, type_replicaProtocolTimeout) == 0){
+ agmt_set_protocol_timeout(agmt, 0);
+ continue;
+ }
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
"deletion of %s attribute is not allowed\n", type_nsds5ReplicaInitialize);
@@ -262,8 +268,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
}
else
{
- char *val;
-
if (mods[i]->mod_bvalues && mods[i]->mod_bvalues[0])
val = slapi_berval_get_string_copy (mods[i]->mod_bvalues[0]);
else
@@ -307,7 +311,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
*returncode = LDAP_UNWILLING_TO_PERFORM;
rc = SLAPI_DSE_CALLBACK_ERROR;
}
- slapi_ch_free ((void**)&val);
}
}
else if (slapi_attr_types_equivalent(mods[i]->mod_type,
@@ -514,6 +517,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
rc = SLAPI_DSE_CALLBACK_ERROR;
}
}
+ else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_replicaProtocolTimeout)){
+ if (val){
+ long ptimeout = atol(val);
+
+ if(ptimeout <= 0){
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "attribute %s value (%s) is invalid, "
+ "must be a number greater than zero.\n",
+ type_replicaProtocolTimeout, val);
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ break;
+ }
+ agmt_set_protocol_timeout(agmt, ptimeout);
+ }
+ }
else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e))
{
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
@@ -564,6 +582,7 @@ done:
{
agmtlist_release_agmt(agmt);
}
+ slapi_ch_free_string(&val);
return rc;
}
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 612fe46..05074b0 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -1921,10 +1921,24 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
static int
repl5_inc_stop(Private_Repl_Protocol *prp)
{
- int return_value;
PRIntervalTime start, maxwait, now;
+ Replica *replica = NULL;
+ PRUint64 timeout;
+ int return_value;
+
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ if(prp->replica_object){
+ object_acquire(prp->replica_object);
+ replica = object_get_data(prp->replica_object);
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ }
+ object_release(prp->replica_object);
+ }
+ }
- maxwait = PR_SecondsToInterval(prp->timeout);
+ maxwait = PR_SecondsToInterval(timeout);
prp->terminate = 1;
event_notify(prp, EVENT_PROTOCOL_SHUTDOWN);
start = PR_IntervalNow();
@@ -1939,8 +1953,8 @@ repl5_inc_stop(Private_Repl_Protocol *prp)
/* Isn't listening. Do something drastic. */
return_value = -1;
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "%s: repl5_inc_stop: protocol does not stop after %d seconds\n",
- agmt_get_long_name(prp->agmt), (int)prp->timeout);
+ "%s: repl5_inc_stop: protocol does not stop after %llu seconds\n",
+ agmt_get_long_name(prp->agmt), (long long unsigned int)timeout);
}
else
{
@@ -2044,7 +2058,6 @@ Repl_5_Inc_Protocol_new(Repl_Protocol *rp)
prp->notify_window_closed = repl5_inc_notify_window_closed;
prp->update_now = repl5_inc_update_now;
prp->replica_object = prot_get_replica_object(rp);
- prp->timeout = prot_get_timeout(rp);
if ((prp->lock = PR_NewLock()) == NULL)
{
goto loser;
diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h
index 37072ee..586e1eb 100644
--- a/ldap/servers/plugins/replication/repl5_prot_private.h
+++ b/ldap/servers/plugins/replication/repl5_prot_private.h
@@ -75,7 +75,6 @@ typedef struct private_repl_protocol
int repl50consumer; /* Flag to tell us if this is a 5.0-style consumer we're talking to */
int repl71consumer; /* Flag to tell us if this is a 7.1-style consumer we're talking to */
int repl90consumer; /* Flag to tell us if this is a 9.0-style consumer we're talking to */
- PRUint64 timeout;
} Private_Repl_Protocol;
extern Private_Repl_Protocol *Repl_5_Inc_Protocol_new();
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index 34fe8a0..0e9668d 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -71,8 +71,7 @@ typedef struct repl_protocol
Object *replica_object; /* Local replica. If non-NULL, replica object is acquired */
int state;
int next_state;
- PRUint64 protocol_timeout;
- PRThread *agmt_thread;
+ PRThread *agmt_thread;
PRLock *lock;
} repl_protocol;
@@ -134,16 +133,17 @@ prot_new(Repl_Agmt *agmt, int protocol_state)
rp->prp_total = private_protocol_factory(rp, PROTOCOL_WINDOWS_TOTAL);
rp->delete_conn = windows_conn_delete;
}
- rp->protocol_timeout = agmt_get_protocol_timeout(agmt);
-
/* XXXggood register callback handlers for entries updated, and
schedule window enter/leave. */
goto done;
+
loser:
prot_delete(&rp);
+
done:
slapi_sdn_free(&replarea_sdn);
+
return rp;
}
@@ -593,8 +593,3 @@ private_protocol_factory(Repl_Protocol *rp, int type)
return prp;
}
-int
-prot_get_timeout(Repl_Protocol *rp)
-{
- return (int)rp->protocol_timeout;
-}
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index b07a9f9..f509bd4 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -87,7 +87,7 @@ struct replica {
PRBool state_update_inprogress; /* replica state is being updated */
PRLock *agmt_lock; /* protects agreement creation, start and stop */
char *locking_purl; /* supplier who has exclusive access */
- PRUint64 protocol_timeout; /* protocol shutdown timeout */
+ Slapi_Counter *protocol_timeout; /* protocol shutdown timeout */
PRUint64 backoff_min; /* backoff retry minimum */
PRUint64 backoff_max; /* backoff retry maximum */
};
@@ -164,26 +164,26 @@ replica_new(const Slapi_DN *root)
Replica *
replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation)
{
- int rc = 0;
- Replica *r;
+ int rc = 0;
+ Replica *r;
char *repl_name = NULL;
- if (e == NULL)
- {
- if (NULL != errortext)
+ if (e == NULL)
+ {
+ if (NULL != errortext)
{
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
}
- return NULL;
- }
+ return NULL;
+ }
- r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
+ r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
- if (!r)
+ if (!r)
{
- if (NULL != errortext)
+ if (NULL != errortext)
{
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
}
rc = -1;
goto done;
@@ -208,6 +208,7 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
rc = -1;
goto done;
}
+ r->protocol_timeout = slapi_counter_new();
/* read parameters from the replica config entry */
rc = _replica_init_from_config (r, e, errortext);
@@ -403,6 +404,8 @@ replica_destroy(void **arg)
csnplFree(&r->min_csn_pl);;
}
+ slapi_counter_destroy(&r->protocol_timeout);
+
slapi_ch_free((void **)arg);
}
@@ -796,10 +799,22 @@ replica_get_type (const Replica *r)
return r->repl_type;
}
-int
+PRUint64
replica_get_protocol_timeout(Replica *r)
{
- return (int)r->protocol_timeout;
+ if(r){
+ return slapi_counter_get_value(r->protocol_timeout);
+ } else {
+ return 0;
+ }
+}
+
+void
+replica_set_protocol_timeout(Replica *r, PRUint64 timeout)
+{
+ if(r){
+ slapi_counter_set_value(r->protocol_timeout, timeout);
+ }
}
/*
@@ -1689,6 +1704,7 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
char *val;
int backoff_min;
int backoff_max;
+ int ptimeout = 0;
int rc;
PR_ASSERT (r && e);
@@ -1761,9 +1777,11 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
}
/* get the protocol timeout */
- r->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
- if(r->protocol_timeout == 0){
- r->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
+ if(ptimeout <= 0){
+ slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
+ } else {
+ slapi_counter_set_value(r->protocol_timeout, ptimeout);
}
/* get replica flags */
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index a4d9e16..42cf8f6 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -397,9 +397,16 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
else if (strcasecmp (config_attr, type_replicaCleanRUV) == 0 ||
strcasecmp (config_attr, type_replicaAbortCleanRUV) == 0)
{
- /* only allow the deletion of the cleanAllRUV config attributes */
+ /*
+ * Only allow the deletion of the cleanAllRUV config attributes, and the
+ * protocol timeout.
+ */
continue;
}
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 )
+ {
+ replica_set_protocol_timeout(r, DEFAULT_PROTOCOL_TIMEOUT);
+ }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
@@ -488,6 +495,22 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
{
*returncode = LDAP_SUCCESS;
}
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 ){
+ if (apply_mods && config_attr_value && config_attr_value[0])
+ {
+ long ptimeout = atol(config_attr_value);
+
+ if(ptimeout <= 0){
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE,
+ "attribute %s value (%s) is invalid, must be a number greater than zero.\n",
+ config_attr, config_attr_value);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n", errortext);
+ } else {
+ replica_set_protocol_timeout(r, ptimeout);
+ }
+ }
+ }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index 5bb203a..a241128 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -505,11 +505,22 @@ static int
repl5_tot_stop(Private_Repl_Protocol *prp)
{
int return_value;
- int seconds = 600;
PRIntervalTime start, maxwait, now;
+ PRUint64 timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ Replica *replica = NULL;
+
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ if(prp->replica_object){
+ replica = object_get_data(prp->replica_object);
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ }
+ }
+ }
prp->terminate = 1;
- maxwait = PR_SecondsToInterval(seconds);
+ maxwait = PR_SecondsToInterval(timeout);
start = PR_IntervalNow();
now = start;
while (!prp->stopped && ((now - start) < maxwait))
@@ -567,7 +578,6 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
prp->notify_window_opened = repl5_tot_noop;
prp->notify_window_closed = repl5_tot_noop;
prp->update_now = repl5_tot_noop;
- prp->timeout = DEFAULT_PROTOCOL_TIMEOUT;
if ((prp->lock = PR_NewLock()) == NULL)
{
goto loser;
@@ -588,6 +598,7 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
prp->repl50consumer = 0;
prp->repl71consumer = 0;
prp->repl90consumer = 0;
+ prp->replica_object = prot_get_replica_object(rp);
return prp;
loser:
repl5_tot_delete(&prp);
10 years, 4 months
ldap/servers
by Mark Reynolds
ldap/servers/plugins/replication/repl5.h | 7 +-
ldap/servers/plugins/replication/repl5_agmt.c | 35 ++++++----
ldap/servers/plugins/replication/repl5_agmtlist.c | 27 ++++++--
ldap/servers/plugins/replication/repl5_inc_protocol.c | 23 +++++-
ldap/servers/plugins/replication/repl5_prot_private.h | 1
ldap/servers/plugins/replication/repl5_protocol.c | 11 ---
ldap/servers/plugins/replication/repl5_replica.c | 54 ++++++++++------
ldap/servers/plugins/replication/repl5_replica_config.c | 25 +++++++
ldap/servers/plugins/replication/repl5_tot_protocol.c | 17 ++++-
9 files changed, 144 insertions(+), 56 deletions(-)
New commits:
commit 9a0fb6add07c0d753da7e75c44b604ccfb54888a
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 6 16:57:41 2013 -0500
Ticket 47620 - 389-ds rejects nsds5ReplicaProtocolTimeout attribute
Bug Description: Attempting to add/modify/delete nsds5ReplicaProtocolTimeout
results in an error 53 (unwilling to perform).
Fix Description: Allow nsds5ReplicaProtocolTimeout to be updated in agreements
and the replica configuration. Also, made the config timeout
setting dynamic.
https://fedorahosted.org/389/ticket/47620
Reviewed by: rmeggins(Thanks!)
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 9bed558..49d83d5 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -393,7 +393,8 @@ char **agmt_get_attrs_to_strip(Repl_Agmt *ra);
int agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e);
int agmt_set_timeout(Repl_Agmt *ra, long timeout);
void agmt_update_done(Repl_Agmt *ra, int is_total);
-int agmt_get_protocol_timeout(Repl_Agmt *agmt);
+PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt);
+void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout);
void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn);
void add_agmt_maxcsns(Slapi_Entry *e, Replica *r);
void agmt_set_maxcsn(Repl_Agmt *ra);
@@ -504,7 +505,6 @@ void prot_notify_window_opened (Repl_Protocol *rp);
void prot_notify_window_closed (Repl_Protocol *rp);
Object *prot_get_replica_object(Repl_Protocol *rp);
void prot_replicate_now(Repl_Protocol *rp);
-int prot_get_timeout(Repl_Protocol *rp);
Repl_Protocol *agmt_get_protocol(Repl_Agmt *ra);
@@ -602,7 +602,8 @@ char *replica_get_dn(Replica *r);
void replica_check_for_tasks(Replica*r, Slapi_Entry *e);
void replica_update_state (time_t when, void *arg);
void replica_reset_csn_pl(Replica *r);
-int replica_get_protocol_timeout(Replica *r);
+PRUint64 replica_get_protocol_timeout(Replica *r);
+void replica_set_protocol_timeout(Replica *r, PRUint64 timeout);
int replica_get_backoff_min(Replica *r);
int replica_get_backoff_max(Replica *r);
void replica_set_backoff_min(Replica *r, int min);
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index a1f5a8b..4f0fa35 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -143,7 +143,7 @@ typedef struct repl5agmt {
char **attrs_to_strip; /* for fractional replication, if a "mod" is empty, strip out these attributes:
* modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */
int agreement_type;
- PRUint64 protocol_timeout;
+ Slapi_Counter *protocol_timeout;
char *maxcsn; /* agmt max csn */
Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */
} repl5agmt;
@@ -275,6 +275,7 @@ agmt_new_from_entry(Slapi_Entry *e)
slapi_entry_get_dn_const(e));
goto loser;
}
+ ra->protocol_timeout = slapi_counter_new();
/* Find all the stuff we need for the agreement */
@@ -350,6 +351,7 @@ agmt_new_from_entry(Slapi_Entry *e)
{
Object *repl_obj;
Replica *replica;
+ PRUint64 ptimeout = 0;
ra->replarea = slapi_sdn_new_dn_passin(tmpstr);
@@ -361,16 +363,9 @@ agmt_new_from_entry(Slapi_Entry *e)
}
/* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */
- ra->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
- if(ra->protocol_timeout == 0){
- /* grab the replica protocol timeout */
- Object *replobj = replica_get_replica_from_dn(ra->replarea);
- if(replobj){
- Replica *replica =(Replica*)object_get_data (replobj);
- ra->protocol_timeout = replica_get_protocol_timeout(replica);
- } else {
- ra->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
- }
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
+ if(ptimeout){
+ slapi_counter_set_value(ra->protocol_timeout, ptimeout);
}
}
@@ -650,6 +645,8 @@ agmt_delete(void **rap)
schedule_destroy(ra->schedule);
slapi_ch_free_string(&ra->long_name);
+ slapi_counter_destroy(&ra->protocol_timeout);
+
/* free the locks */
PR_DestroyLock(ra->lock);
slapi_destroy_rwlock(ra->attr_lock);
@@ -2707,10 +2704,22 @@ agmt_update_done(Repl_Agmt *agmt, int is_total)
}
}
-int
+PRUint64
agmt_get_protocol_timeout(Repl_Agmt *agmt)
{
- return (int)agmt->protocol_timeout;
+ if(agmt){
+ return slapi_counter_get_value(agmt->protocol_timeout);
+ } else {
+ return 0;
+ }
+}
+
+void
+agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout)
+{
+ if(agmt){
+ slapi_counter_set_value(agmt->protocol_timeout, timeout);
+ }
}
/*
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
index bb2d628..f9b844b 100644
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
@@ -209,6 +209,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
LDAPMod **mods;
char buff [SLAPI_DSE_RETURNTEXT_SIZE];
char *errortext = returntext ? returntext : buff;
+ char *val = NULL;
int rc = SLAPI_DSE_CALLBACK_OK;
Slapi_Operation *op;
void *identity;
@@ -243,16 +244,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
for (i = 0; NULL != mods && NULL != mods[i]; i++)
{
+ slapi_ch_free_string(&val);
if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaInitialize))
{
/* we don't allow delete attribute operations unless it was issued by
the replication plugin - handled above */
if (mods[i]->mod_op & LDAP_MOD_DELETE)
{
- if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0){
+ if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0 ){
/* allow the deletion of cleanallruv agmt attr */
continue;
}
+ if(strcasecmp (mods[i]->mod_type, type_replicaProtocolTimeout) == 0){
+ agmt_set_protocol_timeout(agmt, 0);
+ continue;
+ }
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
"deletion of %s attribute is not allowed\n", type_nsds5ReplicaInitialize);
@@ -262,8 +268,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
}
else
{
- char *val;
-
if (mods[i]->mod_bvalues && mods[i]->mod_bvalues[0])
val = slapi_berval_get_string_copy (mods[i]->mod_bvalues[0]);
else
@@ -307,7 +311,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
*returncode = LDAP_UNWILLING_TO_PERFORM;
rc = SLAPI_DSE_CALLBACK_ERROR;
}
- slapi_ch_free ((void**)&val);
}
}
else if (slapi_attr_types_equivalent(mods[i]->mod_type,
@@ -520,6 +523,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
rc = SLAPI_DSE_CALLBACK_ERROR;
}
}
+ else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_replicaProtocolTimeout)){
+ if (val){
+ long ptimeout = atol(val);
+
+ if(ptimeout <= 0){
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "attribute %s value (%s) is invalid, "
+ "must be a number greater than zero.\n",
+ type_replicaProtocolTimeout, val);
+ rc = SLAPI_DSE_CALLBACK_ERROR;
+ break;
+ }
+ agmt_set_protocol_timeout(agmt, ptimeout);
+ }
+ }
else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e))
{
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
@@ -570,6 +588,7 @@ done:
{
agmtlist_release_agmt(agmt);
}
+ slapi_ch_free_string(&val);
return rc;
}
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 612fe46..05074b0 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -1921,10 +1921,24 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
static int
repl5_inc_stop(Private_Repl_Protocol *prp)
{
- int return_value;
PRIntervalTime start, maxwait, now;
+ Replica *replica = NULL;
+ PRUint64 timeout;
+ int return_value;
+
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ if(prp->replica_object){
+ object_acquire(prp->replica_object);
+ replica = object_get_data(prp->replica_object);
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ }
+ object_release(prp->replica_object);
+ }
+ }
- maxwait = PR_SecondsToInterval(prp->timeout);
+ maxwait = PR_SecondsToInterval(timeout);
prp->terminate = 1;
event_notify(prp, EVENT_PROTOCOL_SHUTDOWN);
start = PR_IntervalNow();
@@ -1939,8 +1953,8 @@ repl5_inc_stop(Private_Repl_Protocol *prp)
/* Isn't listening. Do something drastic. */
return_value = -1;
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
- "%s: repl5_inc_stop: protocol does not stop after %d seconds\n",
- agmt_get_long_name(prp->agmt), (int)prp->timeout);
+ "%s: repl5_inc_stop: protocol does not stop after %llu seconds\n",
+ agmt_get_long_name(prp->agmt), (long long unsigned int)timeout);
}
else
{
@@ -2044,7 +2058,6 @@ Repl_5_Inc_Protocol_new(Repl_Protocol *rp)
prp->notify_window_closed = repl5_inc_notify_window_closed;
prp->update_now = repl5_inc_update_now;
prp->replica_object = prot_get_replica_object(rp);
- prp->timeout = prot_get_timeout(rp);
if ((prp->lock = PR_NewLock()) == NULL)
{
goto loser;
diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h
index 37072ee..586e1eb 100644
--- a/ldap/servers/plugins/replication/repl5_prot_private.h
+++ b/ldap/servers/plugins/replication/repl5_prot_private.h
@@ -75,7 +75,6 @@ typedef struct private_repl_protocol
int repl50consumer; /* Flag to tell us if this is a 5.0-style consumer we're talking to */
int repl71consumer; /* Flag to tell us if this is a 7.1-style consumer we're talking to */
int repl90consumer; /* Flag to tell us if this is a 9.0-style consumer we're talking to */
- PRUint64 timeout;
} Private_Repl_Protocol;
extern Private_Repl_Protocol *Repl_5_Inc_Protocol_new();
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
index b56829c..0e9668d 100644
--- a/ldap/servers/plugins/replication/repl5_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
@@ -71,7 +71,6 @@ typedef struct repl_protocol
Object *replica_object; /* Local replica. If non-NULL, replica object is acquired */
int state;
int next_state;
- PRUint64 protocol_timeout;
PRThread *agmt_thread;
PRLock *lock;
} repl_protocol;
@@ -134,16 +133,17 @@ prot_new(Repl_Agmt *agmt, int protocol_state)
rp->prp_total = private_protocol_factory(rp, PROTOCOL_WINDOWS_TOTAL);
rp->delete_conn = windows_conn_delete;
}
- rp->protocol_timeout = agmt_get_protocol_timeout(agmt);
-
/* XXXggood register callback handlers for entries updated, and
schedule window enter/leave. */
goto done;
+
loser:
prot_delete(&rp);
+
done:
slapi_sdn_free(&replarea_sdn);
+
return rp;
}
@@ -593,8 +593,3 @@ private_protocol_factory(Repl_Protocol *rp, int type)
return prp;
}
-int
-prot_get_timeout(Repl_Protocol *rp)
-{
- return (int)rp->protocol_timeout;
-}
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index fc277ff..ffa5adc 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -87,7 +87,7 @@ struct replica {
PRBool state_update_inprogress; /* replica state is being updated */
PRLock *agmt_lock; /* protects agreement creation, start and stop */
char *locking_purl; /* supplier who has exclusive access */
- PRUint64 protocol_timeout; /* protocol shutdown timeout */
+ Slapi_Counter *protocol_timeout; /* protocol shutdown timeout */
PRUint64 backoff_min; /* backoff retry minimum */
PRUint64 backoff_max; /* backoff retry maximum */
PRUint64 agmt_count; /* Number of agmts */
@@ -165,26 +165,26 @@ replica_new(const Slapi_DN *root)
Replica *
replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation)
{
- int rc = 0;
- Replica *r;
+ int rc = 0;
+ Replica *r;
char *repl_name = NULL;
- if (e == NULL)
- {
- if (NULL != errortext)
+ if (e == NULL)
+ {
+ if (NULL != errortext)
{
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
}
- return NULL;
- }
+ return NULL;
+ }
- r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
+ r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
- if (!r)
+ if (!r)
{
- if (NULL != errortext)
+ if (NULL != errortext)
{
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
}
rc = -1;
goto done;
@@ -209,6 +209,7 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
rc = -1;
goto done;
}
+ r->protocol_timeout = slapi_counter_new();
/* read parameters from the replica config entry */
rc = _replica_init_from_config (r, e, errortext);
@@ -404,6 +405,8 @@ replica_destroy(void **arg)
csnplFree(&r->min_csn_pl);;
}
+ slapi_counter_destroy(&r->protocol_timeout);
+
slapi_ch_free((void **)arg);
}
@@ -797,10 +800,22 @@ replica_get_type (const Replica *r)
return r->repl_type;
}
-int
+PRUint64
replica_get_protocol_timeout(Replica *r)
{
- return (int)r->protocol_timeout;
+ if(r){
+ return slapi_counter_get_value(r->protocol_timeout);
+ } else {
+ return 0;
+ }
+}
+
+void
+replica_set_protocol_timeout(Replica *r, PRUint64 timeout)
+{
+ if(r){
+ slapi_counter_set_value(r->protocol_timeout, timeout);
+ }
}
/*
@@ -1691,6 +1706,7 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
char *val;
int backoff_min;
int backoff_max;
+ int ptimeout = 0;
int rc;
PR_ASSERT (r && e);
@@ -1763,9 +1779,11 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
}
/* get the protocol timeout */
- r->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
- if(r->protocol_timeout == 0){
- r->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
+ if(ptimeout <= 0){
+ slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
+ } else {
+ slapi_counter_set_value(r->protocol_timeout, ptimeout);
}
/* get replica flags */
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index ea23837..4a3f29f 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -397,9 +397,16 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
else if (strcasecmp (config_attr, type_replicaCleanRUV) == 0 ||
strcasecmp (config_attr, type_replicaAbortCleanRUV) == 0)
{
- /* only allow the deletion of the cleanAllRUV config attributes */
+ /*
+ * Only allow the deletion of the cleanAllRUV config attributes, and the
+ * protocol timeout.
+ */
continue;
}
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 )
+ {
+ replica_set_protocol_timeout(r, DEFAULT_PROTOCOL_TIMEOUT);
+ }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
@@ -488,6 +495,22 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
{
*returncode = LDAP_SUCCESS;
}
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 ){
+ if (apply_mods && config_attr_value && config_attr_value[0])
+ {
+ long ptimeout = atol(config_attr_value);
+
+ if(ptimeout <= 0){
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
+ PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE,
+ "attribute %s value (%s) is invalid, must be a number greater than zero.\n",
+ config_attr, config_attr_value);
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n", errortext);
+ } else {
+ replica_set_protocol_timeout(r, ptimeout);
+ }
+ }
+ }
else
{
*returncode = LDAP_UNWILLING_TO_PERFORM;
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index 5bb203a..a241128 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -505,11 +505,22 @@ static int
repl5_tot_stop(Private_Repl_Protocol *prp)
{
int return_value;
- int seconds = 600;
PRIntervalTime start, maxwait, now;
+ PRUint64 timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ Replica *replica = NULL;
+
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ if(prp->replica_object){
+ replica = object_get_data(prp->replica_object);
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
+ }
+ }
+ }
prp->terminate = 1;
- maxwait = PR_SecondsToInterval(seconds);
+ maxwait = PR_SecondsToInterval(timeout);
start = PR_IntervalNow();
now = start;
while (!prp->stopped && ((now - start) < maxwait))
@@ -567,7 +578,6 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
prp->notify_window_opened = repl5_tot_noop;
prp->notify_window_closed = repl5_tot_noop;
prp->update_now = repl5_tot_noop;
- prp->timeout = DEFAULT_PROTOCOL_TIMEOUT;
if ((prp->lock = PR_NewLock()) == NULL)
{
goto loser;
@@ -588,6 +598,7 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
prp->repl50consumer = 0;
prp->repl71consumer = 0;
prp->repl90consumer = 0;
+ prp->replica_object = prot_get_replica_object(rp);
return prp;
loser:
repl5_tot_delete(&prp);
10 years, 5 months