andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 574de972761ac0602dcbce14a4f98dc2fd37874d Mon Sep 17 00:00:00 2001
dc8c34
From: Noriko Hosoi <nhosoi@redhat.com>
dc8c34
Date: Fri, 1 Nov 2013 14:24:55 -0700
dc8c34
Subject: [PATCH 145/225] Ticket #47581 - Winsync plugin segfault during
dc8c34
 incremental backoff
dc8c34
dc8c34
Bug description: Once WinSync backoff timer is set, even if the
dc8c34
protocol that the backoff timer belongs to is deleted by removing
dc8c34
the windows sync agreement, the timer is not deleted from the event
dc8c34
queue.  Thus the timer is expired and backoff is called, it crashes
dc8c34
the server since the protocol handle is already freed, then.
dc8c34
dc8c34
Fix description: Make sure to delete the backoff timer when
dc8c34
1) a windows sync agreement is removed and the protocol is deleted, and
dc8c34
2) a new backoff timer set and there is already a backoff timer set up.
dc8c34
dc8c34
In addition to commit d70e66b2157ce3ba40c5e1cb074c2d5c150ddc5b,
dc8c34
the 389-ds-base-1.2.11 patch includes this change that is already made
dc8c34
on 389-ds-base-1.3.1 and newer.
dc8c34
  windows_inc_run
dc8c34
+   if(dirsync){
dc8c34
+       int rc = slapi_eq_cancel(dirsync);
dc8c34
+   }
dc8c34
dc8c34
https://fedorahosted.org/389/ticket/47581
dc8c34
dc8c34
(cherry picked from commit d70e66b2157ce3ba40c5e1cb074c2d5c150ddc5b)
dc8c34
(cherry picked from commit 91d45ff69388e529225ad729c2f48cc35c57c4f4)
dc8c34
---
dc8c34
 .../plugins/replication/windows_inc_protocol.c     | 66 ++++++++++++++--------
dc8c34
 1 file changed, 41 insertions(+), 25 deletions(-)
dc8c34
dc8c34
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
dc8c34
index 15d69a3..321d1a2 100644
dc8c34
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
dc8c34
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
dc8c34
@@ -157,27 +157,34 @@ static Slapi_Eq_Context dirsync;
dc8c34
 static void
dc8c34
 windows_inc_delete(Private_Repl_Protocol **prpp)
dc8c34
 {
dc8c34
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_inc_delete\n" );
dc8c34
-	/* First, stop the protocol if it isn't already stopped */
dc8c34
-	/* Then, delete all resources used by the protocol */
dc8c34
-	slapi_eq_cancel(dirsync); 
dc8c34
-
dc8c34
-        if (!(*prpp)->stopped) {
dc8c34
-                (*prpp)->stopped = 1;
dc8c34
-                (*prpp)->stop(*prpp);
dc8c34
-        }
dc8c34
-        if ((*prpp)->lock) {
dc8c34
-                PR_DestroyLock((*prpp)->lock);
dc8c34
-                (*prpp)->lock = NULL;
dc8c34
-        }
dc8c34
-        if ((*prpp)->cvar) {
dc8c34
-                PR_DestroyCondVar((*prpp)->cvar);
dc8c34
-                (*prpp)->cvar = NULL;
dc8c34
-        }
dc8c34
-        slapi_ch_free((void **)&(*prpp)->private);
dc8c34
-        slapi_ch_free((void **)prpp);
dc8c34
-
dc8c34
-	LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_inc_delete\n" );
dc8c34
+    int rc;
dc8c34
+    windows_inc_private *prp_priv = (windows_inc_private *)(*prpp)->private;
dc8c34
+    LDAPDebug0Args( LDAP_DEBUG_TRACE, "=> windows_inc_delete\n" );
dc8c34
+    /* First, stop the protocol if it isn't already stopped */
dc8c34
+    /* Then, delete all resources used by the protocol */
dc8c34
+    rc = slapi_eq_cancel(dirsync); 
dc8c34
+    slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
dc8c34
+                    "windows_inc_delete: dirsync: %p, rval: %d\n", dirsync, rc);
dc8c34
+    /* if backoff is set, delete it (from EQ, as well) */
dc8c34
+    if (prp_priv->backoff) {
dc8c34
+        backoff_delete(&prp_priv->backoff);
dc8c34
+    }
dc8c34
+    if (!(*prpp)->stopped) {
dc8c34
+        (*prpp)->stopped = 1;
dc8c34
+        (*prpp)->stop(*prpp);
dc8c34
+    }
dc8c34
+    if ((*prpp)->lock) {
dc8c34
+        PR_DestroyLock((*prpp)->lock);
dc8c34
+        (*prpp)->lock = NULL;
dc8c34
+    }
dc8c34
+    if ((*prpp)->cvar) {
dc8c34
+        PR_DestroyCondVar((*prpp)->cvar);
dc8c34
+        (*prpp)->cvar = NULL;
dc8c34
+    }
dc8c34
+    slapi_ch_free((void **)&(*prpp)->private);
dc8c34
+    slapi_ch_free((void **)prpp);
dc8c34
+
dc8c34
+    LDAPDebug0Args( LDAP_DEBUG_TRACE, "<= windows_inc_delete\n" );
dc8c34
 }
