ldap/servers/plugins/sync/sync.h | 7 ++++---
ldap/servers/plugins/sync/sync_persist.c | 3 ++-
ldap/servers/plugins/sync/sync_refresh.c | 18 ++++++++++++------
3 files changed, 18 insertions(+), 10 deletions(-)
New commits:
commit d06de4e43234bbebbdb2ca4e57dbe17e26fcfe00
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Fri Dec 20 14:52:44 2013 +0100
Ticket 47629 - random crashes related to sync repl
Bug Description: if there is no cookie, the persist thread starts
before the initial refresh is complete, both threads use the
same operation structure and there is a race condition
on setting and freeing the search entry.
Fix Description: ensure that the persist thread only starts sending
updates once the refresh is complete
https://fedorahosted.org/389/ticket/47629
Reviewed by: Rich, thanks
diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h
index cf73ce9..8cdc7d0 100644
--- a/ldap/servers/plugins/sync/sync.h
+++ b/ldap/servers/plugins/sync/sync.h
@@ -115,7 +115,7 @@ int sync_is_active (Slapi_Entry *e, Slapi_PBlock *pb);
int sync_is_active_scope (const Slapi_DN *dn, Slapi_PBlock *pb);
int sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie *client_cookie, Sync_Cookie
*session_cookie);
-int sync_refresh_initial_content(Slapi_PBlock *pb, int persist, Sync_Cookie
*session_cookie);
+int sync_refresh_initial_content(Slapi_PBlock *pb, int persist, PRThread *tid,
Sync_Cookie *session_cookie);
int sync_read_entry_from_changelog( Slapi_Entry *cl_entry, void *cb_data);
int sync_send_entry_from_changelog( Slapi_PBlock *pb, int chg_req, char *uniqueid);
void sync_send_deleted_entries (Slapi_PBlock *pb, Sync_UpdateNode *upd, int chg_count,
Sync_Cookie *session_cookie);
@@ -190,7 +190,8 @@ typedef struct sync_request_list {
#define SYNC_FLAG_SEND_INTERMEDIATE 0x08
typedef struct sync_op_info {
- int send_flag; /* hint for preop plugins what to send */
- Sync_Cookie *cookie; /* cookie to add in control */
+ int send_flag; /* hint for preop plugins what to send */
+ Sync_Cookie *cookie;/* cookie to add in control */
+ PRThread *tid; /* thread for persistent phase */
} SyncOpInfo;
diff --git a/ldap/servers/plugins/sync/sync_persist.c
b/ldap/servers/plugins/sync/sync_persist.c
index 7cd65c8..680bcf6 100644
--- a/ldap/servers/plugins/sync/sync_persist.c
+++ b/ldap/servers/plugins/sync/sync_persist.c
@@ -351,7 +351,8 @@ sync_persist_terminate (PRThread *tid)
cur = sync_request_list->sync_req_head;
while ( NULL != cur ) {
if ( cur->req_tid == tid ) {
- cur->req_active = PR_TRUE;
+ cur->req_active = PR_FALSE;
+ cur->req_complete = PR_TRUE;
rc = 0;
break;
}
diff --git a/ldap/servers/plugins/sync/sync_refresh.c
b/ldap/servers/plugins/sync/sync_refresh.c
index 71a0edd..18f7884 100644
--- a/ldap/servers/plugins/sync/sync_refresh.c
+++ b/ldap/servers/plugins/sync/sync_refresh.c
@@ -37,7 +37,7 @@
#include "sync.h"
-static SyncOpInfo *new_SyncOpInfo(int flag, Sync_Cookie *cookie);
+static SyncOpInfo *new_SyncOpInfo(int flag, PRThread *tid, Sync_Cookie *cookie);
static int sync_extension_type;
static int sync_extension_handle;
@@ -157,7 +157,7 @@ int sync_srch_refresh_pre_search(Slapi_PBlock *pb)
sync_result_err(pb,rc, "Invalid session cookie");
}
} else {
- rc = sync_refresh_initial_content (pb, sync_persist, session_cookie);
+ rc = sync_refresh_initial_content (pb, sync_persist, tid, session_cookie);
if (rc == 0 && !sync_persist)
/* maintained in postop code */
session_cookie = NULL;
@@ -172,8 +172,9 @@ int sync_srch_refresh_pre_search(Slapi_PBlock *pb)
Slapi_Operation *operation;
slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
- rc = sync_persist_startup(tid, session_cookie);
-
+ if (client_cookie) {
+ rc = sync_persist_startup(tid, session_cookie);
+ }
if (rc == 0) {
session_cookie = NULL; /* maintained in persist code */
slapi_operation_set_flag(operation, OP_FLAG_SYNC_PERSIST);
@@ -216,6 +217,8 @@ int sync_srch_refresh_post_search(Slapi_PBlock *pb)
* depending on the operation type, reset flag
*/
info->send_flag &= ~SYNC_FLAG_ADD_STATE_CTRL;
+ /* activate the persistent phase thread*/
+ sync_persist_startup(info->tid, info->cookie);
}
if (info->send_flag & SYNC_FLAG_ADD_DONE_CTRL) {
LDAPControl **ctrl = (LDAPControl **)slapi_ch_calloc(2, sizeof (LDAPControl *));
@@ -320,7 +323,7 @@ sync_refresh_update_content(Slapi_PBlock *pb, Sync_Cookie
*client_cookie, Sync_C
}
int
-sync_refresh_initial_content(Slapi_PBlock *pb, int sync_persist, Sync_Cookie *sc)
+sync_refresh_initial_content(Slapi_PBlock *pb, int sync_persist, PRThread *tid,
Sync_Cookie *sc)
{
/* the entries will be sent in the normal search process, but
* - a control has to be sent with each entry
@@ -341,11 +344,13 @@ sync_refresh_initial_content(Slapi_PBlock *pb, int sync_persist,
Sync_Cookie *sc
(SYNC_FLAG_ADD_STATE_CTRL |
SYNC_FLAG_SEND_INTERMEDIATE |
SYNC_FLAG_NO_RESULT,
+ tid,
sc);
} else {
info = new_SyncOpInfo
(SYNC_FLAG_ADD_STATE_CTRL |
SYNC_FLAG_ADD_DONE_CTRL,
+ tid,
sc);
}
sync_set_operation_extension(pb, info);
@@ -672,10 +677,11 @@ sync_send_entry_from_changelog(Slapi_PBlock *pb,int chg_req, char
*uniqueid)
}
static SyncOpInfo*
-new_SyncOpInfo(int flag, Sync_Cookie *cookie) {
+new_SyncOpInfo(int flag, PRThread *tid, Sync_Cookie *cookie) {
SyncOpInfo *spec = (SyncOpInfo *)slapi_ch_calloc(1, sizeof(SyncOpInfo));
spec->send_flag = flag;
spec->cookie = cookie;
+ spec->tid = tid;
return spec;
}