]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
ITS#8789 revert previous patch
[openldap] / servers / slapd / syncrepl.c
index 40254981799c36c50bd993df42675c3c0aeb852e..36d01d85bf7d69d759ed39abef7ac73497ae4324 100644 (file)
@@ -46,11 +46,13 @@ struct nonpresent_entry {
 
 typedef struct cookie_state {
        ldap_pvt_thread_mutex_t cs_mutex;
+       ldap_pvt_thread_cond_t cs_cond;
        struct berval *cs_vals;
        int *cs_sids;
        int     cs_num;
        int cs_age;
        int cs_ref;
+       int cs_updating;
 
        /* pending changes, not yet committed */
        ldap_pvt_thread_mutex_t cs_pmutex;
@@ -150,7 +152,7 @@ static int syncrepl_entry(
                                        struct berval *cookieCSN );
 static int syncrepl_updateCookie(
                                        syncinfo_t *, Operation *,
-                                       struct sync_cookie * );
+                                       struct sync_cookie *, int save );
 static struct berval * slap_uuidstr_from_normalized(
                                        struct berval *, struct berval *, void * );
 static int syncrepl_add_glue_ancestors(
@@ -175,6 +177,7 @@ typedef struct logschema {
        struct berval ls_newRdn;
        struct berval ls_delRdn;
        struct berval ls_newSup;
+       struct berval ls_controls;
 } logschema;
 
 static logschema changelog_sc = {
@@ -183,7 +186,8 @@ static logschema changelog_sc = {
        BER_BVC("changes"),
        BER_BVC("newRDN"),
        BER_BVC("deleteOldRDN"),
-       BER_BVC("newSuperior")
+       BER_BVC("newSuperior"),
+       BER_BVC("controls")
 };
 
 static logschema accesslog_sc = {
@@ -192,7 +196,8 @@ static logschema accesslog_sc = {
        BER_BVC("reqMod"),
        BER_BVC("reqNewRDN"),
        BER_BVC("reqDeleteOldRDN"),
-       BER_BVC("reqNewSuperior")
+       BER_BVC("reqNewSuperior"),
+       BER_BVC("reqControls")
 };
 
 static const char *
@@ -408,7 +413,7 @@ ldap_sync_search(
        int rc;
        int rhint;
        char *base;
-       char **attrs, *lattrs[8];
+       char **attrs, *lattrs[9];
        char *filter;
        int attrsonly;
        int scope;
@@ -437,8 +442,9 @@ ldap_sync_search(
                lattrs[3] = ls->ls_newRdn.bv_val;
                lattrs[4] = ls->ls_delRdn.bv_val;
                lattrs[5] = ls->ls_newSup.bv_val;
-               lattrs[6] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
-               lattrs[7] = NULL;
+               lattrs[6] = ls->ls_controls.bv_val;
+               lattrs[7] = slap_schema.si_ad_entryCSN->ad_cname.bv_val;
+               lattrs[8] = NULL;
 
                rhint = 0;
                base = si->si_logbase.bv_val;
@@ -1023,7 +1029,7 @@ do_syncrep2(
                                if ( ( rc = syncrepl_message_to_op( si, op, msg ) ) == LDAP_SUCCESS &&
                                        syncCookie.ctxcsn )
                                {
-                                       rc = syncrepl_updateCookie( si, op, &syncCookie );
+                                       rc = syncrepl_updateCookie( si, op, &syncCookie, 0 );
                                } else switch ( rc ) {
                                        case LDAP_ALREADY_EXISTS:
                                        case LDAP_NO_SUCH_OBJECT:
@@ -1051,7 +1057,7 @@ do_syncrep2(
                                        syncstate, syncUUID, syncCookie.ctxcsn ) ) == LDAP_SUCCESS &&
                                        syncCookie.ctxcsn )
                                {
-                                       rc = syncrepl_updateCookie( si, op, &syncCookie );
+                                       rc = syncrepl_updateCookie( si, op, &syncCookie, 0 );
                                }
                        }
                        if ( punlock >= 0 ) {
@@ -1197,7 +1203,7 @@ do_syncrep2(
                        }
                        if ( syncCookie.ctxcsn && match < 0 && err == LDAP_SUCCESS )
                        {
-                               rc = syncrepl_updateCookie( si, op, &syncCookie );
+                               rc = syncrepl_updateCookie( si, op, &syncCookie, 1 );
                        }
                        if ( si->si_refreshCount ) {
                                LDAP_SLIST_REMOVE( &op->o_extra, si->si_refreshTxn, OpExtra, oe_next );
@@ -1387,7 +1393,7 @@ do_syncrep2(
 
                                        if ( syncCookie.ctxcsn )
                                        {
-                                               rc = syncrepl_updateCookie( si, op, &syncCookie);
+                                               rc = syncrepl_updateCookie( si, op, &syncCookie, 1 );
                                        }
                                        if ( si->si_presentlist ) {
                                                presentlist_free( si->si_presentlist );
@@ -2188,11 +2194,8 @@ syncrepl_op_modify( Operation *op, SlapReply *rs )
        if ( match < 0 ) {
                Operation op2 = *op;
                AttributeName an[2];
-               const char *text;
                struct berval bv;
-               char *ptr;
-               Modifications *ml;
-               int size, rc;
+               int size;
                SlapReply rs1 = {0};
                resolve_ctxt rx;
                slap_callback cb = { NULL, syncrepl_resolve_cb, NULL, NULL };
@@ -2412,6 +2415,22 @@ syncrepl_message_to_op(
                        }
                } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_newSup ) ) {
                        sup = bvals[0];
+               } else if ( !ber_bvstrcasecmp( &bv, &ls->ls_controls ) ) {
+                       int i;
+                       struct berval rel_ctrl_bv;
+
+                       (void)ber_str2bv( "{" LDAP_CONTROL_RELAX, 0, 0, &rel_ctrl_bv );
+                       for ( i = 0; bvals[i].bv_val; i++ ) {
+                               struct berval cbv, tmp;
+
+                               ber_bvchr_post( &cbv, &bvals[i], '}' );
+                               ber_bvchr_post( &tmp, &cbv, '{' );
+                               ber_bvchr_pre( &cbv, &tmp, ' ' );
+                               if ( cbv.bv_len == tmp.bv_len )         /* control w/o value */
+                                       ber_bvchr_pre( &cbv, &tmp, '}' );
+                               if ( !ber_bvcmp( &cbv, &rel_ctrl_bv ) )
+                                       op->o_relax = SLAP_CONTROL_CRITICAL;
+                       }
                } else if ( !ber_bvstrcasecmp( &bv,
                        &slap_schema.si_ad_entryCSN->ad_cname ) )
                {
@@ -2430,6 +2449,9 @@ syncrepl_message_to_op(
        op->o_callback = &cb;
        slap_op_time( &op->o_time, &op->o_tincr );
 
+       Debug( LDAP_DEBUG_SYNC, "syncrepl_message_to_op: %s tid %x\n",
+               si->si_ridtxt, op->o_tid, 0 );
+
        switch( op->o_tag ) {
        case LDAP_REQ_ADD:
        case LDAP_REQ_MODIFY:
@@ -2937,8 +2959,8 @@ syncrepl_entry(
        int     freecsn = 1;
 
        Debug( LDAP_DEBUG_SYNC,
-               "syncrepl_entry: %s LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_%s)\n",
-               si->si_ridtxt, syncrepl_state2str( syncstate ), 0 );
+               "syncrepl_entry: %s LDAP_RES_SEARCH_ENTRY(LDAP_SYNC_%s) tid %x\n",
+               si->si_ridtxt, syncrepl_state2str( syncstate ), op->o_tid );
 
        if (( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD ) ) {
                if ( !si->si_refreshPresent && !si->si_refreshDone ) {
@@ -3909,7 +3931,8 @@ static int
 syncrepl_updateCookie(
        syncinfo_t *si,
        Operation *op,
-       struct sync_cookie *syncCookie )
+       struct sync_cookie *syncCookie,
+       int save )
 {
        Backend *be = op->o_bd;
        Modifications mod;
@@ -3933,6 +3956,8 @@ syncrepl_updateCookie(
        mod.sml_next = NULL;
 
        ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
+       while ( si->si_cookieState->cs_updating )
+               ldap_pvt_thread_cond_wait( &si->si_cookieState->cs_cond, &si->si_cookieState->cs_mutex );
 
 #ifdef CHECK_CSN
        for ( i=0; i<syncCookie->numcsns; i++ ) {
@@ -3995,6 +4020,10 @@ syncrepl_updateCookie(
                ch_free( sc.sids );
                return 0;
        }
+
+       si->si_cookieState->cs_updating = 1;
+       ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
+
        op->o_bd = si->si_wbe;
        slap_queue_csn( op, &first );
 
@@ -4008,7 +4037,11 @@ syncrepl_updateCookie(
        op->o_req_ndn = si->si_contextdn;
 
        /* update contextCSN */
-       op->o_dont_replicate = 1;
+       op->o_dont_replicate = !save;
+
+       /* avoid timestamp collisions */
+       if ( save )
+               slap_op_time( &op->o_time, &op->o_tincr );
 
        mod.sml_numvals = sc.numcsns;
        mod.sml_values = sc.ctxcsn;
@@ -4025,6 +4058,8 @@ syncrepl_updateCookie(
                Entry *e = slap_create_context_csn_entry( op->o_bd, NULL );
                rs_reinit( &rs_modify, REP_RESULT );
                rc = slap_mods2entry( &mod, &e, 0, 1, &text, txtbuf, textlen);
+               slap_queue_csn( op, &first );
+               op->o_tag = LDAP_REQ_ADD;
                op->ora_e = e;
                rc = op->o_bd->be_add( op, &rs_modify );
                if ( e == op->ora_e )
@@ -4033,6 +4068,7 @@ syncrepl_updateCookie(
 
        op->orm_no_opattrs = 0;
        op->o_dont_replicate = 0;
+       ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
 
        if ( rs_modify.sr_err == LDAP_SUCCESS ) {
                slap_sync_cookie_free( &si->si_syncCookie, 0 );
@@ -4065,6 +4101,8 @@ syncrepl_updateCookie(
        }
 #endif
 
+       si->si_cookieState->cs_updating = 0;
+       ldap_pvt_thread_cond_broadcast( &si->si_cookieState->cs_cond );
        ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
 
        op->o_bd = be;
@@ -4729,6 +4767,7 @@ syncinfo_free( syncinfo_t *sie, int free_all )
                        if ( !sie->si_cookieState->cs_ref ) {
                                ch_free( sie->si_cookieState->cs_sids );
                                ber_bvarray_free( sie->si_cookieState->cs_vals );
+                               ldap_pvt_thread_cond_destroy( &sie->si_cookieState->cs_cond );
                                ldap_pvt_thread_mutex_destroy( &sie->si_cookieState->cs_mutex );
                                ch_free( sie->si_cookieState->cs_psids );
                                ber_bvarray_free( sie->si_cookieState->cs_pvals );
@@ -5535,6 +5574,7 @@ add_syncrepl(
                        si->si_cookieState = ch_calloc( 1, sizeof( cookie_state ));
                        ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_mutex );
                        ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_pmutex );
+                       ldap_pvt_thread_cond_init( &si->si_cookieState->cs_cond );
 
                        c->be->be_syncinfo = si;
                }