]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
ITS#6270
[openldap] / servers / slapd / syncrepl.c
index 703fe25a6bb5c096177387df6d4ce337406fbccb..fb1001f239943255b10defc829dc88914edaffc4 100644 (file)
@@ -75,6 +75,7 @@ typedef struct syncinfo_s {
        struct berval           si_base;
        struct berval           si_logbase;
        struct berval           si_filterstr;
+       Filter                  *si_filter;
        struct berval           si_logfilterstr;
        struct berval           si_contextdn;
        int                     si_scope;
@@ -768,7 +769,7 @@ do_syncrep2(
 
        Modifications   *modlist = NULL;
 
-       int                             match, m, punlock = 0;
+       int                             match, m, punlock = -1;
 
        struct timeval *tout_p = NULL;
        struct timeval tout = { 0, 0 };
@@ -889,7 +890,7 @@ do_syncrep2(
                                                for ( i =0; i<si->si_cookieState->cs_pnum; i++ ) {
                                                        if ( si->si_cookieState->cs_psids[i] == sid ) {
                                                                if ( ber_bvcmp( syncCookie.ctxcsn, &si->si_cookieState->cs_pvals[i] ) <= 0 ) {
-                                                                       Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN too old, ignoring %s\n",
+                                                                       Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN pending, ignoring %s\n",
                                                                                si->si_ridtxt, syncCookie.ctxcsn->bv_val, 0 );
                                                                        ldap_controls_free( rctrls );
                                                                        rc = 0;
@@ -908,7 +909,7 @@ do_syncrep2(
                                                        si->si_cookieState->cs_psids = ch_realloc( si->si_cookieState->cs_psids, si->si_cookieState->cs_pnum * sizeof(int));
                                                        si->si_cookieState->cs_psids[i] = sid;
                                                }
-                                               punlock = 1;
+                                               punlock = i;
                                        }
                                        op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
                                }
@@ -942,8 +943,22 @@ do_syncrep2(
                                        rc = syncrepl_updateCookie( si, op, &syncCookie );
                                }
                        }
-                       if ( punlock );
+                       if ( punlock >= 0 ) {
+                               /* on failure, revert pending CSN */
+                               if ( rc != LDAP_SUCCESS ) {
+                                       int i;
+                                       for ( i = 0; i<si->si_cookieState->cs_num; i++ ) {
+                                               if ( si->si_cookieState->cs_sids[i] == si->si_cookieState->cs_psids[punlock] ) {
+                                                       ber_bvreplace( &si->si_cookieState->cs_pvals[punlock],
+                                                               &si->si_cookieState->cs_vals[i] );
+                                                       break;
+                                               }
+                                       }
+                                       if ( i == si->si_cookieState->cs_num )
+                                               si->si_cookieState->cs_pvals[punlock].bv_val[0] = '\0';
+                               }
                                ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_pmutex );
+                       }
                        ldap_controls_free( rctrls );
                        if ( modlist ) {
                                slap_mods_free( modlist, 1 );
@@ -2724,7 +2739,7 @@ syncrepl_del_nonpresent(
                op->ors_tlimit = SLAP_NO_LIMIT;
                op->ors_limit = NULL;
                op->ors_attrsonly = 0;
-               op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val );
+               op->ors_filter = filter_dup( si->si_filter, op->o_tmpmemctx );
                /* In multimaster, updates can continue to arrive while
                 * we're searching. Limit the search result to entries
                 * older than our newest cookie CSN.
@@ -3760,6 +3775,9 @@ syncinfo_free( syncinfo_t *sie, int free_all )
                if ( sie->si_filterstr.bv_val ) {
                        ch_free( sie->si_filterstr.bv_val );
                }
+               if ( sie->si_filter ) {
+                       filter_free( sie->si_filter );
+               }
                if ( sie->si_logfilterstr.bv_val ) {
                        ch_free( sie->si_logfilterstr.bv_val );
                }
@@ -4372,6 +4390,13 @@ parse_syncrepl_line(
                }
        }
 
+       si->si_filter = str2filter( si->si_filterstr.bv_val );
+       if ( si->si_filter == NULL ) {
+               Debug( LDAP_DEBUG_ANY, "syncrepl %s " SEARCHBASESTR "=\"%s\": unable to parse filter=\"%s\"\n", 
+                       si->si_ridtxt, c->be->be_suffix ? c->be->be_suffix[ 0 ].bv_val : "(null)", si->si_filterstr.bv_val );
+               return 1;
+       }
+
        return 0;
 }