From 797d98bf5ef5cb4f645b94472945928b39b0e673 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Tue, 27 Nov 2012 15:16:45 -0500
Subject: [PATCH] Ticket 393 - Change in winSyncInterval does not take immediate effect

Bug Description:  If you change the sync interval you must restart the DS for
                  it to take effect.

Fix Description:  When we change certain config settings(like the interval), notify
                  the repl protocol that the agmt has changed.  This iputs the incr_run
                  into the START state where we will pick the interval change.

                  We do not want to notify the protocol when updating these attributes:

                        nsds7WindowsReplicaSubtree
                        nsds7DirectoryReplicaSubtree
                        nsds7WindowsDomain

                  Notifying the protocol automatically triggers these attributes to be
                  updated, so we don't want to renotify the protocol and end up in an
                  infinite loop.

https://fedorahosted.org/389/ticket/393

Reviewed by: ?
---
 ldap/servers/plugins/replication/repl5.h           |    2 +
 ldap/servers/plugins/replication/repl5_agmt.c      |   10 ++++++++
 .../plugins/replication/windows_inc_protocol.c     |   23 +++++++++----------
 ldap/servers/plugins/replication/windows_private.c |   10 +++++++-
 4 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 4c57ee5..f1d6ef4 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -492,6 +492,8 @@ void prot_notify_window_closed (Repl_Protocol *rp);
 Object *prot_get_replica_object(Repl_Protocol *rp);
 void prot_replicate_now(Repl_Protocol *rp);
 
+Repl_Protocol *agmt_get_protocol(Repl_Agmt *ra);
+
 /* In repl5_replica.c */
 typedef enum
 {   
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 935fb37..da68e16 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2497,6 +2497,16 @@ void* agmt_get_connection(Repl_Agmt *ra)
 	}
 }
 
+Repl_Protocol *
+agmt_get_protocol(Repl_Agmt *ra)
+{
+	if(ra){
+		return ra->protocol;
+	} else {
+		return NULL;
+	}
+}
+
 int
 agmt_has_protocol(Repl_Agmt *agmt)
 {
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
index b5fcadc..20a1c7a 100644
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
@@ -147,7 +147,7 @@ static const char* event2name (int event);
 static const char* acquire2name (int code);
 static void periodic_dirsync(time_t when, void *arg);
 
-static Slapi_Eq_Context dirsync;
+static Slapi_Eq_Context dirsync = NULL;
 /*
  * It's specifically ok to delete a protocol instance that
  * is currently running. The instance will be shut down, and
@@ -292,8 +292,8 @@ windows_inc_run(Private_Repl_Protocol *prp)
 	PRBool use_busy_backoff_timer = PR_FALSE;
 	long pausetime = 0;
 	long busywaittime = 0;
-	/* Some operations should only be done the first time STATE_START is true. */
-	static PRBool is_first_start = PR_TRUE;
+	unsigned long current_interval = 0;
+	unsigned long interval = 0;
 	int one_way;
  
 	PRBool run_dirsync = PR_FALSE;
@@ -357,17 +357,16 @@ windows_inc_run(Private_Repl_Protocol *prp)
 					w_set_pause_and_busy_time(&pausetime, &busywaittime);
 				}
 
-
-				if (is_first_start) {
-					unsigned long interval = windows_private_get_sync_interval(prp->agmt) * 1000;
-					/*
-					 * The function, the arguments, the time (hence) when it is first to be called, 
-					 * and the repeat interval. 
-					 */ 
-					/* DBDB: we should probably make this polling interval configurable */
+				/* Check if the interval changed */
+				interval = windows_private_get_sync_interval(prp->agmt) * 1000;
+				if(interval != current_interval){
+					current_interval = interval;
+					if(dirsync){
+						slapi_eq_cancel(dirsync);
+					}
 					dirsync = slapi_eq_repeat(periodic_dirsync, (void*) prp, (time_t)0 , interval);
-					is_first_start = PR_FALSE;
 				}
+
 				break;
 
 			case STATE_WAIT_WINDOW_OPEN:
diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c
index cc007aa..6b509a1 100644
--- a/ldap/servers/plugins/replication/windows_private.c
+++ b/ldap/servers/plugins/replication/windows_private.c
@@ -180,8 +180,9 @@ windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
 		{
 			windows_private_set_create_users(ra, PR_FALSE);
 		}
-		retval = 1;
 		slapi_ch_free((void**)&tmpstr);
+		prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
+		retval = 1;
 	}
 	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7CreateNewGroups))
 	{
@@ -194,8 +195,9 @@ windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
 		{
 			windows_private_set_create_groups(ra, PR_FALSE);
 		}
-		retval = 1;
 		slapi_ch_free((void**)&tmpstr);
+		prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
+		retval = 1;
 	}
 	if (type == NULL || slapi_attr_types_equivalent(type,type_nsds7WindowsDomain))
 	{
@@ -214,6 +216,7 @@ windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
 		if (NULL != tmpstr)
 		{
 			windows_private_set_sync_interval(ra,tmpstr);
+			prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
 		}
 		slapi_ch_free_string(&tmpstr);
 		retval = 1;
@@ -240,6 +243,7 @@ windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
 			windows_private_set_one_way(ra, ONE_WAY_SYNC_DISABLED);
 		}
 		slapi_ch_free((void**)&tmpstr);
+		prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
 		retval = 1;
 	}
 	if (type == NULL || slapi_attr_types_equivalent(type,type_winsyncMoveAction))
@@ -266,8 +270,10 @@ windows_parse_config_entry(Repl_Agmt *ra, const char *type, Slapi_Entry *e)
 			windows_private_set_move_action(ra, MOVE_DOES_NOTHING);
 		}
 		slapi_ch_free((void**)&tmpstr);
+		prot_notify_agmt_changed(agmt_get_protocol(ra), (char *)agmt_get_long_name(ra));
 		retval = 1;
 	}
+
 	return retval;
 }
 
-- 
1.7.1