dc8c34
 
dc8c34
 /* helper function */
dc8c34
@@ -357,7 +364,6 @@ windows_inc_run(Private_Repl_Protocol *prp)
dc8c34
 					w_set_pause_and_busy_time(&pausetime, &busywaittime);
dc8c34
 				}
dc8c34
 
dc8c34
-
dc8c34
 				if (is_first_start) {
dc8c34
 					unsigned long interval = windows_private_get_sync_interval(prp->agmt) * 1000;
dc8c34
 					/*
dc8c34
@@ -365,6 +371,12 @@ windows_inc_run(Private_Repl_Protocol *prp)
dc8c34
 					 * and the repeat interval. 
dc8c34
 					 */ 
dc8c34
 					/* DBDB: we should probably make this polling interval configurable */
dc8c34
+					if(dirsync){
dc8c34
+						int rc = slapi_eq_cancel(dirsync);
dc8c34
+						slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
dc8c34
+						                "windows_inc_runs: cancelled dirsync: %p, rval: %d\n",
dc8c34
+						                dirsync, rc);
dc8c34
+					}
dc8c34
 					dirsync = slapi_eq_repeat(periodic_dirsync, (void*) prp, (time_t)0 , interval);
dc8c34
 					is_first_start = PR_FALSE;
dc8c34
 				}
dc8c34
@@ -606,7 +618,11 @@ windows_inc_run(Private_Repl_Protocol *prp)
dc8c34
 				  }
dc8c34
 				else
dc8c34
 				  {
dc8c34
-							/* Set up the backoff timer to wake us up at the appropriate time */
dc8c34
+					/* Set up the backoff timer to wake us up at the appropriate time */
dc8c34
+					/* if previous backoff set up, delete it. */
dc8c34
+					if (prp_priv->backoff) {
dc8c34
+						backoff_delete(&prp_priv->backoff);
dc8c34
+					}
dc8c34
 					if (use_busy_backoff_timer)
dc8c34
 					{
dc8c34
 					  /* we received a busy signal from the consumer, wait for a while */
dc8c34
@@ -651,14 +667,14 @@ windows_inc_run(Private_Repl_Protocol *prp)
dc8c34
 						run_dirsync = PR_TRUE;
dc8c34
 
dc8c34
 						windows_conn_set_agmt_changed(prp->conn);
dc8c34
-								/* Destroy the backoff timer, since we won't need it anymore */ 
dc8c34
+						/* Destroy the backoff timer, since we won't need it anymore */ 
dc8c34
 						if (prp_priv->backoff)   
dc8c34
 						  backoff_delete(&prp_priv->backoff);
dc8c34
 					  }
dc8c34
 					else if (event_occurred(prp, EVENT_WINDOW_CLOSED))
dc8c34
 					  {
dc8c34
 						next_state = STATE_WAIT_WINDOW_OPEN;
dc8c34
-								/* Destroy the backoff timer, since we won't need it anymore */
dc8c34
+						/* Destroy the backoff timer, since we won't need it anymore */
dc8c34
 						if (prp_priv->backoff)
dc8c34
 						  backoff_delete(&prp_priv->backoff);
dc8c34
 					  }
dc8c34
-- 
dc8c34
1.8.1.4
dc8c34