/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2003-2011 The OpenLDAP Foundation.
+ * Copyright 2003-2012 The OpenLDAP Foundation.
* Portions Copyright 2003 by IBM Corporation.
* Portions Copyright 2003-2008 by Howard Chu, Symas Corporation.
* All rights reserved.
int delOldRDN; /* Was old RDN deleted? */
Modifications **modlist; /* the modlist we received */
Modifications *mods; /* the modlist we compared */
- Attribute *oldNattr; /* old naming attr */
+ int oldNcount; /* #values of old naming attr */
AttributeDescription *oldDesc; /* for renames */
AttributeDescription *newDesc; /* for renames */
} dninfo;
*/
op->o_csn = a->a_vals[0];
freecsn = 0;
+ /* There was no cookie CSN attached to this op,
+ * make sure it's new enough
+ */
+ if ( !syncCSN ) {
+ int i, sid = slap_parse_csn_sid( &a->a_vals[0] );
+ for ( i = 0; i<si->si_cookieState->cs_num; i++ ) {
+ if ( sid < si->si_cookieState->cs_sids[i] )
+ break;
+ if ( sid == si->si_cookieState->cs_sids[i] ) {
+ if ( ber_bvcmp( &a->a_vals[0], &si->si_cookieState->cs_vals[i] ) <= 0 ) {
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s entryCSN too old, ignoring %s (%s)\n",
+ si->si_ridtxt, a->a_vals[0].bv_val, entry->e_name.bv_val );
+ goto done;
+ }
+ }
+ }
+ }
}
}
retry_add:;
case LDAP_REFERRAL:
/* we assume that LDAP_NO_SUCH_OBJECT is returned
- * only if the suffix entry is not present */
+ * only if the suffix entry is not present.
+ * This should not happen during Persist phase.
+ */
case LDAP_NO_SUCH_OBJECT:
+ if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST &&
+ si->si_refreshDone ) {
+ /* Something's wrong, start over */
+ ber_bvarray_free( si->si_syncCookie.ctxcsn );
+ si->si_syncCookie.ctxcsn = NULL;
+ ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
+ ber_bvarray_free( si->si_cookieState->cs_vals );
+ ch_free( si->si_cookieState->cs_sids );
+ si->si_cookieState->cs_vals = NULL;
+ si->si_cookieState->cs_sids = 0;
+ si->si_cookieState->cs_num = 0;
+ ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
+ return LDAP_NO_SUCH_OBJECT;
+ }
rc = syncrepl_add_glue( op, entry );
entry = NULL;
break;
* If delOldRDN is TRUE then we should see a delete modop
* for oldDesc. We might see a replace instead.
* delete with no values: therefore newDesc != oldDesc.
- * if oldNattr had only one value, then Drop this op.
+ * if oldNcount == 1, then Drop this op.
* delete with 1 value: can only be the oldRDN value. Drop op.
* delete with N values: Drop oldRDN value, keep remainder.
- * replace with 1 value: if oldNattr had only one value and
+ * replace with 1 value: if oldNcount == 1 and
* newDesc == oldDesc, Drop this op.
* Any other cases must be left intact.
*
continue;
}
if ( mod->sml_numvals <= 1 &&
- dni.oldNattr->a_numvals == 1 &&
+ dni.oldNcount == 1 &&
( mod->sml_op == LDAP_MOD_DELETE ||
mod->sml_op == LDAP_MOD_REPLACE )) {
if ( mod->sml_op == LDAP_MOD_REPLACE )
Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s be_delete %s (%d)\n",
si->si_ridtxt, op->o_req_dn.bv_val, rc );
+ if ( rc == LDAP_NO_SUCH_OBJECT )
+ rc = LDAP_SUCCESS;
while ( rs_delete.sr_err == LDAP_SUCCESS
&& op->o_delete_glue_parent ) {
}
if ( !BER_BVISEMPTY( &ptr ) ) {
- dn.bv_len -= ptr.bv_len + 1;
- dn.bv_val += ptr.bv_len + 1;
+ dn.bv_len -= ptr.bv_len + ( suffrdns != 0 );
+ dn.bv_val += ptr.bv_len + ( suffrdns != 0 );
}
/* the normalizedDNs are always the same length, no counting
dni->oldDesc = ad;
for ( oldpos=0, a=rs->sr_entry->e_attrs;
a && a->a_desc != ad; oldpos++, a=a->a_next );
- dni->oldNattr = a;
+ /* a should not be NULL but apparently it happens.
+ * ITS#7144
+ */
+ dni->oldNcount = a ? a->a_numvals : 0;
for ( newpos=0, a=dni->new_entry->e_attrs;
a && a->a_desc != ad; newpos++, a=a->a_next );
if ( !a || oldpos != newpos || attr_valfind( a,
ldap_pvt_runqueue_stoptask( &slapd_rq, re );
isrunning = 1;
}
- ldap_pvt_runqueue_remove( &slapd_rq, re );
- ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-
if ( ldap_pvt_thread_pool_retract( &connection_pool,
re->routine, re ) > 0 )
isrunning = 0;
+ ldap_pvt_runqueue_remove( &slapd_rq, re );
+ ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+
ldap_pvt_thread_mutex_unlock( &si->si_mutex );
}
}