/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 2003-2015 The OpenLDAP Foundation.
+ * Copyright 2003-2017 The OpenLDAP Foundation.
* Portions Copyright 2003 by IBM Corporation.
* Portions Copyright 2003-2008 by Howard Chu, Symas Corporation.
* All rights reserved.
struct berval si_base;
struct berval si_logbase;
struct berval si_filterstr;
- Filter *si_filter;
struct berval si_logfilterstr;
+ Filter *si_filter;
+ Filter *si_logfilter;
struct berval si_contextdn;
int si_scope;
int si_attrsonly;
int si_refreshDelete;
int si_refreshPresent;
int si_refreshDone;
+ int si_refreshCount;
+ time_t si_refreshBeg;
+ time_t si_refreshEnd;
+ OpExtra *si_refreshTxn;
int si_syncdata;
int si_logstate;
int si_lazyCommit;
}
si->si_refreshDone = 0;
+ si->si_refreshBeg = slap_get_time();
+ si->si_refreshCount = 0;
+ si->si_refreshTxn = NULL;
+ Debug( LDAP_DEBUG_ANY, "do_syncrep1: %s starting refresh\n",
+ si->si_ridtxt, 0, 0 );
rc = ldap_sync_search( si, op->o_tmpmemctx );
check_syncprov( op, si );
ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
for ( i =0; i<si->si_cookieState->cs_num; i++ ) {
+#ifdef CHATTY_SYNCLOG
+ Debug( LDAP_DEBUG_SYNC, "do_syncrep2: %s CSN for sid %d: %s\n",
+ si->si_ridtxt, i, si->si_cookieState->cs_vals[i].bv_val );
+#endif
/* new SID */
if ( sid < si->si_cookieState->cs_sids[i] )
break;
{
rc = syncrepl_updateCookie( si, op, &syncCookie );
}
+ if ( si->si_refreshCount ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, si->si_refreshTxn, OpExtra, oe_next );
+ op->o_bd->bd_info->bi_op_txn( op, SLAP_TXN_COMMIT, &si->si_refreshTxn );
+ si->si_refreshCount = 0;
+ si->si_refreshTxn = NULL;
+ }
+ si->si_refreshEnd = slap_get_time();
if ( err == LDAP_SUCCESS
&& si->si_logstate == SYNCLOG_FALLBACK ) {
si->si_logstate = SYNCLOG_LOGGING;
{
si->si_refreshDone = 1;
}
+ if ( si->si_refreshDone ) {
+ if ( si->si_refreshCount ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, si->si_refreshTxn, OpExtra, oe_next );
+ op->o_bd->bd_info->bi_op_txn( op, SLAP_TXN_COMMIT, &si->si_refreshTxn );
+ si->si_refreshCount = 0;
+ si->si_refreshTxn = NULL;
+ }
+ si->si_refreshEnd = slap_get_time();
+ Debug( LDAP_DEBUG_ANY, "do_syncrep1: %s finished refresh\n",
+ si->si_ridtxt, 0, 0 );
+ }
ber_scanf( ber, /*"{"*/ "}" );
if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST &&
si->si_refreshDone )
if ( ldap_pvt_thread_pool_pausing( &connection_pool )) {
slap_sync_cookie_free( &syncCookie, 0 );
slap_sync_cookie_free( &syncCookie_req, 0 );
+ if ( si->si_refreshCount ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, si->si_refreshTxn, OpExtra, oe_next );
+ op->o_bd->bd_info->bi_op_txn( op, SLAP_TXN_COMMIT, &si->si_refreshTxn );
+ si->si_refreshCount = 0;
+ si->si_refreshTxn = NULL;
+ }
return SYNC_PAUSED;
}
}
if ( !colon ) {
/* Invalid */
continue;
+ } else if ( colon == bv.bv_val ) {
+ /* ITS#6545: An empty attribute signals that a new mod
+ * is about to start */
+ mod = NULL;
+ continue;
}
bv.bv_len = colon - bv.bv_val;
if ( !mod )
return SLAP_CB_CONTINUE;
+ {
+ int i, sid;
+ sid = slap_parse_csn_sid( &mod->sml_nvalues[0] );
+ ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex );
+ for ( i =0; i<si->si_cookieState->cs_num; i++ ) {
+#ifdef CHATTY_SYNCLOG
+ Debug( LDAP_DEBUG_SYNC, "syncrepl_op_modify: %s CSN for sid %d: %s\n",
+ si->si_ridtxt, i, si->si_cookieState->cs_vals[i].bv_val );
+#endif
+ /* new SID */
+ if ( sid < si->si_cookieState->cs_sids[i] )
+ break;
+ if ( si->si_cookieState->cs_sids[i] == sid ) {
+ if ( ber_bvcmp( &mod->sml_nvalues[0], &si->si_cookieState->cs_vals[i] ) <= 0 ) {
+ Debug( LDAP_DEBUG_SYNC, "syncrepl_op_modify: %s entryCSN too old, ignoring %s (%s)\n",
+ si->si_ridtxt, mod->sml_nvalues[0].bv_val, op->o_req_dn.bv_val );
+ ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
+ slap_graduate_commit_csn( op );
+ /* tell accesslog this was a failure */
+ rs->sr_err = LDAP_TYPE_OR_VALUE_EXISTS;
+ return LDAP_SUCCESS;
+ }
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex );
+ }
+
rc = overlay_entry_get_ov( op, &op->o_req_ndn, NULL, NULL, 0, &e, on );
if ( rc == 0 ) {
Attribute *a;
}
/* equal? Should never happen */
if ( match == 0 ) {
+ slap_graduate_commit_csn( op );
/* tell accesslog this was a failure */
rs->sr_err = LDAP_TYPE_OR_VALUE_EXISTS;
return LDAP_SUCCESS;
SlapReply rs1 = {0};
resolve_ctxt rx;
slap_callback cb = { NULL, syncrepl_resolve_cb, NULL, NULL };
+ Filter lf[3] = {0};
+ AttributeAssertion aa[2] = {0};
rx.rx_si = si;
rx.rx_mods = newlist;
op2.ors_filterstr.bv_len = sprintf(op2.ors_filterstr.bv_val,
"(&(entryCSN>=%s)(reqDN=%s)%s)",
bv.bv_val, op->o_req_ndn.bv_val, si->si_logfilterstr.bv_val );
- op2.ors_filter = str2filter_x( op, op2.ors_filterstr.bv_val );
+
+ lf[0].f_choice = LDAP_FILTER_AND;
+ lf[0].f_and = lf+1;
+ lf[1].f_choice = LDAP_FILTER_GE;
+ lf[1].f_ava = aa;
+ lf[1].f_av_desc = slap_schema.si_ad_entryCSN;
+ lf[1].f_av_value = bv;
+ lf[1].f_next = lf+2;
+ lf[2].f_choice = LDAP_FILTER_EQUALITY;
+ lf[2].f_ava = aa+1;
+ lf[2].f_av_desc = ad_reqDN;
+ lf[2].f_av_value = op->o_req_ndn;
+ lf[2].f_next = si->si_logfilter;
+
+ op2.ors_filter = lf;
op2.o_callback = &cb;
op2.o_bd = select_backend( &op2.o_req_ndn, 1 );
sc->sc_private = mx;
sc->sc_next = op->o_callback;
sc->sc_cleanup = NULL;
+ sc->sc_writewait = NULL;
op->o_callback = sc;
op->orm_no_opattrs = 1;
mx->mx_orig = op->orm_modlist;
Avlnode **a2 = (Avlnode **)av;
unsigned short s;
+ if (!av)
+ return NULL;
+
memcpy(&s, val->bv_val, 2);
return avl_find( a2[s], val->bv_val+2, syncuuid_cmp );
#else
slap_queue_csn( op, syncCSN );
}
- if ( !si->si_refreshDone && si->si_lazyCommit )
- op->o_lazyCommit = SLAP_CONTROL_NONCRITICAL;
+ if ( !si->si_refreshDone ) {
+ if ( si->si_lazyCommit )
+ op->o_lazyCommit = SLAP_CONTROL_NONCRITICAL;
+ if ( si->si_refreshCount == 500 ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, si->si_refreshTxn, OpExtra, oe_next );
+ op->o_bd->bd_info->bi_op_txn( op, SLAP_TXN_COMMIT, &si->si_refreshTxn );
+ si->si_refreshCount = 0;
+ si->si_refreshTxn = NULL;
+ }
+ if ( op->o_bd->bd_info->bi_op_txn ) {
+ if ( !si->si_refreshCount ) {
+ op->o_bd->bd_info->bi_op_txn( op, SLAP_TXN_BEGIN, &si->si_refreshTxn );
+ }
+ si->si_refreshCount++;
+ }
+ }
slap_op_time( &op->o_time, &op->o_tincr );
switch ( syncstate ) {
if ( sie->si_logfilterstr.bv_val ) {
ch_free( sie->si_logfilterstr.bv_val );
}
+ if ( sie->si_logfilter ) {
+ filter_free( sie->si_logfilter );
+ }
if ( sie->si_base.bv_val ) {
ch_free( sie->si_base.bv_val );
}
return 1;
}
+ if ( si->si_got & GOT_LOGFILTER ) {
+ si->si_logfilter = str2filter( si->si_logfilterstr.bv_val );
+ if ( si->si_logfilter == NULL ) {
+ Debug( LDAP_DEBUG_ANY, "syncrepl %s " SEARCHBASESTR "=\"%s\": unable to parse logfilter=\"%s\"\n",
+ si->si_ridtxt, c->be->be_suffix ? c->be->be_suffix[ 0 ].bv_val : "(null)", si->si_logfilterstr.bv_val );
+ return 1;
+ }
+ }
+
return 0;
}
* happen when running on the cn=config DB.
*/
if ( si->si_re ) {
- if ( ldap_pvt_thread_mutex_trylock( &si->si_mutex )) {
+ if ( si->si_be == c->be || ldap_pvt_thread_mutex_trylock( &si->si_mutex )) {
isrunning = 1;
} else {
/* There is no active thread, but we must still
ldap_pvt_runqueue_stoptask( &slapd_rq, re );
isrunning = 1;
}
- if ( ldap_pvt_thread_pool_retract( &connection_pool,
- re->routine, re ) > 0 )
+ if ( ldap_pvt_thread_pool_retract( re->pool_cookie ) > 0 )
isrunning = 0;
ldap_pvt_runqueue_remove( &slapd_rq, re );