Blame SOURCES/0048-Ticket-47581-Winsync-plugin-segfault-during-incremen.patch

ba46c7
From 7f82657dcf6661c51b5fa85d9581724d27941686 Mon Sep 17 00:00:00 2001
ba46c7
From: Noriko Hosoi <nhosoi@redhat.com>
ba46c7
Date: Fri, 1 Nov 2013 14:24:55 -0700
ba46c7
Subject: [PATCH 48/49] Ticket #47581 - Winsync plugin segfault during
ba46c7
 incremental backoff
ba46c7
ba46c7
Bug description: Once WinSync backoff timer is set, even if the
ba46c7
protocol that the backoff timer belongs to is deleted by removing
ba46c7
the windows sync agreement, the timer is not deleted from the event
ba46c7
queue.  Thus the timer is expired and backoff is called, it crashes
ba46c7
the server since the protocol handle is already freed, then.
ba46c7
ba46c7
Fix description: Make sure to delete the backoff timer when
ba46c7
1) a windows sync agreement is removed and the protocol is deleted, and
ba46c7
2) a new backoff timer set and there is already a backoff timer set up.
ba46c7
ba46c7
https://fedorahosted.org/389/ticket/47581
ba46c7
ba46c7
Reviewed by rmeggins (Thank you, Rich!!)
ba46c7
(cherry picked from commit d70e66b2157ce3ba40c5e1cb074c2d5c150ddc5b)
ba46c7
(cherry picked from commit 59846f7247bae47f8fbcfc808c4cb6e6e96e2dc9)
ba46c7
(cherry picked from commit be0e47009a44af34f8dc0dd38f1a1ae1a49c42ce)
ba46c7
---
ba46c7
 .../plugins/replication/windows_inc_protocol.c     | 66 ++++++++++++++--------
ba46c7
 1 file changed, 41 insertions(+), 25 deletions(-)
ba46c7
ba46c7
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
ba46c7
index 58f48f2..29fa20f 100644
ba46c7
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
ba46c7
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
ba46c7
@@ -157,27 +157,34 @@ static Slapi_Eq_Context dirsync = NULL;
ba46c7
 static void
ba46c7
 windows_inc_delete(Private_Repl_Protocol **prpp)
ba46c7
 {
ba46c7
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_inc_delete\n" );
ba46c7
-	/* First, stop the protocol if it isn't already stopped */
ba46c7
-	/* Then, delete all resources used by the protocol */
ba46c7
-	slapi_eq_cancel(dirsync); 
ba46c7
-
ba46c7
-        if (!(*prpp)->stopped) {
ba46c7
-                (*prpp)->stopped = 1;
ba46c7
-                (*prpp)->stop(*prpp);
ba46c7
-        }
ba46c7
-        if ((*prpp)->lock) {
ba46c7
-                PR_DestroyLock((*prpp)->lock);
ba46c7
-                (*prpp)->lock = NULL;
ba46c7
-        }
ba46c7
-        if ((*prpp)->cvar) {
ba46c7
-                PR_DestroyCondVar((*prpp)->cvar);
ba46c7
-                (*prpp)->cvar = NULL;
ba46c7
-        }
ba46c7
-        slapi_ch_free((void **)&(*prpp)->private);
ba46c7
-        slapi_ch_free((void **)prpp);
ba46c7
-
ba46c7
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_inc_delete\n" );
ba46c7
+    int rc;
ba46c7
+    windows_inc_private *prp_priv = (windows_inc_private *)(*prpp)->private;
ba46c7
+    LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_inc_delete\n" );
ba46c7
+    /* First, stop the protocol if it isn't already stopped */
ba46c7
+    /* Then, delete all resources used by the protocol */
ba46c7
+    rc = slapi_eq_cancel(dirsync); 
ba46c7
+    slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
ba46c7
+                    "windows_inc_delete: dirsync: %p, rval: %d\n", dirsync, rc);
ba46c7
+    /* if backoff is set, delete it (from EQ, as well) */
ba46c7
+    if (prp_priv->backoff) {
ba46c7
+        backoff_delete(&prp_priv->backoff);
ba46c7
+    }
ba46c7
+    if (!(*prpp)->stopped) {
ba46c7
+        (*prpp)->stopped = 1;
ba46c7
+        (*prpp)->stop(*prpp);
ba46c7
+    }
ba46c7
+    if ((*prpp)->lock) {
ba46c7
+        PR_DestroyLock((*prpp)->lock);
ba46c7
+        (*prpp)->lock = NULL;
ba46c7
+    }
ba46c7
+    if ((*prpp)->cvar) {
ba46c7
+        PR_DestroyCondVar((*prpp)->cvar);
ba46c7
+        (*prpp)->cvar = NULL;
ba46c7
+    }
ba46c7
+    slapi_ch_free((void **)&(*prpp)->private);
ba46c7
+    slapi_ch_free((void **)prpp);
ba46c7
+
ba46c7
+    LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_inc_delete\n" );
ba46c7
 }
