]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
More for #6020
[openldap] / servers / slapd / syncrepl.c
index e2c570937b44ddb92c29b3ceca5a2ca7cc9d0fa9..76b9ec1a97c4e11bbff14032787d0d678f1b9dac 100644 (file)
@@ -863,6 +863,7 @@ do_syncrep2(
                                                        }
                                                }
                                        }
+                                       op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
                                }
                        }
                        rc = 0;
@@ -969,6 +970,7 @@ do_syncrep2(
                                        if ( !BER_BVISNULL( &syncCookie.octet_str ) )
                                        {
                                                slap_parse_sync_cookie( &syncCookie, NULL );
+                                               op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
                                        }
                                }
                                if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES )
@@ -1037,6 +1039,18 @@ do_syncrep2(
                                                "LDAP_RES_INTERMEDIATE", 
                                                "NEW_COOKIE" );
                                        ber_scanf( ber, "tm", &tag, &cookie );
+                                       Debug( LDAP_DEBUG_SYNC,
+                                               "do_syncrep2: %s NEW_COOKIE: %s\n",
+                                               si->si_ridtxt,
+                                               cookie.bv_val, 0);
+                                       if ( !BER_BVISNULL( &cookie ) ) {
+                                               ch_free( syncCookie.octet_str.bv_val );
+                                               ber_dupbv( &syncCookie.octet_str, &cookie );
+                                       }
+                                       if (!BER_BVISNULL( &syncCookie.octet_str ) ) {
+                                               slap_parse_sync_cookie( &syncCookie, NULL );
+                                               op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
+                                       }
                                        break;
                                case LDAP_TAG_SYNC_REFRESH_DELETE:
                                case LDAP_TAG_SYNC_REFRESH_PRESENT:
@@ -1066,6 +1080,7 @@ do_syncrep2(
                                                if ( !BER_BVISNULL( &syncCookie.octet_str ) )
                                                {
                                                        slap_parse_sync_cookie( &syncCookie, NULL );
+                                                       op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
                                                }
                                        }
                                        /* Defaults to TRUE */
@@ -1101,6 +1116,7 @@ do_syncrep2(
                                                if ( !BER_BVISNULL( &syncCookie.octet_str ) )
                                                {
                                                        slap_parse_sync_cookie( &syncCookie, NULL );
+                                                       op->o_controls[slap_cids.sc_LDAPsync] = &syncCookie;
                                                        compare_csns( &syncCookie_req, &syncCookie, &m );
                                                }
                                        }
@@ -1149,6 +1165,7 @@ do_syncrep2(
 
                                if ( match < 0 ) {
                                        if ( si->si_refreshPresent == 1 &&
+                                               si_tag != LDAP_TAG_SYNC_NEW_COOKIE &&
                                                syncCookie_req.numcsns == syncCookie.numcsns ) {
                                                syncrepl_del_nonpresent( op, si, NULL,
                                                        &syncCookie, m );
@@ -1246,8 +1263,13 @@ do_syncrepl(
        if ( si == NULL )
                return NULL;
 
-       /* There will never be more than one instance active */
-       ldap_pvt_thread_mutex_lock( &si->si_mutex );
+       /* Don't get stuck here while a pause is initiated */
+       while ( ldap_pvt_thread_mutex_trylock( &si->si_mutex )) {
+               if ( slapd_shutdown )
+                       return NULL;
+               if ( !ldap_pvt_thread_pool_pausecheck( &connection_pool ))
+                       ldap_pvt_thread_yield();
+       }
 
        switch( abs( si->si_type ) ) {
        case LDAP_SYNC_REFRESH_ONLY:
@@ -1442,22 +1464,9 @@ reload:
 
        /* Do final delete cleanup */
        if ( !si->si_ctype ) {
-               cookie_state *cs = NULL;
-               syncinfo_t **sip;
-
-               cs = be->be_syncinfo->si_cookieState;
-               for ( sip = &be->be_syncinfo; *sip != si; sip = &(*sip)->si_next );
-               *sip = si->si_next;
-               syncinfo_free( si, 0 );
-               if ( !be->be_syncinfo ) {
-                       SLAP_DBFLAGS( be ) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW);
-                       if ( cs ) {
-                               ch_free( cs->cs_sids );
-                               ber_bvarray_free( cs->cs_vals );
-                               ldap_pvt_thread_mutex_destroy( &cs->cs_mutex );
-                               ch_free( cs );
-                       }
-               }
+               cookie_state *cs = si->si_cookieState;
+               syncinfo_free( si, ( !be->be_syncinfo ||
+                       be->be_syncinfo->si_cookieState != cs ));
        }
        return NULL;
 }
@@ -2322,6 +2331,12 @@ retry_add:;
                                                                break;
                                                        }
                                                }
+                                               if ( !mod->sml_numvals ) {
+                                                       /* Drop this op */
+                                                       *ml = mod->sml_next;
+                                                       mod->sml_next = NULL;
+                                                       slap_mods_free( mod, 1 );
+                                               }
                                                break;
                                        }
                                }
