syncrepl consistency patch

This commit is contained in:
Jong Hyuk Choi 2004-10-09 09:26:16 +00:00
parent baa76b6f35
commit 4efd705cc3
6 changed files with 446 additions and 58 deletions

View File

@ -96,6 +96,7 @@ LDAP_BEGIN_DECL
#define LDAP_DEBUG_PARSE 0x0800
#define LDAP_DEBUG_CACHE 0x1000
#define LDAP_DEBUG_INDEX 0x2000
#define LDAP_DEBUG_SYNC 0x4000
#define LDAP_DEBUG_NONE 0x8000
#define LDAP_DEBUG_ANY -1

View File

@ -366,6 +366,17 @@ retry: /* transaction retry */
goto return_results;
}
ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREDELETE );
if ( rc ) {
Debug( LDAP_DEBUG_TRACE,
"bdb_delete: persistent search failed (%d,%d)\n",
rc, rs->sr_err, 0 );
}
}
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
/* delete from dn2id */
rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e );
if ( rs->sr_err != 0 ) {

View File

@ -45,6 +45,9 @@ static void send_paged_response(
ID *lastid,
int tentries );
static int bdb_pfid_cmp( const void *v_id1, const void *v_id2 );
static ID* bdb_id_dup( Operation *op, ID *id );
/* Dereference aliases for a single alias entry. Return the final
* dereferenced entry on success, NULL on any failure.
*/
@ -306,6 +309,7 @@ sameido:
#define IS_BDB_REPLACE(type) (( type == LDAP_PSEARCH_BY_DELETE ) || \
( type == LDAP_PSEARCH_BY_SCOPEOUT ))
#define IS_PSEARCH (op != sop)
#define IS_POST_SEARCH ( op->ors_post_search_id != NOID )
static Operation *
bdb_drop_psearch( Operation *op, ber_int_t msgid )
@ -369,19 +373,170 @@ bdb_cancel( Operation *op, SlapReply *rs )
int bdb_search( Operation *op, SlapReply *rs )
{
return bdb_do_search( op, rs, op, NULL, 0 );
int rc;
struct pc_entry *pce = NULL;
struct pc_entry *tmp_pce = NULL;
Entry ps_e = {0};
Attribute *a;
ps_e.e_private = NULL;
ldap_pvt_thread_mutex_init( &op->o_pcmutex );
LDAP_TAILQ_INIT( &op->o_ps_pre_candidates );
LDAP_TAILQ_INIT( &op->o_ps_post_candidates );
op->ors_post_search_id = NOID;
rc = bdb_do_search( op, rs, op, NULL, 0 );
ldap_pvt_thread_mutex_lock( &op->o_pcmutex );
pce = LDAP_TAILQ_FIRST( &op->o_ps_post_candidates );
ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
while ( rc == LDAP_SUCCESS && pce &&
op->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) {
ps_e.e_id = op->ors_post_search_id = pce->pc_id;
if ( op->o_sync_csn.bv_val ) {
ch_free( op->o_sync_csn.bv_val );
op->o_sync_csn.bv_val = NULL;
}
ber_dupbv( &op->o_sync_csn, &pce->pc_csn );
ber_dupbv( &ps_e.e_name, &pce->pc_ename );
ber_dupbv( &ps_e.e_nname, &pce->pc_enname );
a = ch_calloc( 1, sizeof( Attribute ));
a->a_desc = slap_schema.si_ad_entryUUID;
a->a_vals = ch_calloc( 2, sizeof( struct berval ));
ber_dupbv( &a->a_vals[0], &pce->pc_entryUUID );
a->a_nvals = a->a_vals;
a->a_next = NULL;
ps_e.e_attrs = a;
rc = bdb_do_search( op, rs, op, &ps_e, 0 );
tmp_pce = pce;
ldap_pvt_thread_mutex_lock( &op->o_pcmutex );
pce = LDAP_TAILQ_NEXT( pce, pc_link );
LDAP_TAILQ_REMOVE( &op->o_ps_post_candidates, tmp_pce, pc_link );
ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
ch_free( tmp_pce->pc_csn.bv_val );
ch_free( tmp_pce->pc_entryUUID.bv_val );
ch_free( tmp_pce->pc_ename.bv_val );
ch_free( tmp_pce->pc_enname.bv_val );
ch_free( tmp_pce );
entry_clean( &ps_e );
}
return rc;
}
int bdb_psearch( Operation *op, SlapReply *rs, Operation *sop,
Entry *ps_e, int ps_type )
{
int rc;
struct pc_entry *pce = NULL;
struct pc_entry *p = NULL;
sop->o_private = op->o_private;
rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
sop->o_private = NULL;
op->ors_post_search_id = NOID;
return rc;
switch (ps_type) {
case LDAP_PSEARCH_BY_PREMODIFY:
case LDAP_PSEARCH_BY_PREDELETE:
if ( sop->o_refresh_in_progress ) {
pce = (struct pc_entry *) ch_calloc( 1, sizeof( struct pc_entry ));
pce->pc_id = ps_e->e_id;
ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
if ( LDAP_TAILQ_EMPTY( &sop->o_ps_pre_candidates )) {
LDAP_TAILQ_INSERT_HEAD( &sop->o_ps_pre_candidates, pce, pc_link );
} else {
LDAP_TAILQ_FOREACH( p, &sop->o_ps_pre_candidates, pc_link ) {
if ( p->pc_id > pce->pc_id )
break;
}
if ( p ) {
LDAP_TAILQ_INSERT_BEFORE( p, pce, pc_link );
} else {
LDAP_TAILQ_INSERT_TAIL(
&sop->o_ps_pre_candidates,
pce, pc_link );
}
}
ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
} else {
rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
return rc;
}
/* Wait until refresh search send the entry */
while ( !pce->pc_sent ) {
if ( sop->o_refresh_in_progress ) {
ldap_pvt_thread_yield();
} else {
break;
}
}
if ( !sop->o_refresh_in_progress && !pce->pc_sent ) {
/* refresh ended without processing pce */
/* need to perform psearch for ps_e */
ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
LDAP_TAILQ_REMOVE( &sop->o_ps_pre_candidates, pce, pc_link );
ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
ch_free( pce );
rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
return rc;
} else {
/* the pce entry was sent in the refresh phase */
if ( ps_type == LDAP_PSEARCH_BY_PREMODIFY ) {
struct psid_entry* psid_e;
psid_e = (struct psid_entry *) ch_calloc(1,
sizeof(struct psid_entry));
psid_e->ps_op = sop;
LDAP_LIST_INSERT_HEAD( &op->o_pm_list, psid_e, ps_link );
}
ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
LDAP_TAILQ_REMOVE( &sop->o_ps_pre_candidates, pce, pc_link );
ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
ch_free( pce );
return LDAP_SUCCESS;
}
break;
case LDAP_PSEARCH_BY_DELETE:
case LDAP_PSEARCH_BY_SCOPEOUT:
case LDAP_PSEARCH_BY_ADD:
case LDAP_PSEARCH_BY_MODIFY:
ldap_pvt_thread_mutex_lock( &op->o_pcmutex );
if ( sop->o_refresh_in_progress ||
!LDAP_TAILQ_EMPTY( &sop->o_ps_post_candidates )) {
pce = (struct pc_entry *) ch_calloc( 1, sizeof( struct pc_entry ));
pce->pc_id = ps_e->e_id;
// pce->ps_type = ps_type;
ber_dupbv( &pce->pc_csn, &op->o_sync_csn );
if ( ps_type == LDAP_PSEARCH_BY_DELETE ) {
Attribute *a;
for ( a = ps_e->e_attrs; a != NULL; a = a->a_next ) {
AttributeDescription *desc = a->a_desc;
if ( desc == slap_schema.si_ad_entryUUID ) {
ber_dupbv( &pce->pc_entryUUID, &a->a_nvals[0] );
}
}
}
ber_dupbv( &pce->pc_ename, &ps_e->e_name );
ber_dupbv( &pce->pc_enname, &ps_e->e_nname );
LDAP_TAILQ_INSERT_TAIL( &sop->o_ps_post_candidates, pce, pc_link );
ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
} else {
ldap_pvt_thread_mutex_unlock( &op->o_pcmutex );
rc = bdb_do_search( op, rs, sop, ps_e, ps_type );
return rc;
}
break;
default:
Debug( LDAP_DEBUG_TRACE, "do_psearch: invalid psearch type\n",
0, 0, 0 );
return LDAP_OTHER;
}
}
/* For persistent searches, op is the currently executing operation,
@ -428,6 +583,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
const char *text;
int slog_found = 0;
struct pc_entry *pce = NULL;
BerVarray syncUUID_set = NULL;
int syncUUID_set_cnt = 0;
@ -439,7 +595,8 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
opinfo = (struct bdb_op_info *) op->o_private;
if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) {
if ( !IS_POST_SEARCH && !IS_PSEARCH &&
sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) {
struct slap_session_entry *sent;
if ( sop->o_sync_state.sid >= 0 ) {
LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) {
@ -452,14 +609,16 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
}
/* psearch needs to be registered before refresh begins */
/* psearch and refresh transmission is serialized in send_ldap_ber() */
if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_PERSIST ) {
if ( !IS_POST_SEARCH && !IS_PSEARCH &&
sop->o_sync_mode & SLAP_SYNC_PERSIST ) {
sop->o_refresh_in_progress = 1;
ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_INSERT_HEAD( &bdb->bi_psearch_list, sop, o_ps_link );
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
} else if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST
&& sop->o_sync_slog_size >= 0 )
} else if ( !IS_POST_SEARCH && !IS_PSEARCH &&
sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST
&& sop->o_sync_slog_size >= 0 )
{
ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
@ -545,6 +704,14 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
}
}
if ( IS_POST_SEARCH ) {
cursor = 0;
candidates[0] = 1;
candidates[1] = op->ors_post_search_id;
search_context_csn = ber_dupbv( NULL, &op->o_sync_csn );
goto loop_start;
}
if ( sop->o_req_ndn.bv_len == 0 ) {
/* DIT root special case */
ei_root.bei_e = &e_root;
@ -876,13 +1043,64 @@ dn2entry_retry:
}
}
loop_start:
for ( id = bdb_idl_first( candidates, &cursor );
id != NOID && !no_sync_state_change;
id != NOID && !no_sync_state_change;
id = bdb_idl_next( candidates, &cursor ) )
{
int scopeok = 0;
ID* idhole = NULL;
loop_begin:
if ( !IS_POST_SEARCH ) {
idhole = (ID*) avl_find( sop->o_psearch_finished,
(caddr_t)&id, bdb_pfid_cmp );
if ( idhole ) {
avl_delete( &sop->o_psearch_finished,
(caddr_t)idhole, bdb_pfid_cmp );
sop->o_tmpfree( idhole, sop->o_tmpmemctx );
goto loop_continue;
}
if ( sop->o_refresh_in_progress ) {
ldap_pvt_thread_mutex_lock( &sop->o_pcmutex );
pce = LDAP_TAILQ_FIRST( &sop->o_ps_pre_candidates );
while ( pce && pce->pc_sent ) {
pce = LDAP_TAILQ_NEXT( pce, pc_link );
}
ldap_pvt_thread_mutex_unlock( &sop->o_pcmutex );
if ( pce ) {
ID pos;
if ( BDB_IDL_IS_RANGE( candidates ) ) {
if ( pce->pc_id >= candidates[1] &&
pce->pc_id <= candidates[2] &&
pce->pc_id > cursor-1 ) {
id = pce->pc_id;
cursor--;
avl_insert( &sop->o_psearch_finished,
(caddr_t)bdb_id_dup( sop, &pce->pc_id ),
bdb_pfid_cmp, avl_dup_error );
} else {
pce->pc_sent = 1;
}
} else {
pos = bdb_idl_search(candidates, pce->pc_id);
if ( pos > cursor-1 && pos <= candidates[0] ) {
id = pce->pc_id;
cursor--;
avl_insert( &sop->o_psearch_finished,
(caddr_t)bdb_id_dup( sop, &pce->pc_id ),
bdb_pfid_cmp, avl_dup_error );
} else {
pce->pc_sent = 1;
}
}
}
}
}
/* check for abandon */
if ( sop->o_abandon ) {
if ( sop != op ) {
@ -937,7 +1155,11 @@ id2entry_retry:
}
if ( e == NULL ) {
if( !BDB_IDL_IS_RANGE(candidates) ) {
if ( IS_POST_SEARCH ) {
/* send LDAP_SYNC_DELETE */
rs->sr_entry = e = ps_e;
goto post_search_no_entry;
} else if( !BDB_IDL_IS_RANGE(candidates) ) {
/* only complain for non-range IDLs */
Debug( LDAP_DEBUG_TRACE,
"bdb_search: candidate %ld not found\n",
@ -1049,7 +1271,7 @@ id2entry_retry:
#endif
/* Not in scope, ignore it */
if ( !scopeok ) {
if ( !IS_POST_SEARCH && !scopeok ) {
Debug( LDAP_DEBUG_TRACE,
"bdb_search: %ld scope not okay\n",
(long) id, 0, 0 );
@ -1091,29 +1313,39 @@ id2entry_retry:
}
} else {
if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
rc_sync = test_filter( sop, rs->sr_entry, &cookief );
rs->sr_err = test_filter( sop, rs->sr_entry, &contextcsnand );
if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
if ( rc_sync == LDAP_COMPARE_TRUE ) {
if ( no_sync_state_change ) {
Debug( LDAP_DEBUG_TRACE,
"bdb_search: error in context csn management\n",
0, 0, 0 );
}
entry_sync_state = LDAP_SYNC_ADD;
if ( !IS_POST_SEARCH ) {
if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
rc_sync = test_filter( sop, rs->sr_entry, &cookief );
rs->sr_err = test_filter( sop, rs->sr_entry,
&contextcsnand );
if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
if ( rc_sync == LDAP_COMPARE_TRUE ) {
if ( no_sync_state_change ) {
Debug( LDAP_DEBUG_TRACE,
"bdb_search: "
"error in context csn management\n",
0, 0, 0 );
}
entry_sync_state = LDAP_SYNC_ADD;
} else {
if ( no_sync_state_change ) {
goto loop_continue;
} else {
if ( no_sync_state_change ) {
goto loop_continue;
}
entry_sync_state = LDAP_SYNC_PRESENT;
}
entry_sync_state = LDAP_SYNC_PRESENT;
}
} else {
rs->sr_err = test_filter( sop,
rs->sr_entry, sop->oq_search.rs_filter );
}
} else {
rs->sr_err = test_filter( sop,
rs->sr_entry, sop->oq_search.rs_filter );
if ( scopeok ) {
rs->sr_err = test_filter( sop,
rs->sr_entry, sop->oq_search.rs_filter );
} else {
rs->sr_err = LDAP_COMPARE_TRUE;
}
}
}
@ -1147,16 +1379,17 @@ id2entry_retry:
/* safe default */
int result = -1;
if (IS_PSEARCH) {
if (IS_PSEARCH || IS_POST_SEARCH) {
int premodify_found = 0;
int entry_sync_state;
if ( ps_type == LDAP_PSEARCH_BY_ADD ||
if ( IS_POST_SEARCH ||
ps_type == LDAP_PSEARCH_BY_ADD ||
ps_type == LDAP_PSEARCH_BY_DELETE ||
ps_type == LDAP_PSEARCH_BY_MODIFY ||
ps_type == LDAP_PSEARCH_BY_SCOPEOUT )
{
if ( ps_type == LDAP_PSEARCH_BY_MODIFY ) {
if ( !IS_POST_SEARCH &&
ps_type == LDAP_PSEARCH_BY_MODIFY ) {
struct psid_entry* psid_e;
LDAP_LIST_FOREACH( psid_e,
&op->o_pm_list, ps_link)
@ -1170,7 +1403,14 @@ id2entry_retry:
if (psid_e != NULL) free (psid_e);
}
if ( ps_type == LDAP_PSEARCH_BY_ADD ) {
if ( IS_POST_SEARCH ) {
if ( scopeok ) {
entry_sync_state = LDAP_SYNC_ADD;
} else {
post_search_no_entry:
entry_sync_state = LDAP_SYNC_DELETE;
}
} else if ( ps_type == LDAP_PSEARCH_BY_ADD ) {
entry_sync_state = LDAP_SYNC_ADD;
} else if ( ps_type == LDAP_PSEARCH_BY_DELETE ) {
entry_sync_state = LDAP_SYNC_DELETE;
@ -1199,11 +1439,16 @@ id2entry_retry:
search_context_csn,
sop->o_sync_state.sid,
sop->o_sync_state.rid );
rs->sr_err = slap_build_sync_state_ctrl( sop,
rs, e, entry_sync_state, ctrls,
rs->sr_err = slap_build_sync_state_ctrl(
sop, rs, e, entry_sync_state, ctrls,
num_ctrls++, 1, &cookie );
if ( rs->sr_err != LDAP_SUCCESS ) goto done;
rs->sr_attrs = attrs;
if (!(IS_POST_SEARCH &&
entry_sync_state == LDAP_SYNC_DELETE)) {
rs->sr_attrs = attrs;
} else {
rs->sr_attrs = NULL;
}
rs->sr_operational_attrs = NULL;
rs->sr_ctrls = ctrls;
rs->sr_flags = 0;
@ -1235,8 +1480,8 @@ id2entry_retry:
} else {
if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */
rs->sr_err = slap_build_sync_state_ctrl( sop,
rs, e, entry_sync_state, ctrls,
rs->sr_err = slap_build_sync_state_ctrl(
sop, rs, e, entry_sync_state, ctrls,
num_ctrls++, 0, NULL );
if ( rs->sr_err != LDAP_SUCCESS ) goto done;
rs->sr_ctrls = ctrls;
@ -1321,15 +1566,24 @@ loop_continue:
if( e != NULL ) {
/* free reader lock */
if (!IS_PSEARCH) {
bdb_cache_return_entry_r( bdb->bi_dbenv,
&bdb->bi_cache, e , &lock );
if ( sop->o_nocaching ) {
bdb_cache_delete_entry( bdb, ei, locker, &lock );
if (!(IS_POST_SEARCH &&
entry_sync_state == LDAP_SYNC_DELETE)) {
bdb_cache_return_entry_r( bdb->bi_dbenv,
&bdb->bi_cache, e , &lock );
if ( sop->o_nocaching ) {
bdb_cache_delete_entry( bdb, ei, locker, &lock );
}
}
}
e = NULL;
rs->sr_entry = NULL;
}
if ( sop->o_refresh_in_progress ) {
if ( pce ) {
pce->pc_sent = 1;
}
}
ldap_pvt_thread_yield();
}
@ -1345,7 +1599,7 @@ loop_continue:
}
nochange:
if (!IS_PSEARCH) {
if (!IS_PSEARCH && !IS_POST_SEARCH) {
if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) {
if ( sop->o_sync_mode & SLAP_SYNC_PERSIST ) {
struct berval cookie;
@ -1458,9 +1712,17 @@ nochange:
}
}
if ( sop->o_refresh_in_progress ) {
sop->o_refresh_in_progress = 0;
}
rs->sr_err = LDAP_SUCCESS;
done:
if ( sop->o_psearch_finished ) {
avl_free( sop->o_psearch_finished, ch_free );
}
if( !IS_PSEARCH && e != NULL ) {
/* free reader lock */
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
@ -1849,3 +2111,18 @@ done:
(void) ber_free_buf( ber );
}
static int
bdb_pfid_cmp( const void *v_id1, const void *v_id2 )
{
const ID *p1 = v_id1, *p2 = v_id2;
return *p1 - *p2;
}
static ID*
bdb_id_dup( Operation *op, ID *id )
{
ID *new;
new = ch_malloc( sizeof(ID) );
*new = *id;
return new;
}

View File

@ -694,8 +694,8 @@ LDAP_SLAPD_V (int) krbv4_ldap_auth();
* ldapsync.c
*/
LDAP_SLAPD_F (int) slap_build_sync_state_ctrl LDAP_P((
Operation *, SlapReply *, Entry *, int, LDAPControl **,
int, int, struct berval * ));
Operation *, SlapReply *, Entry *, int,
LDAPControl **, int, int, struct berval * ));
LDAP_SLAPD_F (int) slap_build_sync_done_ctrl LDAP_P((
Operation *, SlapReply *, LDAPControl **,
int, int, struct berval *, int ));

View File

@ -1662,6 +1662,7 @@ typedef struct req_search_s {
AttributeName *rs_attrs;
Filter *rs_filter;
struct berval rs_filterstr;
int rs_post_search_id;
} req_search_s;
typedef struct req_compare_s {
@ -1998,6 +1999,7 @@ typedef struct slap_paged_state {
#define LDAP_PSEARCH_BY_PREMODIFY 0x03
#define LDAP_PSEARCH_BY_MODIFY 0x04
#define LDAP_PSEARCH_BY_SCOPEOUT 0x05
#define LDAP_PSEARCH_BY_PREDELETE 0x06
struct psid_entry {
struct slap_op *ps_op;
@ -2029,6 +2031,16 @@ struct slap_csn_entry {
LDAP_TAILQ_ENTRY (slap_csn_entry) ce_csn_link;
};
struct pc_entry {
ID pc_id;
int pc_sent;
struct berval pc_csn;
struct berval pc_entryUUID;
struct berval pc_ename;
struct berval pc_enname;
LDAP_TAILQ_ENTRY( pc_entry ) pc_link;
};
/*
* Caches the result of a backend_group check for ACL evaluation
*/
@ -2101,6 +2113,7 @@ typedef struct slap_op {
#define ors_attrs oq_search.rs_attrs
#define ors_filter oq_search.rs_filter
#define ors_filterstr oq_search.rs_filterstr
#define ors_post_search_id oq_search.rs_post_search_id
#define orr_newrdn oq_modrdn.rs_newrdn
#define orr_nnewrdn oq_modrdn.rs_nnewrdn
@ -2202,6 +2215,12 @@ typedef struct slap_op {
LDAP_LIST_ENTRY(slap_op) o_ps_link;
LDAP_LIST_HEAD(pe, psid_entry) o_pm_list;
int o_refresh_in_progress;
LDAP_TAILQ_HEAD(pc_pre, pc_entry) o_ps_pre_candidates;
LDAP_TAILQ_HEAD(pc_post, pc_entry) o_ps_post_candidates;
Avlnode *o_psearch_finished;
ldap_pvt_thread_mutex_t o_pcmutex;
AuthorizationInformation o_authz;
BerElement *o_ber; /* ber of the request */

View File

@ -48,6 +48,9 @@ static int dn_callback( struct slap_op *, struct slap_rep * );
static int nonpresent_callback( struct slap_op *, struct slap_rep * );
static int null_callback( struct slap_op *, struct slap_rep * );
static int si_refreshDelete = 0;
static int si_refreshPresent = 0;
static AttributeDescription *sync_descs[4];
struct runqueue_s syncrepl_rq;
@ -588,7 +591,7 @@ do_syncrep2(
ldap_get_entry_controls( si->si_ld, msg, &rctrls );
/* we can't work without the control */
if ( !rctrls ) {
Debug( LDAP_DEBUG_ANY, "do_syncrep2 : "
Debug( LDAP_DEBUG_ANY, "do_syncrep2: "
"got search entry without "
"control\n", 0, 0, 0 );
rc = -1;
@ -632,10 +635,12 @@ do_syncrep2(
case LDAP_RES_SEARCH_REFERENCE:
Debug( LDAP_DEBUG_ANY,
"do_syncrep2 : reference received\n", 0, 0, 0 );
"do_syncrep2: reference received error\n", 0, 0, 0 );
break;
case LDAP_RES_SEARCH_RESULT:
Debug( LDAP_DEBUG_SYNC,
"do_syncrep2: LDAP_RES_SEARCH_RESULT\n", 0, 0, 0 );
ldap_parse_result( si->si_ld, msg, &err, NULL, NULL, NULL,
&rctrls, 0 );
if ( rctrls ) {
@ -703,18 +708,31 @@ do_syncrep2(
rc = ldap_parse_intermediate( si->si_ld, msg,
&retoid, &retdata, NULL, 0 );
if ( !rc && !strcmp( retoid, LDAP_SYNC_INFO ) ) {
int si_refreshDelete = 0;
int si_refreshPresent = 0;
ber_init2( ber, retdata, LBER_USE_DER );
switch ( si_tag = ber_peek_tag( ber, &len )) {
ber_tag_t tag;
case LDAP_TAG_SYNC_NEW_COOKIE:
Debug( LDAP_DEBUG_SYNC,
"do_syncrep2: %s - %s%s\n",
"LDAP_RES_INTERMEDIATE",
"NEW_COOKIE", "\n" );
ber_scanf( ber, "tm", &tag, &cookie );
break;
case LDAP_TAG_SYNC_REFRESH_DELETE:
Debug( LDAP_DEBUG_SYNC,
"do_syncrep2: %s - %s%s\n",
"LDAP_RES_INTERMEDIATE",
"REFRESH_DELETE\n", "\n" );
si_refreshDelete = 1;
case LDAP_TAG_SYNC_REFRESH_PRESENT:
Debug( LDAP_DEBUG_SYNC,
"do_syncrep2: %s - %s%s\n",
"LDAP_RES_INTERMEDIATE",
si_tag == LDAP_TAG_SYNC_REFRESH_PRESENT ?
"REFRESH_PRESENT" : "REFRESH_DELETE",
"\n" );
si_refreshDelete = 1;
si_refreshPresent = 1;
ber_scanf( ber, "t{" /*"}"*/, &tag );
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE )
@ -740,6 +758,11 @@ do_syncrep2(
ber_scanf( ber, /*"{"*/ "}" );
break;
case LDAP_TAG_SYNC_ID_SET:
Debug( LDAP_DEBUG_SYNC,
"do_syncrep2: %s - %s%s\n",
"LDAP_RES_INTERMEDIATE",
"SYNC_ID_SET",
"\n" );
ber_scanf( ber, "t{" /*"}"*/, &tag );
if ( ber_peek_tag( ber, &len ) ==
LDAP_TAG_SYNC_COOKIE )
@ -775,8 +798,8 @@ do_syncrep2(
slap_sl_free( syncUUIDs, op->o_tmpmemctx );
break;
default:
Debug( LDAP_DEBUG_ANY,
"do_syncrep2 : unknown syncinfo tag (%ld)\n",
Debug( LDAP_DEBUG_ANY,
"do_syncrep2 : unknown syncinfo tag (%ld)\n",
(long) si_tag, 0, 0 );
ldap_memfree( retoid );
ber_bvfree( retdata );
@ -919,6 +942,8 @@ do_syncrepl(
/* Establish session, do search */
if ( !si->si_ld ) {
first = 1;
si_refreshDelete = 0;
si_refreshPresent = 0;
rc = do_syncrep1( &op, si );
}
@ -1170,10 +1195,42 @@ syncrepl_entry(
struct berval org_ndn = BER_BVNULL;
int org_managedsait;
Debug( LDAP_DEBUG_SYNC, "%s: %s",
"syncrepl_entry",
"LDAP_RES_SEARCH_ENTRY", 0 );
switch( syncstate ) {
case LDAP_SYNC_PRESENT:
Debug( LDAP_DEBUG_SYNC, "%s: %s",
"syncrepl_entry",
"LDAP_SYNC_PRESENT", "\n" );
break;
case LDAP_SYNC_ADD:
Debug( LDAP_DEBUG_SYNC, "%s: %s",
"syncrepl_entry",
"LDAP_SYNC_ADD", "\n" );
break;
case LDAP_SYNC_DELETE:
Debug( LDAP_DEBUG_SYNC, "%s: %s",
"syncrepl_entry",
"LDAP_SYNC_DELETE", "\n" );
break;
case LDAP_SYNC_MODIFY:
Debug( LDAP_DEBUG_SYNC, "%s: %s",
"syncrepl_entry",
"LDAP_SYNC_MODIFY", "\n" );
break;
default:
Debug( LDAP_DEBUG_ANY, "%s: %s",
"syncrepl_entry",
"UNKNONW syncstate", "\n" );
}
if (( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD )) {
syncuuid_bv = ber_dupbv( NULL, syncUUID );
avl_insert( &si->si_presentlist, (caddr_t) syncuuid_bv,
syncuuid_cmp, avl_dup_error );
if ( !si_refreshPresent ) {
syncuuid_bv = ber_dupbv( NULL, syncUUID );
avl_insert( &si->si_presentlist, (caddr_t) syncuuid_bv,
syncuuid_cmp, avl_dup_error );
}
}
if ( syncstate == LDAP_SYNC_PRESENT ) {
@ -1222,6 +1279,9 @@ syncrepl_entry(
if ( limits_check( op, &rs_search ) == 0 ) {
rc = be->be_search( op, &rs_search );
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s (%d)\n",
"be_search", rc, 0 );
}
if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
@ -1231,7 +1291,18 @@ syncrepl_entry(
cb.sc_response = null_callback;
cb.sc_private = si;
if ( rs_search.sr_err == LDAP_SUCCESS && !BER_BVISNULL( &si->si_syncUUID_ndn ) )
if ( entry && entry->e_name.bv_val ) {
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s\n",
entry->e_name.bv_val, 0, 0 );
} else {
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s\n",
si->si_syncUUID_ndn.bv_val, 0, 0 );
}
if ( rs_search.sr_err == LDAP_SUCCESS &&
!BER_BVISNULL( &si->si_syncUUID_ndn ))
{
char *subseq_ptr;
@ -1250,6 +1321,9 @@ syncrepl_entry(
op->o_req_ndn = si->si_syncUUID_ndn;
op->o_tag = LDAP_REQ_DELETE;
rc = be->be_delete( op, &rs_delete );
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s (%d)\n",
"be_delete", rc, 0 );
org_req_dn = op->o_req_dn;
org_req_ndn = op->o_req_ndn;
@ -1303,6 +1377,9 @@ syncrepl_entry(
op->o_req_ndn = entry->e_nname;
rc = be->be_add( op, &rs_add );
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s (%d)\n",
"be_add", rc, 0 );
if ( rs_add.sr_err != LDAP_SUCCESS ) {
if ( rs_add.sr_err == LDAP_ALREADY_EXISTS &&
@ -1330,6 +1407,9 @@ syncrepl_entry(
op->o_req_ndn = entry->e_nname;
rc = be->be_modify( op, &rs_modify );
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s (%d)\n",
"be_modify", rc, 0 );
if ( rs_modify.sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
"syncrepl_entry : be_modify failed (%d)\n",