]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/syncprov.c
Each refint op needs a unique timestamp, must perform searches as rootdn
[openldap] / servers / slapd / overlays / syncprov.c
index f697131834b6acc0ed829b27deb6f2742e09b1ac..5a3b4185c631d59e0060deaee0d11d62152d5dfc 100644 (file)
@@ -1055,6 +1055,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
        int rc;
        struct berval newdn;
        int freefdn = 0;
+       BackendDB *b0 = op->o_bd, db;
 
        fc.fdn = &op->o_req_ndn;
        /* compute new DN */
@@ -1067,6 +1068,10 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
                freefdn = 1;
        }
        if ( op->o_tag != LDAP_REQ_ADD ) {
+               if ( !SLAP_ISOVERLAY( op->o_bd )) {
+                       db = *op->o_bd;
+                       op->o_bd = &db;
+               }
                op->o_bd->bd_info = (BackendInfo *)on->on_info;
                rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );
                /* If we're sending responses now, make a copy and unlock the DB */
@@ -1076,7 +1081,10 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
                        e = e2;
                }
                op->o_bd->bd_info = (BackendInfo *)on;
-               if ( rc ) return;
+               if ( rc ) {
+                       op->o_bd = b0;
+                       return;
+               }
        } else {
                e = op->ora_e;
        }
@@ -1174,6 +1182,7 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
        if ( freefdn ) {
                op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx );
        }
+       op->o_bd = b0;
 }
 
 static int
@@ -1302,9 +1311,6 @@ syncprov_add_slog( Operation *op, struct berval *csn )
                        sl->sl_mincsn.bv_len = se->se_csn.bv_len;
                        ch_free( se );
                        sl->sl_num--;
-                       if ( !sl->sl_head ) {
-                               sl->sl_tail = NULL;
-                       }
                }
                ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
        }
@@ -1323,12 +1329,14 @@ playlog_cb( Operation *op, SlapReply *rs )
 /* enter with sl->sl_mutex locked, release before returning */
 static void
 syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
-       struct berval *oldcsn, struct berval *ctxcsn )
+       sync_control *srs, struct berval *ctxcsn )
 {
        slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
        slog_entry *se;
        int i, j, ndel, num, nmods, mmods;
+       char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
        BerVarray uuids;
+       struct berval delcsn;
 
        if ( !sl->sl_num ) {
                ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
@@ -1341,19 +1349,23 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
 
        uuids = op->o_tmpalloc( (num+1) * sizeof( struct berval ) +
                num * UUID_LEN, op->o_tmpmemctx );
-
        uuids[0].bv_val = (char *)(uuids + num + 1);
 
+       delcsn.bv_len = 0;
+       delcsn.bv_val = cbuf;
+
        /* Make a copy of the relevant UUIDs. Put the Deletes up front
         * and everything else at the end. Do this first so we can
         * unlock the list mutex.
         */
        for ( se=sl->sl_head; se; se=se->se_next ) {
-               if ( ber_bvcmp( &se->se_csn, oldcsn ) < 0 ) continue;
+               if ( ber_bvcmp( &se->se_csn, &srs->sr_state.ctxcsn ) <= 0 ) continue;
                if ( ber_bvcmp( &se->se_csn, ctxcsn ) > 0 ) break;
                if ( se->se_tag == LDAP_REQ_DELETE ) {
                        j = i;
                        i++;
+                       AC_MEMCPY( cbuf, se->se_csn.bv_val, se->se_csn.bv_len );
+                       delcsn.bv_len = se->se_csn.bv_len;
                } else {
                        nmods++;
                        j = num - nmods;
@@ -1445,9 +1457,14 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
                fop.o_bd->bd_info = (BackendInfo *)on;
        }
        if ( ndel ) {
+               struct berval cookie;
+
+               slap_compose_sync_cookie( op, &cookie, &delcsn, srs->sr_state.rid );
                uuids[ndel].bv_val = NULL;
-               syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, NULL, 0, uuids, 1 );
+               syncprov_sendinfo( op, rs, LDAP_TAG_SYNC_ID_SET, &cookie, 0, uuids, 1 );
+               op->o_tmpfree( cookie.bv_val, op->o_tmpmemctx );
        }
+       op->o_tmpfree( uuids, op->o_tmpmemctx );
 }
 
 static int
@@ -1814,13 +1831,23 @@ syncprov_search_response( Operation *op, SlapReply *rs )
                }
                if ( a ) {
                        /* Make sure entry is less than the snapshot'd contextCSN */
-                       if ( ber_bvcmp( &a->a_nvals[0], &ss->ss_ctxcsn ) > 0 )
+                       if ( ber_bvcmp( &a->a_nvals[0], &ss->ss_ctxcsn ) > 0 ) {
+                               Debug( LDAP_DEBUG_SYNC, "Entry %s CSN %s greater than snapshot %s\n",
+                                       rs->sr_entry->e_name.bv_val,
+                                       a->a_nvals[0].bv_val,
+                                       ss->ss_ctxcsn.bv_val );
                                return LDAP_SUCCESS;
+                       }
 
                        /* Don't send the ctx entry twice */
                        if ( !BER_BVISNULL( &srs->sr_state.ctxcsn ) &&
-                               bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )
+                               bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) ) {
+                               Debug( LDAP_DEBUG_SYNC, "Entry %s CSN %s matches ctx %s\n",
+                                       rs->sr_entry->e_name.bv_val,
+                                       a->a_nvals[0].bv_val,
+                                       srs->sr_state.ctxcsn.bv_val );
                                return LDAP_SUCCESS;
+                       }
                }
                rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
                        op->o_tmpmemctx );
@@ -1905,10 +1932,12 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                /* syncprov_findbase expects to be called as a callback... */
                sc.sc_private = &opc;
                opc.son = on;
+               ldap_pvt_thread_mutex_init( &so.s_mutex );
                cb = op->o_callback;
                op->o_callback = &sc;
                rs->sr_err = syncprov_findbase( op, &fc );
                op->o_callback = cb;
+               ldap_pvt_thread_mutex_destroy( &so.s_mutex );
 
                if ( rs->sr_err != LDAP_SUCCESS ) {
                        send_ldap_result( op, rs );
@@ -1964,7 +1993,7 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                        if ( ber_bvcmp( &srs->sr_state.ctxcsn, &sl->sl_mincsn ) >= 0 ) {
                                do_present = 0;
                                /* mutex is unlocked in playlog */
-                               syncprov_playlog( op, rs, sl, &srs->sr_state.ctxcsn, &ctxcsn );
+                               syncprov_playlog( op, rs, sl, srs, &ctxcsn );
                        } else {
                                ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
                        }