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