@@ -2889,6 +2904,9 @@ syncrepl_updateCookie(
        Backend *be = op->o_bd;
        Modifications mod;
        struct berval first = BER_BVNULL;
+#ifdef CHECK_CSN
+       Syntax *syn = slap_schema.si_ad_contextCSN->ad_type->sat_syntax;
+#endif
 
        int rc, i, j;
        ber_len_t len;
@@ -2905,6 +2923,15 @@ syncrepl_updateCookie(
 
        ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
 
+#ifdef CHECK_CSN
+       for ( i=0; i<syncCookie->numcsns; i++ ) {
+               assert( !syn->ssyn_validate( syn, syncCookie->ctxcsn+i ));
+       }
+       for ( i=0; i<si->si_cookieState->cs_num; i++ ) {
+               assert( !syn->ssyn_validate( syn, si->si_cookieState->cs_vals+i ));
+       }
+#endif
+
        /* clone the cookieState CSNs so we can Replace the whole thing */
        mod.sml_numvals = si->si_cookieState->cs_num;
        mod.sml_values = op->o_tmpalloc(( mod.sml_numvals+1 )*sizeof(struct berval), op->o_tmpmemctx );
@@ -3007,6 +3034,12 @@ syncrepl_updateCookie(
        if ( mod.sml_next ) slap_mods_free( mod.sml_next, 1 );
        op->o_tmpfree( mod.sml_values, op->o_tmpmemctx );
 
+#ifdef CHECK_CSN
+       for ( i=0; i<si->si_cookieState->cs_num; i++ ) {
+               assert( !syn->ssyn_validate( syn, si->si_cookieState->cs_vals+i ));
+       }
+#endif
+
        return rc;
 }
 
@@ -3183,8 +3216,6 @@ dn_callback(
                                 * is actually newer than old entry
                                 */
                                if ( !is_entry_glue( rs->sr_entry )) {
-                                       old = attr_find( rs->sr_entry->e_attrs,
-                                               slap_schema.si_ad_objectClass );
                                        old = attr_find( rs->sr_entry->e_attrs,
                                                slap_schema.si_ad_entryCSN );
                                        new = attr_find( dni->new_entry->e_attrs,
@@ -4320,13 +4351,22 @@ add_syncrepl(
                        BER_BVISNULL( &si->si_bindconf.sb_uri ) ?
                        "(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 );
                if ( c->be->be_syncinfo ) {
+                       syncinfo_t *sip;
+
                        si->si_cookieState = c->be->be_syncinfo->si_cookieState;
+
+                       // add new syncrepl to end of list (same order as when deleting)
+                       for ( sip = c->be->be_syncinfo; sip->si_next; sip = sip->si_next );
+                       sip->si_next = si;
                } else {
                        si->si_cookieState = ch_calloc( 1, sizeof( cookie_state ));
                        ldap_pvt_thread_mutex_init( &si->si_cookieState->cs_mutex );
+
+                       c->be->be_syncinfo = si;
                }
-               si->si_next = c->be->be_syncinfo;
-               c->be->be_syncinfo = si;
+
+               si->si_next = NULL;
+
                return 0;
        }
 }
@@ -4523,6 +4563,7 @@ syncrepl_config( ConfigArgs *c )
                return 1;
        } else if ( c->op == LDAP_MOD_DELETE ) {
                cookie_state *cs = NULL;
+               int isrunning = 0;
                if ( c->be->be_syncinfo ) {
                        syncinfo_t *si, **sip;
                        int i;
@@ -4531,19 +4572,21 @@ syncrepl_config( ConfigArgs *c )
                        for ( sip = &c->be->be_syncinfo, i=0; *sip; i++ ) {
                                si = *sip;
                                if ( c->valx == -1 || i == c->valx ) {
-                                       int isrunning = 0;
                                        *sip = si->si_next;
                                        /* If the task is currently active, we have to leave
                                         * it running. It will exit on its own. This will only
                                         * happen when running on the cn=config DB.
                                         */
                                        if ( si->si_re ) {
-                                               ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
-                                               isrunning = ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re );
-                                               ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+                                               if ( ldap_pvt_thread_mutex_trylock( &si->si_mutex )) {
+                                                       isrunning = 1;
+                                               } else {
+                                                       ldap_pvt_thread_mutex_unlock( &si->si_mutex );
+                                               }
                                        }
                                        if ( si->si_re && isrunning ) {
                                                si->si_ctype = 0;
+                                               si->si_next = NULL;
                                        } else {
                                                syncinfo_free( si, 0 );
                                        }
@@ -4556,7 +4599,8 @@ syncrepl_config( ConfigArgs *c )
                }
                if ( !c->be->be_syncinfo ) {
                        SLAP_DBFLAGS( c->be ) &= ~SLAP_DBFLAG_SHADOW_MASK;
-                       if ( cs ) {
+                       if ( cs && !isrunning ) {
+                               ch_free( cs->cs_sids );
                                ber_bvarray_free( cs->cs_vals );
                                ldap_pvt_thread_mutex_destroy( &cs->cs_mutex );
                                ch_free( cs );