ba46c7
 
ba46c7
 /* helper function */
ba46c7
@@ -362,9 +369,14 @@ windows_inc_run(Private_Repl_Protocol *prp)
ba46c7
 				if(interval != current_interval){
ba46c7
 					current_interval = interval;
ba46c7
 					if(dirsync){
ba46c7
-						slapi_eq_cancel(dirsync);
ba46c7
+						int rc = slapi_eq_cancel(dirsync);
ba46c7
+						slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
ba46c7
+						                "windows_inc_runs: cancelled dirsync: %p, rval: %d\n",
ba46c7
+						                dirsync, rc);
ba46c7
 					}
ba46c7
 					dirsync = slapi_eq_repeat(periodic_dirsync, (void*) prp, (time_t)0 , interval);
ba46c7
+					slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
ba46c7
+					                "windows_inc_runs: new dirsync: %p\n", dirsync);
ba46c7
 				}
ba46c7
 
ba46c7
 				break;
ba46c7
@@ -605,7 +617,11 @@ windows_inc_run(Private_Repl_Protocol *prp)
ba46c7
 				  }
ba46c7
 				else
ba46c7
 				  {
ba46c7
-							/* Set up the backoff timer to wake us up at the appropriate time */
ba46c7
+					/* Set up the backoff timer to wake us up at the appropriate time */
ba46c7
+					/* if previous backoff set up, delete it. */
ba46c7
+					if (prp_priv->backoff) {
ba46c7
+						backoff_delete(&prp_priv->backoff);
ba46c7
+					}
ba46c7
 					if (use_busy_backoff_timer)
ba46c7
 					{
ba46c7
 					  /* we received a busy signal from the consumer, wait for a while */
ba46c7
@@ -648,14 +664,14 @@ windows_inc_run(Private_Repl_Protocol *prp)
ba46c7
 						run_dirsync = PR_TRUE;
ba46c7
 
ba46c7
 						windows_conn_set_agmt_changed(prp->conn);
ba46c7
-								/* Destroy the backoff timer, since we won't need it anymore */ 
ba46c7
+						/* Destroy the backoff timer, since we won't need it anymore */ 
ba46c7
 						if (prp_priv->backoff)   
ba46c7
 						  backoff_delete(&prp_priv->backoff);
ba46c7
 					  }
ba46c7
 					else if (event_occurred(prp, EVENT_WINDOW_CLOSED))
ba46c7
 					  {
ba46c7
 						next_state = STATE_WAIT_WINDOW_OPEN;
ba46c7
-								/* Destroy the backoff timer, since we won't need it anymore */
ba46c7
+						/* Destroy the backoff timer, since we won't need it anymore */
ba46c7
 						if (prp_priv->backoff)
ba46c7
 						  backoff_delete(&prp_priv->backoff);
ba46c7
 					  }
ba46c7
-- 
ba46c7
1.8.1.4
ba46c7