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; i<num; i++ ) {
+ if ( ber_bvcmp( &a.a_nvals[i],
+ &si->si_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; j<si->si_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,
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; i<num; i++ ) {
- if ( ber_bvcmp( &a.a_nvals[i],
- &si->si_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; j<si->si_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;
}
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 ) {
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 ) {