]> git.sur5r.net Git - openldap/commitdiff
ITS#5470 ignore presentlist on partial multimaster refreshes
authorHoward Chu <hyc@openldap.org>
Thu, 17 Apr 2008 01:42:40 +0000 (01:42 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 17 Apr 2008 01:42:40 +0000 (01:42 +0000)
servers/slapd/syncrepl.c

index 161ff46b144c208b1c99da4e27a464710dc4696a..99e506908a19aaee0f423144e4735df60765b13d 100644 (file)
@@ -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; 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,
@@ -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; 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;
@@ -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 ) {