From 26c3fd67b82e2a5ac180644354f4348092e028f6 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 17 Apr 2008 01:42:40 +0000 Subject: [PATCH] ITS#5470 ignore presentlist on partial multimaster refreshes --- servers/slapd/syncrepl.c | 214 +++++++++++++++++++++------------------ 1 file changed, 116 insertions(+), 98 deletions(-) diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 161ff46b14..99e506908a 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -432,6 +432,112 @@ ldap_sync_search( return rc; } +static int +check_syncprov( + Operation *op, + syncinfo_t *si ) +{ + AttributeName at[2]; + Attribute a = {0}; + Entry e = {0}; + SlapReply rs = {0}; + int i, j, changed = 0; + + /* Look for contextCSN from syncprov overlay. If + * there's no overlay, this will be a no-op. That means + * this is a pure consumer, so local changes will not be + * allowed, and all changes will already be reflected in + * the cookieState. + */ + a.a_desc = slap_schema.si_ad_contextCSN; + e.e_attrs = &a; + e.e_name = op->o_bd->be_suffix[0]; + e.e_nname = op->o_bd->be_nsuffix[0]; + at[0].an_name = a.a_desc->ad_cname; + at[0].an_desc = a.a_desc; + BER_BVZERO( &at[1].an_name ); + rs.sr_entry = &e; + rs.sr_flags = REP_ENTRY_MODIFIABLE; + rs.sr_attrs = at; + op->o_req_dn = e.e_name; + op->o_req_ndn = e.e_nname; + + ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex ); + i = backend_operational( op, &rs ); + if ( i == LDAP_SUCCESS && a.a_nvals ) { + int num = a.a_numvals; + /* check for differences */ + if ( num != si->si_cookieState->cs_num ) { + changed = 1; + } else { + for ( i=0; isi_cookieState->cs_vals[i] )) { + changed =1; + break; + } + } + } + if ( changed ) { + ber_bvarray_free( si->si_cookieState->cs_vals ); + ch_free( si->si_cookieState->cs_sids ); + si->si_cookieState->cs_num = num; + si->si_cookieState->cs_vals = a.a_nvals; + si->si_cookieState->cs_sids = slap_parse_csn_sids( a.a_nvals, + num, NULL ); + si->si_cookieState->cs_age++; + } else { + ber_bvarray_free( a.a_nvals ); + } + ber_bvarray_free( a.a_vals ); + } + /* See if the cookieState has changed due to anything outside + * this particular consumer. That includes other consumers in + * the same context, or local changes detected above. + */ + if ( si->si_cookieState->cs_num > 0 && si->si_cookieAge != + si->si_cookieState->cs_age ) { + if ( !si->si_syncCookie.numcsns ) { + ber_bvarray_free( si->si_syncCookie.ctxcsn ); + ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn, + si->si_cookieState->cs_vals, NULL ); + changed = 1; + } else { + for (i=0; !BER_BVISNULL( &si->si_syncCookie.ctxcsn[i] ); i++) { + /* bogus, just dup everything */ + if ( si->si_syncCookie.sids[i] == -1 ) { + ber_bvarray_free( si->si_syncCookie.ctxcsn ); + ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn, + si->si_cookieState->cs_vals, NULL ); + changed = 1; + break; + } + for (j=0; jsi_cookieState->cs_num; j++) { + if ( si->si_syncCookie.sids[i] != + si->si_cookieState->cs_sids[j] ) + continue; + if ( bvmatch( &si->si_syncCookie.ctxcsn[i], + &si->si_cookieState->cs_vals[j] )) + break; + ber_bvreplace( &si->si_syncCookie.ctxcsn[i], + &si->si_cookieState->cs_vals[j] ); + changed = 1; + break; + } + } + } + } + if ( changed ) { + si->si_cookieAge = si->si_cookieState->cs_age; + ch_free( si->si_syncCookie.octet_str.bv_val ); + slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, + si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, + si->si_syncCookie.sid ); + } + ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); + return changed; +} + static int do_syncrep1( Operation *op, @@ -538,104 +644,8 @@ do_syncrep1( si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, si->si_syncCookie.sid ); } else { - AttributeName at[2]; - Attribute a = {0}; - Entry e = {0}; - SlapReply rs = {0}; - int i, j, changed = 0; - - /* Look for contextCSN from syncprov overlay. If - * there's no overlay, this will be a no-op. That means - * this is a pure consumer, so local changes will not be - * allowed, and all changes will already be reflected in - * the cookieState. - */ - a.a_desc = slap_schema.si_ad_contextCSN; - e.e_attrs = &a; - e.e_name = op->o_bd->be_suffix[0]; - e.e_nname = op->o_bd->be_nsuffix[0]; - at[0].an_name = a.a_desc->ad_cname; - at[0].an_desc = a.a_desc; - BER_BVZERO( &at[1].an_name ); - rs.sr_entry = &e; - rs.sr_flags = REP_ENTRY_MODIFIABLE; - rs.sr_attrs = at; - op->o_req_dn = e.e_name; - op->o_req_ndn = e.e_nname; - - ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex ); - rc = backend_operational( op, &rs ); - if ( rc == LDAP_SUCCESS && a.a_nvals ) { - int num = a.a_numvals; - /* check for differences */ - if ( num != si->si_cookieState->cs_num ) { - changed = 1; - } else { - for ( i=0; isi_cookieState->cs_vals[i] )) { - changed =1; - break; - } - } - } - if ( changed ) { - ber_bvarray_free( si->si_cookieState->cs_vals ); - ch_free( si->si_cookieState->cs_sids ); - si->si_cookieState->cs_num = num; - si->si_cookieState->cs_vals = a.a_nvals; - si->si_cookieState->cs_sids = slap_parse_csn_sids( a.a_nvals, - num, NULL ); - si->si_cookieState->cs_age++; - } else { - ber_bvarray_free( a.a_nvals ); - } - ber_bvarray_free( a.a_vals ); - } - /* See if the cookieState has changed due to anything outside - * this particular consumer. That includes other consumers in - * the same context, or local changes detected above. - */ - if ( si->si_cookieState->cs_num > 0 && si->si_cookieAge != - si->si_cookieState->cs_age ) { - if ( !si->si_syncCookie.numcsns ) { - ber_bvarray_free( si->si_syncCookie.ctxcsn ); - ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn, - si->si_cookieState->cs_vals, NULL ); - changed = 1; - } else { - for (i=0; !BER_BVISNULL( &si->si_syncCookie.ctxcsn[i] ); i++) { - /* bogus, just dup everything */ - if ( si->si_syncCookie.sids[i] == -1 ) { - ber_bvarray_free( si->si_syncCookie.ctxcsn ); - ber_bvarray_dup_x( &si->si_syncCookie.ctxcsn, - si->si_cookieState->cs_vals, NULL ); - changed = 1; - break; - } - for (j=0; jsi_cookieState->cs_num; j++) { - if ( si->si_syncCookie.sids[i] != - si->si_cookieState->cs_sids[j] ) - continue; - if ( bvmatch( &si->si_syncCookie.ctxcsn[i], - &si->si_cookieState->cs_vals[j] )) - break; - ber_bvreplace( &si->si_syncCookie.ctxcsn[i], - &si->si_cookieState->cs_vals[j] ); - changed = 1; - break; - } - } - } - } - if ( changed ) { - si->si_cookieAge = si->si_cookieState->cs_age; - ch_free( si->si_syncCookie.octet_str.bv_val ); - slap_compose_sync_cookie( NULL, &si->si_syncCookie.octet_str, - si->si_syncCookie.ctxcsn, si->si_syncCookie.rid, - si->si_syncCookie.sid ); - } - ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); + /* Look for contextCSN from syncprov overlay. */ + check_syncprov( op, si ); } si->si_refreshDone = 0; @@ -915,6 +925,10 @@ do_syncrep2( } ber_scanf( ber, /*"{"*/ "}" ); } + if ( SLAP_MULTIMASTER( op->o_bd ) && check_syncprov( op, si )) { + slap_sync_cookie_free( &syncCookie_req, 0 ); + slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie ); + } if ( !syncCookie.ctxcsn ) { match = 1; } else if ( !syncCookie_req.ctxcsn ) { @@ -1067,6 +1081,10 @@ do_syncrep2( continue; } + if ( SLAP_MULTIMASTER( op->o_bd ) && check_syncprov( op, si )) { + slap_sync_cookie_free( &syncCookie_req, 0 ); + slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie ); + } if ( !syncCookie.ctxcsn ) { match = 1; } else if ( !syncCookie_req.ctxcsn ) { -- 2.39.5