From 81a53a9a5c6a299fbdb1c64c6547123aadd83ce5 Mon Sep 17 00:00:00 2001 From: Jong Hyuk Choi Date: Tue, 26 Aug 2003 22:49:44 +0000 Subject: [PATCH] LDAP Sync protocol extension - do not send updates in state mode when syncCookie >= contextCSN (or omitCSN if changelog is used) --- servers/slapd/back-bdb/search.c | 29 ++++++++++++++ servers/slapd/syncrepl.c | 68 ++++++++++++++++++++++----------- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 007e0ba699..20e1a3fcde 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -400,6 +400,7 @@ int bdb_search( Operation *op, SlapReply *rs ) int rc_sync = 0; int entry_sync_state = -1; AttributeName null_attr; + int no_sync_state_change = 0; #endif struct slap_limits_set *limit = NULL; int isroot = 0; @@ -854,6 +855,10 @@ ctxcsn_retry : if ( (sop->o_sync_mode & SLAP_SYNC_REFRESH) || ( IS_PSEARCH && sop->o_ps_protocol == LDAP_SYNC )) { + MatchingRule *mr; + const char *text; + int match; + cookief.f_choice = LDAP_FILTER_AND; cookief.f_and = &csnfnot; cookief.f_next = NULL; @@ -888,6 +893,16 @@ ctxcsn_retry : contextcsnle.f_av_desc = slap_schema.si_ad_entryCSN; contextcsnle.f_av_value = *search_context_csn; contextcsnle.f_next = sop->oq_search.rs_filter; + + mr = slap_schema.si_ad_entryCSN->ad_type->sat_ordering; + if ( sop->o_sync_state.bv_len != 0 ) { + value_match( &match, slap_schema.si_ad_entryCSN, mr, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &sop->o_sync_state, search_context_csn, &text ); + } else { + match = -1; + } + no_sync_state_change = !match; } else { csnfge.f_next = sop->oq_search.rs_filter; } @@ -1131,8 +1146,22 @@ id2entry_retry: rs->sr_entry, &contextcsnand ); if ( rs->sr_err == LDAP_COMPARE_TRUE ) { if ( rc_sync == LDAP_COMPARE_TRUE ) { + if ( no_sync_state_change ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: error in context csn management\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "bdb_search: error in context csn management\n", + 0, 0, 0 ); +#endif + } entry_sync_state = LDAP_SYNC_ADD; } else { + if ( no_sync_state_change ) { + goto loop_continue; + } entry_sync_state = LDAP_SYNC_PRESENT; } } diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 227967b771..9b6975e7be 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -201,6 +201,7 @@ do_syncrepl( int syncstate; struct berval syncUUID = { 0, NULL }; struct berval syncCookie = { 0, NULL }; + struct berval syncCookie_req = { 0, NULL }; int rc; int err; @@ -234,6 +235,9 @@ do_syncrepl( Modifications *ml, *mlnext; char *def_filter_str = NULL; + const char *text; + int match; + #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 ); #else @@ -418,6 +422,8 @@ do_syncrepl( si->syncCookie = NULL; be->be_search( &op, &rs ); + ber_dupbv( &syncCookie_req, si->syncCookie ); + ch_free( op.o_req_dn.bv_val ); ch_free( op.o_req_ndn.bv_val ); filter_free( op.ors_filter ); @@ -481,6 +487,7 @@ do_syncrepl( msg != NULL; msg = ldap_next_message( ld, msg ) ) { + syncCookie.bv_len = 0; syncCookie.bv_val = NULL; switch( ldap_msgtype( msg ) ) { case LDAP_RES_SEARCH_ENTRY: entry = syncrepl_message_to_entry( si, ld, &op, msg, @@ -523,9 +530,13 @@ do_syncrepl( ber_scanf( ctrl_ber, "o", &syncCookie ); } } + value_match( &match, slap_schema.si_ad_entryCSN, + slap_schema.si_ad_entryCSN->ad_type->sat_ordering, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &syncCookie_req, &syncCookie, &text ); if (si->type == LDAP_SYNC_REFRESH_AND_PERSIST) { if ( cancel_response ) { - if ( syncCookie.bv_len ) { + if ( syncCookie.bv_len && match < 0) { syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie ); } if ( ctrl_ber ) @@ -538,11 +549,12 @@ do_syncrepl( break; } } else { - if ( syncCookie.bv_len ) { + if ( syncCookie.bv_len && match < 0 ) { syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie); } - if ( si->sync_mode == LDAP_SYNC_STATE_MODE ) - syncrepl_del_nonpresent( ld, &op ); + if ( si->sync_mode == LDAP_SYNC_STATE_MODE && match < 0 ) { + syncrepl_del_nonpresent( ld, &op ); + } if ( ctrl_ber ) ber_free( ctrl_ber, 1 ); goto done; @@ -557,8 +569,34 @@ do_syncrepl( res_ber = ber_init( retdata ); ber_scanf( res_ber, "{e" /*"}"*/, &syncstate ); + if ( ber_peek_tag( res_ber, &len ) + == LDAP_SYNC_TAG_COOKIE ) { + ber_scanf( res_ber, /*"{"*/ "o}", &syncCookie ); + } else { + if ( syncstate == LDAP_SYNC_NEW_COOKIE ) { +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, + "do_syncrepl : cookie required\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "do_syncrepl : cookie required\n", 0, 0, 0 ); +#endif + } + } + + value_match( &match, slap_schema.si_ad_entryCSN, + slap_schema.si_ad_entryCSN->ad_type->sat_ordering, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &syncCookie_req, &syncCookie, &text ); + + if ( syncCookie.bv_len && match < 0 ) { + syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie); + } + if ( syncstate == LDAP_SYNC_STATE_MODE_DONE ) { - syncrepl_del_nonpresent( ld, &op ); + if ( match < 0 ) { + syncrepl_del_nonpresent( ld, &op ); + } si->sync_mode = LDAP_SYNC_LOG_MODE; } else if ( syncstate == LDAP_SYNC_LOG_MODE_DONE ) { si->sync_mode = LDAP_SYNC_PERSIST_MODE; @@ -575,24 +613,6 @@ do_syncrepl( #endif } - if ( ber_peek_tag( res_ber, &len ) - == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( res_ber, /*"{"*/ "o}", &syncCookie ); - if ( syncCookie.bv_len ) { - syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie); - } - } else { - if ( syncstate == LDAP_SYNC_NEW_COOKIE ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "do_syncrepl : cookie required\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "do_syncrepl : cookie required\n", 0, 0, 0 ); -#endif - } - } - ldap_memfree( retoid ); ber_bvfree( retdata ); ber_free( res_ber, 1 ); @@ -640,6 +660,8 @@ do_syncrepl( done: if ( syncCookie.bv_val ) ch_free( syncCookie.bv_val ); + if ( syncCookie_req.bv_val ) + ch_free( syncCookie_req.bv_val ); if ( syncUUID.bv_val ) ch_free( syncUUID.bv_val ); -- 2.39.5