|
|
cc3dff |
From 39af2e9e98c895c5145090865d5ab7cde6cc12fd Mon Sep 17 00:00:00 2001
|
|
|
cc3dff |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
cc3dff |
Date: Fri, 6 Dec 2013 16:57:41 -0500
|
|
|
cc3dff |
Subject: [PATCH 65/65] Ticket 47620 - 389-ds rejects
|
|
|
cc3dff |
nsds5ReplicaProtocolTimeout attribute
|
|
|
cc3dff |
|
|
|
cc3dff |
Bug Description: Attempting to add/modify/delete nsds5ReplicaProtocolTimeout
|
|
|
cc3dff |
results in an error 53 (unwilling to perform).
|
|
|
cc3dff |
|
|
|
cc3dff |
Fix Description: Allow nsds5ReplicaProtocolTimeout to be updated in agreements
|
|
|
cc3dff |
and the replica configuration. Also, made the config timeout
|
|
|
cc3dff |
setting dynamic.
|
|
|
cc3dff |
|
|
|
cc3dff |
https://fedorahosted.org/389/ticket/47620
|
|
|
cc3dff |
|
|
|
cc3dff |
Reviewed by: rmeggins(Thanks!)
|
|
|
cc3dff |
(cherry picked from commit 58fca2c4e4f2120cb6e5fb249008be8f551e944c)
|
|
|
cc3dff |
(cherry picked from commit 490360fd96121d06fa8813e182b44d045257be98)
|
|
|
cc3dff |
---
|
|
|
cc3dff |
ldap/servers/plugins/replication/repl5.h | 12 +++--
|
|
|
cc3dff |
ldap/servers/plugins/replication/repl5_agmt.c | 54 ++++++++++++++++------
|
|
|
cc3dff |
ldap/servers/plugins/replication/repl5_agmtlist.c | 27 +++++++++--
|
|
|
cc3dff |
.../plugins/replication/repl5_inc_protocol.c | 23 +++++++--
|
|
|
cc3dff |
.../plugins/replication/repl5_prot_private.h | 1 -
|
|
|
cc3dff |
ldap/servers/plugins/replication/repl5_protocol.c | 13 ++----
|
|
|
cc3dff |
ldap/servers/plugins/replication/repl5_replica.c | 54 ++++++++++++++--------
|
|
|
cc3dff |
.../plugins/replication/repl5_replica_config.c | 25 +++++++++-
|
|
|
cc3dff |
.../plugins/replication/repl5_tot_protocol.c | 17 +++++--
|
|
|
cc3dff |
9 files changed, 169 insertions(+), 57 deletions(-)
|
|
|
cc3dff |
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
|
|
cc3dff |
index 92a9229..321a285 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5.h
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5.h
|
|
|
cc3dff |
@@ -386,9 +386,15 @@ char **agmt_get_attrs_to_strip(Repl_Agmt *ra);
|
|
|
cc3dff |
int agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e);
|
|
|
cc3dff |
int agmt_set_timeout(Repl_Agmt *ra, long timeout);
|
|
|
cc3dff |
void agmt_update_done(Repl_Agmt *ra, int is_total);
|
|
|
cc3dff |
-int agmt_get_protocol_timeout(Repl_Agmt *agmt);
|
|
|
cc3dff |
|
|
|
cc3dff |
typedef struct replica Replica;
|
|
|
cc3dff |
+PRUint64 agmt_get_protocol_timeout(Repl_Agmt *agmt);
|
|
|
cc3dff |
+void agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout);
|
|
|
cc3dff |
+void agmt_update_maxcsn(Replica *r, Slapi_DN *sdn, int op, LDAPMod **mods, CSN *csn);
|
|
|
cc3dff |
+void add_agmt_maxcsns(Slapi_Entry *e, Replica *r);
|
|
|
cc3dff |
+void agmt_set_maxcsn(Repl_Agmt *ra);
|
|
|
cc3dff |
+void agmt_remove_maxcsn(Repl_Agmt *ra);
|
|
|
cc3dff |
+int agmt_maxcsn_to_smod (Replica *r, Slapi_Mod *smod);
|
|
|
cc3dff |
|
|
|
cc3dff |
/* In repl5_agmtlist.c */
|
|
|
cc3dff |
int agmtlist_config_init();
|
|
|
cc3dff |
@@ -494,7 +500,6 @@ void prot_notify_window_opened (Repl_Protocol *rp);
|
|
|
cc3dff |
void prot_notify_window_closed (Repl_Protocol *rp);
|
|
|
cc3dff |
Object *prot_get_replica_object(Repl_Protocol *rp);
|
|
|
cc3dff |
void prot_replicate_now(Repl_Protocol *rp);
|
|
|
cc3dff |
-int prot_get_timeout(Repl_Protocol *rp);
|
|
|
cc3dff |
|
|
|
cc3dff |
Repl_Protocol *agmt_get_protocol(Repl_Agmt *ra);
|
|
|
cc3dff |
|
|
|
cc3dff |
@@ -591,7 +596,8 @@ char *replica_get_dn(Replica *r);
|
|
|
cc3dff |
void replica_check_for_tasks(Replica*r, Slapi_Entry *e);
|
|
|
cc3dff |
void replica_update_state (time_t when, void *arg);
|
|
|
cc3dff |
void replica_reset_csn_pl(Replica *r);
|
|
|
cc3dff |
-int replica_get_protocol_timeout(Replica *r);
|
|
|
cc3dff |
+PRUint64 replica_get_protocol_timeout(Replica *r);
|
|
|
cc3dff |
+void replica_set_protocol_timeout(Replica *r, PRUint64 timeout);
|
|
|
cc3dff |
int replica_get_backoff_min(Replica *r);
|
|
|
cc3dff |
int replica_get_backoff_max(Replica *r);
|
|
|
cc3dff |
void replica_set_backoff_min(Replica *r, int min);
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
|
|
|
cc3dff |
index 90d94f8..b0da172 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_agmt.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
|
|
|
cc3dff |
@@ -142,7 +142,9 @@ typedef struct repl5agmt {
|
|
|
cc3dff |
char **attrs_to_strip; /* for fractional replication, if a "mod" is empty, strip out these attributes:
|
|
|
cc3dff |
* modifiersname, modifytimestamp, internalModifiersname, internalModifyTimestamp, etc */
|
|
|
cc3dff |
int agreement_type;
|
|
|
cc3dff |
- PRUint64 protocol_timeout;
|
|
|
cc3dff |
+ Slapi_Counter *protocol_timeout;
|
|
|
cc3dff |
+ char *maxcsn; /* agmt max csn */
|
|
|
cc3dff |
+ Slapi_RWLock *attr_lock; /* RW lock for all the stripped attrs */
|
|
|
cc3dff |
} repl5agmt;
|
|
|
cc3dff |
|
|
|
cc3dff |
/* Forward declarations */
|
|
|
cc3dff |
@@ -265,6 +267,14 @@ agmt_new_from_entry(Slapi_Entry *e)
|
|
|
cc3dff |
slapi_entry_get_dn_const(e));
|
|
|
cc3dff |
goto loser;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ if ((ra->attr_lock = slapi_new_rwlock()) == NULL)
|
|
|
cc3dff |
+ {
|
|
|
cc3dff |
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "Unable to create new attr lock "
|
|
|
cc3dff |
+ "for replication agreement \"%s\" - agreement ignored.\n",
|
|
|
cc3dff |
+ slapi_entry_get_dn_const(e));
|
|
|
cc3dff |
+ goto loser;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ ra->protocol_timeout = slapi_counter_new();
|
|
|
cc3dff |
|
|
|
cc3dff |
/* Find all the stuff we need for the agreement */
|
|
|
cc3dff |
|
|
|
cc3dff |
@@ -338,19 +348,14 @@ agmt_new_from_entry(Slapi_Entry *e)
|
|
|
cc3dff |
tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaRoot);
|
|
|
cc3dff |
if (NULL != tmpstr)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
+ PRUint64 ptimeout = 0;
|
|
|
cc3dff |
+
|
|
|
cc3dff |
ra->replarea = slapi_sdn_new_dn_passin(tmpstr);
|
|
|
cc3dff |
|
|
|
cc3dff |
/* If this agmt has its own timeout, grab it, otherwise use the replica's protocol timeout */
|
|
|
cc3dff |
- ra->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
|
|
|
cc3dff |
- if(ra->protocol_timeout == 0){
|
|
|
cc3dff |
- /* grab the replica protocol timeout */
|
|
|
cc3dff |
- Object *replobj = replica_get_replica_from_dn(ra->replarea);
|
|
|
cc3dff |
- if(replobj){
|
|
|
cc3dff |
- Replica *replica =(Replica*)object_get_data (replobj);
|
|
|
cc3dff |
- ra->protocol_timeout = replica_get_protocol_timeout(replica);
|
|
|
cc3dff |
- } else {
|
|
|
cc3dff |
- ra->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
- }
|
|
|
cc3dff |
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
|
|
|
cc3dff |
+ if(ptimeout){
|
|
|
cc3dff |
+ slapi_counter_set_value(ra->protocol_timeout, ptimeout);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
@@ -613,6 +618,17 @@ agmt_delete(void **rap)
|
|
|
cc3dff |
if(ra->attrs_to_strip){
|
|
|
cc3dff |
slapi_ch_array_free(ra->attrs_to_strip);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ if(ra->maxcsn){
|
|
|
cc3dff |
+ slapi_ch_free_string(&ra->maxcsn);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ schedule_destroy(ra->schedule);
|
|
|
cc3dff |
+ slapi_ch_free_string(&ra->long_name);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ slapi_counter_destroy(&ra->protocol_timeout);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ /* free the locks */
|
|
|
cc3dff |
+ PR_DestroyLock(ra->lock);
|
|
|
cc3dff |
+ slapi_destroy_rwlock(ra->attr_lock);
|
|
|
cc3dff |
|
|
|
cc3dff |
schedule_destroy(ra->schedule);
|
|
|
cc3dff |
slapi_ch_free((void **)&ra->long_name);
|
|
|
cc3dff |
@@ -2663,9 +2679,21 @@ agmt_update_done(Repl_Agmt *agmt, int is_total)
|
|
|
cc3dff |
windows_update_done(agmt, is_total);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
-int
|
|
|
cc3dff |
+PRUint64
|
|
|
cc3dff |
agmt_get_protocol_timeout(Repl_Agmt *agmt)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- return (int)agmt->protocol_timeout;
|
|
|
cc3dff |
+ if(agmt){
|
|
|
cc3dff |
+ return slapi_counter_get_value(agmt->protocol_timeout);
|
|
|
cc3dff |
+ } else {
|
|
|
cc3dff |
+ return 0;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+}
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+void
|
|
|
cc3dff |
+agmt_set_protocol_timeout(Repl_Agmt *agmt, PRUint64 timeout)
|
|
|
cc3dff |
+{
|
|
|
cc3dff |
+ if(agmt){
|
|
|
cc3dff |
+ slapi_counter_set_value(agmt->protocol_timeout, timeout);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_agmtlist.c b/ldap/servers/plugins/replication/repl5_agmtlist.c
|
|
|
cc3dff |
index 1167b0c..04891b7 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_agmtlist.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_agmtlist.c
|
|
|
cc3dff |
@@ -209,6 +209,7 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
|
|
|
cc3dff |
LDAPMod **mods;
|
|
|
cc3dff |
char buff [SLAPI_DSE_RETURNTEXT_SIZE];
|
|
|
cc3dff |
char *errortext = returntext ? returntext : buff;
|
|
|
cc3dff |
+ char *val = NULL;
|
|
|
cc3dff |
int rc = SLAPI_DSE_CALLBACK_OK;
|
|
|
cc3dff |
Slapi_Operation *op;
|
|
|
cc3dff |
void *identity;
|
|
|
cc3dff |
@@ -243,16 +244,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
|
|
|
cc3dff |
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods;;
|
|
|
cc3dff |
for (i = 0; NULL != mods && NULL != mods[i]; i++)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
+ slapi_ch_free_string(&val;;
|
|
|
cc3dff |
if (slapi_attr_types_equivalent(mods[i]->mod_type, type_nsds5ReplicaInitialize))
|
|
|
cc3dff |
{
|
|
|
cc3dff |
/* we don't allow delete attribute operations unless it was issued by
|
|
|
cc3dff |
the replication plugin - handled above */
|
|
|
cc3dff |
if (mods[i]->mod_op & LDAP_MOD_DELETE)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0){
|
|
|
cc3dff |
+ if(strcasecmp (mods[i]->mod_type, type_nsds5ReplicaCleanRUVnotified) == 0 ){
|
|
|
cc3dff |
/* allow the deletion of cleanallruv agmt attr */
|
|
|
cc3dff |
continue;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ if(strcasecmp (mods[i]->mod_type, type_replicaProtocolTimeout) == 0){
|
|
|
cc3dff |
+ agmt_set_protocol_timeout(agmt, 0);
|
|
|
cc3dff |
+ continue;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
|
|
|
cc3dff |
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
|
|
|
cc3dff |
"deletion of %s attribute is not allowed\n", type_nsds5ReplicaInitialize);
|
|
|
cc3dff |
@@ -262,8 +268,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
|
|
|
cc3dff |
}
|
|
|
cc3dff |
else
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- char *val;
|
|
|
cc3dff |
-
|
|
|
cc3dff |
if (mods[i]->mod_bvalues && mods[i]->mod_bvalues[0])
|
|
|
cc3dff |
val = slapi_berval_get_string_copy (mods[i]->mod_bvalues[0]);
|
|
|
cc3dff |
else
|
|
|
cc3dff |
@@ -304,7 +308,6 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
|
|
|
cc3dff |
val, mods[i]->mod_type);
|
|
|
cc3dff |
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: %s\n", errortext);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
- slapi_ch_free ((void**)&val;;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
}
|
|
|
cc3dff |
else if (slapi_attr_types_equivalent(mods[i]->mod_type,
|
|
|
cc3dff |
@@ -511,6 +514,21 @@ agmtlist_modify_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry
|
|
|
cc3dff |
rc = SLAPI_DSE_CALLBACK_ERROR;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ else if (slapi_attr_types_equivalent(mods[i]->mod_type, type_replicaProtocolTimeout)){
|
|
|
cc3dff |
+ if (val){
|
|
|
cc3dff |
+ long ptimeout = atol(val);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ if(ptimeout <= 0){
|
|
|
cc3dff |
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
cc3dff |
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "attribute %s value (%s) is invalid, "
|
|
|
cc3dff |
+ "must be a number greater than zero.\n",
|
|
|
cc3dff |
+ type_replicaProtocolTimeout, val);
|
|
|
cc3dff |
+ rc = SLAPI_DSE_CALLBACK_ERROR;
|
|
|
cc3dff |
+ break;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ agmt_set_protocol_timeout(agmt, ptimeout);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
else if (0 == windows_handle_modify_agreement(agmt, mods[i]->mod_type, e))
|
|
|
cc3dff |
{
|
|
|
cc3dff |
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name, "agmtlist_modify_callback: "
|
|
|
cc3dff |
@@ -561,6 +579,7 @@ done:
|
|
|
cc3dff |
{
|
|
|
cc3dff |
agmtlist_release_agmt(agmt);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ slapi_ch_free_string(&val;;
|
|
|
cc3dff |
|
|
|
cc3dff |
return rc;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
|
|
|
cc3dff |
index 612fe46..05074b0 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
|
|
|
cc3dff |
@@ -1921,10 +1921,24 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
|
|
|
cc3dff |
static int
|
|
|
cc3dff |
repl5_inc_stop(Private_Repl_Protocol *prp)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- int return_value;
|
|
|
cc3dff |
PRIntervalTime start, maxwait, now;
|
|
|
cc3dff |
+ Replica *replica = NULL;
|
|
|
cc3dff |
+ PRUint64 timeout;
|
|
|
cc3dff |
+ int return_value;
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
|
|
|
cc3dff |
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
+ if(prp->replica_object){
|
|
|
cc3dff |
+ object_acquire(prp->replica_object);
|
|
|
cc3dff |
+ replica = object_get_data(prp->replica_object);
|
|
|
cc3dff |
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
|
|
|
cc3dff |
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ object_release(prp->replica_object);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
|
|
|
cc3dff |
- maxwait = PR_SecondsToInterval(prp->timeout);
|
|
|
cc3dff |
+ maxwait = PR_SecondsToInterval(timeout);
|
|
|
cc3dff |
prp->terminate = 1;
|
|
|
cc3dff |
event_notify(prp, EVENT_PROTOCOL_SHUTDOWN);
|
|
|
cc3dff |
start = PR_IntervalNow();
|
|
|
cc3dff |
@@ -1939,8 +1953,8 @@ repl5_inc_stop(Private_Repl_Protocol *prp)
|
|
|
cc3dff |
/* Isn't listening. Do something drastic. */
|
|
|
cc3dff |
return_value = -1;
|
|
|
cc3dff |
slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
|
|
|
cc3dff |
- "%s: repl5_inc_stop: protocol does not stop after %d seconds\n",
|
|
|
cc3dff |
- agmt_get_long_name(prp->agmt), (int)prp->timeout);
|
|
|
cc3dff |
+ "%s: repl5_inc_stop: protocol does not stop after %llu seconds\n",
|
|
|
cc3dff |
+ agmt_get_long_name(prp->agmt), (long long unsigned int)timeout);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
else
|
|
|
cc3dff |
{
|
|
|
cc3dff |
@@ -2044,7 +2058,6 @@ Repl_5_Inc_Protocol_new(Repl_Protocol *rp)
|
|
|
cc3dff |
prp->notify_window_closed = repl5_inc_notify_window_closed;
|
|
|
cc3dff |
prp->update_now = repl5_inc_update_now;
|
|
|
cc3dff |
prp->replica_object = prot_get_replica_object(rp);
|
|
|
cc3dff |
- prp->timeout = prot_get_timeout(rp);
|
|
|
cc3dff |
if ((prp->lock = PR_NewLock()) == NULL)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
goto loser;
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h
|
|
|
cc3dff |
index 37072ee..586e1eb 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_prot_private.h
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_prot_private.h
|
|
|
cc3dff |
@@ -75,7 +75,6 @@ typedef struct private_repl_protocol
|
|
|
cc3dff |
int repl50consumer; /* Flag to tell us if this is a 5.0-style consumer we're talking to */
|
|
|
cc3dff |
int repl71consumer; /* Flag to tell us if this is a 7.1-style consumer we're talking to */
|
|
|
cc3dff |
int repl90consumer; /* Flag to tell us if this is a 9.0-style consumer we're talking to */
|
|
|
cc3dff |
- PRUint64 timeout;
|
|
|
cc3dff |
} Private_Repl_Protocol;
|
|
|
cc3dff |
|
|
|
cc3dff |
extern Private_Repl_Protocol *Repl_5_Inc_Protocol_new();
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_protocol.c b/ldap/servers/plugins/replication/repl5_protocol.c
|
|
|
cc3dff |
index 34fe8a0..0e9668d 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_protocol.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_protocol.c
|
|
|
cc3dff |
@@ -71,8 +71,7 @@ typedef struct repl_protocol
|
|
|
cc3dff |
Object *replica_object; /* Local replica. If non-NULL, replica object is acquired */
|
|
|
cc3dff |
int state;
|
|
|
cc3dff |
int next_state;
|
|
|
cc3dff |
- PRUint64 protocol_timeout;
|
|
|
cc3dff |
- PRThread *agmt_thread;
|
|
|
cc3dff |
+ PRThread *agmt_thread;
|
|
|
cc3dff |
PRLock *lock;
|
|
|
cc3dff |
} repl_protocol;
|
|
|
cc3dff |
|
|
|
cc3dff |
@@ -134,16 +133,17 @@ prot_new(Repl_Agmt *agmt, int protocol_state)
|
|
|
cc3dff |
rp->prp_total = private_protocol_factory(rp, PROTOCOL_WINDOWS_TOTAL);
|
|
|
cc3dff |
rp->delete_conn = windows_conn_delete;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
- rp->protocol_timeout = agmt_get_protocol_timeout(agmt);
|
|
|
cc3dff |
-
|
|
|
cc3dff |
/* XXXggood register callback handlers for entries updated, and
|
|
|
cc3dff |
schedule window enter/leave. */
|
|
|
cc3dff |
|
|
|
cc3dff |
goto done;
|
|
|
cc3dff |
+
|
|
|
cc3dff |
loser:
|
|
|
cc3dff |
prot_delete(&rp);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
done:
|
|
|
cc3dff |
slapi_sdn_free(&replarea_sdn);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
return rp;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
@@ -593,8 +593,3 @@ private_protocol_factory(Repl_Protocol *rp, int type)
|
|
|
cc3dff |
return prp;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
-int
|
|
|
cc3dff |
-prot_get_timeout(Repl_Protocol *rp)
|
|
|
cc3dff |
-{
|
|
|
cc3dff |
- return (int)rp->protocol_timeout;
|
|
|
cc3dff |
-}
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
|
|
cc3dff |
index 8a1c590..02d4e74 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
|
|
cc3dff |
@@ -87,7 +87,7 @@ struct replica {
|
|
|
cc3dff |
PRBool state_update_inprogress; /* replica state is being updated */
|
|
|
cc3dff |
PRLock *agmt_lock; /* protects agreement creation, start and stop */
|
|
|
cc3dff |
char *locking_purl; /* supplier who has exclusive access */
|
|
|
cc3dff |
- PRUint64 protocol_timeout; /* protocol shutdown timeout */
|
|
|
cc3dff |
+ Slapi_Counter *protocol_timeout; /* protocol shutdown timeout */
|
|
|
cc3dff |
PRUint64 backoff_min; /* backoff retry minimum */
|
|
|
cc3dff |
PRUint64 backoff_max; /* backoff retry maximum */
|
|
|
cc3dff |
};
|
|
|
cc3dff |
@@ -164,26 +164,26 @@ replica_new(const Slapi_DN *root)
|
|
|
cc3dff |
Replica *
|
|
|
cc3dff |
replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- int rc = 0;
|
|
|
cc3dff |
- Replica *r;
|
|
|
cc3dff |
+ int rc = 0;
|
|
|
cc3dff |
+ Replica *r;
|
|
|
cc3dff |
char *repl_name = NULL;
|
|
|
cc3dff |
|
|
|
cc3dff |
- if (e == NULL)
|
|
|
cc3dff |
- {
|
|
|
cc3dff |
- if (NULL != errortext)
|
|
|
cc3dff |
+ if (e == NULL)
|
|
|
cc3dff |
+ {
|
|
|
cc3dff |
+ if (NULL != errortext)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
|
|
|
cc3dff |
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "NULL entry");
|
|
|
cc3dff |
}
|
|
|
cc3dff |
- return NULL;
|
|
|
cc3dff |
- }
|
|
|
cc3dff |
+ return NULL;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
|
|
|
cc3dff |
- r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
|
|
|
cc3dff |
+ r = (Replica *)slapi_ch_calloc(1, sizeof(Replica));
|
|
|
cc3dff |
|
|
|
cc3dff |
- if (!r)
|
|
|
cc3dff |
+ if (!r)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- if (NULL != errortext)
|
|
|
cc3dff |
+ if (NULL != errortext)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
|
|
|
cc3dff |
+ PR_snprintf(errortext, SLAPI_DSE_RETURNTEXT_SIZE, "Out of memory");
|
|
|
cc3dff |
}
|
|
|
cc3dff |
rc = -1;
|
|
|
cc3dff |
goto done;
|
|
|
cc3dff |
@@ -208,6 +208,7 @@ replica_new_from_entry (Slapi_Entry *e, char *errortext, PRBool is_add_operation
|
|
|
cc3dff |
rc = -1;
|
|
|
cc3dff |
goto done;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ r->protocol_timeout = slapi_counter_new();
|
|
|
cc3dff |
|
|
|
cc3dff |
/* read parameters from the replica config entry */
|
|
|
cc3dff |
rc = _replica_init_from_config (r, e, errortext);
|
|
|
cc3dff |
@@ -403,6 +404,8 @@ replica_destroy(void **arg)
|
|
|
cc3dff |
csnplFree(&r->min_csn_pl);;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
+ slapi_counter_destroy(&r->protocol_timeout);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
slapi_ch_free((void **)arg);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
@@ -796,10 +799,22 @@ replica_get_type (const Replica *r)
|
|
|
cc3dff |
return r->repl_type;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
-int
|
|
|
cc3dff |
+PRUint64
|
|
|
cc3dff |
replica_get_protocol_timeout(Replica *r)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- return (int)r->protocol_timeout;
|
|
|
cc3dff |
+ if(r){
|
|
|
cc3dff |
+ return slapi_counter_get_value(r->protocol_timeout);
|
|
|
cc3dff |
+ } else {
|
|
|
cc3dff |
+ return 0;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+}
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+void
|
|
|
cc3dff |
+replica_set_protocol_timeout(Replica *r, PRUint64 timeout)
|
|
|
cc3dff |
+{
|
|
|
cc3dff |
+ if(r){
|
|
|
cc3dff |
+ slapi_counter_set_value(r->protocol_timeout, timeout);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
/*
|
|
|
cc3dff |
@@ -1659,6 +1674,7 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
|
|
|
cc3dff |
char *val;
|
|
|
cc3dff |
int backoff_min;
|
|
|
cc3dff |
int backoff_max;
|
|
|
cc3dff |
+ int ptimeout = 0;
|
|
|
cc3dff |
int rc;
|
|
|
cc3dff |
|
|
|
cc3dff |
PR_ASSERT (r && e);
|
|
|
cc3dff |
@@ -1731,9 +1747,11 @@ _replica_init_from_config (Replica *r, Slapi_Entry *e, char *errortext)
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
/* get the protocol timeout */
|
|
|
cc3dff |
- r->protocol_timeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
|
|
|
cc3dff |
- if(r->protocol_timeout == 0){
|
|
|
cc3dff |
- r->protocol_timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
+ ptimeout = slapi_entry_attr_get_int(e, type_replicaProtocolTimeout);
|
|
|
cc3dff |
+ if(ptimeout <= 0){
|
|
|
cc3dff |
+ slapi_counter_set_value(r->protocol_timeout, DEFAULT_PROTOCOL_TIMEOUT);
|
|
|
cc3dff |
+ } else {
|
|
|
cc3dff |
+ slapi_counter_set_value(r->protocol_timeout, ptimeout);
|
|
|
cc3dff |
}
|
|
|
cc3dff |
|
|
|
cc3dff |
/* get replica flags */
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
|
cc3dff |
index 94c23c0..9452d51 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
|
|
cc3dff |
@@ -396,9 +396,16 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
|
|
|
cc3dff |
else if (strcasecmp (config_attr, type_replicaCleanRUV) == 0 ||
|
|
|
cc3dff |
strcasecmp (config_attr, type_replicaAbortCleanRUV) == 0)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
- /* only allow the deletion of the cleanAllRUV config attributes */
|
|
|
cc3dff |
+ /*
|
|
|
cc3dff |
+ * Only allow the deletion of the cleanAllRUV config attributes, and the
|
|
|
cc3dff |
+ * protocol timeout.
|
|
|
cc3dff |
+ */
|
|
|
cc3dff |
continue;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 )
|
|
|
cc3dff |
+ {
|
|
|
cc3dff |
+ replica_set_protocol_timeout(r, DEFAULT_PROTOCOL_TIMEOUT);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
else
|
|
|
cc3dff |
{
|
|
|
cc3dff |
*returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
cc3dff |
@@ -487,6 +494,22 @@ replica_config_modify (Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry*
|
|
|
cc3dff |
{
|
|
|
cc3dff |
*returncode = LDAP_SUCCESS;
|
|
|
cc3dff |
}
|
|
|
cc3dff |
+ else if (strcasecmp (config_attr, type_replicaProtocolTimeout) == 0 ){
|
|
|
cc3dff |
+ if (apply_mods && config_attr_value && config_attr_value[0])
|
|
|
cc3dff |
+ {
|
|
|
cc3dff |
+ long ptimeout = atol(config_attr_value);
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ if(ptimeout <= 0){
|
|
|
cc3dff |
+ *returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
cc3dff |
+ PR_snprintf (errortext, SLAPI_DSE_RETURNTEXT_SIZE,
|
|
|
cc3dff |
+ "attribute %s value (%s) is invalid, must be a number greater than zero.\n",
|
|
|
cc3dff |
+ config_attr, config_attr_value);
|
|
|
cc3dff |
+ slapi_log_error(SLAPI_LOG_FATAL, repl_plugin_name, "replica_config_modify: %s\n", errortext);
|
|
|
cc3dff |
+ } else {
|
|
|
cc3dff |
+ replica_set_protocol_timeout(r, ptimeout);
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
else
|
|
|
cc3dff |
{
|
|
|
cc3dff |
*returncode = LDAP_UNWILLING_TO_PERFORM;
|
|
|
cc3dff |
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
|
|
cc3dff |
index 5bb203a..a241128 100644
|
|
|
cc3dff |
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
|
|
cc3dff |
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
|
|
|
cc3dff |
@@ -505,11 +505,22 @@ static int
|
|
|
cc3dff |
repl5_tot_stop(Private_Repl_Protocol *prp)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
int return_value;
|
|
|
cc3dff |
- int seconds = 600;
|
|
|
cc3dff |
PRIntervalTime start, maxwait, now;
|
|
|
cc3dff |
+ PRUint64 timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
+ Replica *replica = NULL;
|
|
|
cc3dff |
+
|
|
|
cc3dff |
+ if((timeout = agmt_get_protocol_timeout(prp->agmt)) == 0){
|
|
|
cc3dff |
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
+ if(prp->replica_object){
|
|
|
cc3dff |
+ replica = object_get_data(prp->replica_object);
|
|
|
cc3dff |
+ if((timeout = replica_get_protocol_timeout(replica)) == 0){
|
|
|
cc3dff |
+ timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
+ }
|
|
|
cc3dff |
|
|
|
cc3dff |
prp->terminate = 1;
|
|
|
cc3dff |
- maxwait = PR_SecondsToInterval(seconds);
|
|
|
cc3dff |
+ maxwait = PR_SecondsToInterval(timeout);
|
|
|
cc3dff |
start = PR_IntervalNow();
|
|
|
cc3dff |
now = start;
|
|
|
cc3dff |
while (!prp->stopped && ((now - start) < maxwait))
|
|
|
cc3dff |
@@ -567,7 +578,6 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
|
|
|
cc3dff |
prp->notify_window_opened = repl5_tot_noop;
|
|
|
cc3dff |
prp->notify_window_closed = repl5_tot_noop;
|
|
|
cc3dff |
prp->update_now = repl5_tot_noop;
|
|
|
cc3dff |
- prp->timeout = DEFAULT_PROTOCOL_TIMEOUT;
|
|
|
cc3dff |
if ((prp->lock = PR_NewLock()) == NULL)
|
|
|
cc3dff |
{
|
|
|
cc3dff |
goto loser;
|
|
|
cc3dff |
@@ -588,6 +598,7 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
|
|
|
cc3dff |
prp->repl50consumer = 0;
|
|
|
cc3dff |
prp->repl71consumer = 0;
|
|
|
cc3dff |
prp->repl90consumer = 0;
|
|
|
cc3dff |
+ prp->replica_object = prot_get_replica_object(rp);
|
|
|
cc3dff |
return prp;
|
|
|
cc3dff |
loser:
|
|
|
cc3dff |
repl5_tot_delete(&prp;;
|
|
|
cc3dff |
--
|
|
|
cc3dff |
1.8.1.4
|
|
|
cc3dff |
|