X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsyncrepl.c;h=a0b87a9ec47be30a45b198d6b6ca3e487dd8044c;hb=e0cc94a0b72d1fb866c406dc7c940bba9010c84f;hp=8df18f10109959bbfed6b4746848c6a16a55dea2;hpb=5a3a54333cc067209bd6aa53fd84a250f7a48b1d;p=openldap diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 8df18f1010..a0b87a9ec4 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * 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. @@ -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; @@ -82,8 +84,9 @@ typedef struct syncinfo_s { 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; @@ -120,6 +123,7 @@ typedef struct syncinfo_s { int si_got; int si_strict_refresh; /* stop listening during fallback refresh */ int si_too_old; + int si_has_syncprov; ber_int_t si_msgid; Avlnode *si_presentlist; LDAP *si_ld; @@ -149,7 +153,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( @@ -161,7 +165,6 @@ static int syncrepl_op_modify( Operation *op, SlapReply *rs ); /* callback functions */ static int dn_callback( Operation *, SlapReply * ); static int nonpresent_callback( Operation *, SlapReply * ); -static int null_callback( Operation *, SlapReply * ); static AttributeDescription *sync_descs[4]; @@ -175,6 +178,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 +187,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 +197,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 +414,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 +443,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; @@ -557,6 +564,7 @@ check_syncprov( ber_bvarray_free( a.a_nvals ); } ber_bvarray_free( a.a_vals ); + si->si_has_syncprov = 1; } /* See if the cookieState has changed due to anything outside * this particular consumer. That includes other consumers in @@ -721,6 +729,8 @@ do_syncrep1( si->si_syncCookie.sids[i] = si->si_cookieState->cs_sids[i]; } ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); + /* Also look in syncprov overlay, if it was already active */ + check_syncprov( op, si ); } ch_free( si->si_syncCookie.octet_str.bv_val ); @@ -944,6 +954,10 @@ do_syncrep2( check_syncprov( op, si ); ldap_pvt_thread_mutex_lock( &si->si_cookieState->cs_mutex ); for ( i =0; isi_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; @@ -1019,7 +1033,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: @@ -1047,7 +1061,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 ) { @@ -1193,11 +1207,13 @@ 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 ); 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 @@ -1285,6 +1301,8 @@ do_syncrep2( 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", @@ -1379,7 +1397,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 ); @@ -1420,6 +1438,12 @@ do_syncrep2( 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; } } @@ -1780,6 +1804,11 @@ syncrepl_accesslog_mods( 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; @@ -2088,6 +2117,33 @@ syncrepl_op_modify( Operation *op, SlapReply *rs ) 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; isi_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; @@ -2101,6 +2157,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs ) } /* 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; @@ -2141,14 +2198,13 @@ 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 }; + Filter lf[3] = {0}; + AttributeAssertion aa[2] = {0}; rx.rx_si = si; rx.rx_mods = newlist; @@ -2176,7 +2232,21 @@ syncrepl_op_modify( Operation *op, SlapReply *rs ) 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 ); @@ -2194,6 +2264,7 @@ syncrepl_op_modify( Operation *op, SlapReply *rs ) 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; @@ -2215,6 +2286,34 @@ syncrepl_op_modify( Operation *op, SlapReply *rs ) return SLAP_CB_CONTINUE; } +static int +syncrepl_null_callback( + Operation *op, + SlapReply *rs ) +{ + /* If we're not the last callback in the chain, move to the end */ + if ( op->o_callback->sc_next ) { + slap_callback **sc, *s1; + s1 = op->o_callback; + op->o_callback = op->o_callback->sc_next; + for ( sc = &op->o_callback; *sc; sc = &(*sc)->sc_next ) ; + *sc = s1; + s1->sc_next = NULL; + return SLAP_CB_CONTINUE; + } + if ( rs->sr_err != LDAP_SUCCESS && + rs->sr_err != LDAP_REFERRAL && + rs->sr_err != LDAP_ALREADY_EXISTS && + rs->sr_err != LDAP_NO_SUCH_OBJECT && + rs->sr_err != LDAP_NOT_ALLOWED_ON_NONLEAF ) + { + Debug( LDAP_DEBUG_ANY, + "syncrepl_null_callback : error code 0x%x\n", + rs->sr_err, 0, 0 ); + } + return LDAP_SUCCESS; +} + static int syncrepl_message_to_op( syncinfo_t *si, @@ -2226,7 +2325,7 @@ syncrepl_message_to_op( Modifications *modlist = NULL; logschema *ls; SlapReply rs = { REP_RESULT }; - slap_callback cb = { NULL, null_callback, NULL, NULL }; + slap_callback cb = { NULL, syncrepl_null_callback, NULL, NULL }; const char *text; char txtbuf[SLAP_TEXT_BUFLEN]; @@ -2320,6 +2419,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 ) ) { @@ -2338,6 +2453,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: @@ -2845,8 +2963,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 ) { @@ -2941,7 +3059,7 @@ syncrepl_entry( slap_sl_free( op->ors_filterstr.bv_val, op->o_tmpmemctx ); } - cb.sc_response = null_callback; + cb.sc_response = syncrepl_null_callback; cb.sc_private = si; if ( entry && !BER_BVISNULL( &entry->e_name ) ) { @@ -2968,10 +3086,12 @@ syncrepl_entry( si->si_refreshCount = 0; si->si_refreshTxn = NULL; } - if ( !si->si_refreshCount ) { - op->o_bd->bd_info->bi_op_txn( op, SLAP_TXN_BEGIN, &si->si_refreshTxn ); + 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++; } - si->si_refreshCount++; } slap_op_time( &op->o_time, &op->o_tincr ); @@ -3359,7 +3479,7 @@ retry_modrdn:; op->o_delete_glue_parent = 0; if ( !be_issuffix( be, &op->o_req_ndn ) ) { slap_callback cb = { NULL }; - cb.sc_response = slap_null_cb; + cb.sc_response = syncrepl_null_callback; dnParent( &op->o_req_ndn, &pdn ); op->o_req_dn = pdn; op->o_req_ndn = pdn; @@ -3557,7 +3677,7 @@ syncrepl_del_nonpresent( np_list = LDAP_LIST_NEXT( np_list, npe_link ); op->o_tag = LDAP_REQ_DELETE; op->o_callback = &cb; - cb.sc_response = null_callback; + cb.sc_response = syncrepl_null_callback; cb.sc_private = si; op->o_req_dn = *np_prev->npe_name; op->o_req_ndn = *np_prev->npe_nname; @@ -3599,7 +3719,7 @@ syncrepl_del_nonpresent( op->o_delete_glue_parent = 0; if ( !be_issuffix( be, &op->o_req_ndn ) ) { slap_callback cb = { NULL }; - cb.sc_response = slap_null_cb; + cb.sc_response = syncrepl_null_callback; dnParent( &op->o_req_ndn, &pdn ); op->o_req_dn = pdn; op->o_req_ndn = pdn; @@ -3652,7 +3772,7 @@ syncrepl_add_glue_ancestors( op->o_tag = LDAP_REQ_ADD; op->o_callback = &cb; - cb.sc_response = null_callback; + cb.sc_response = syncrepl_null_callback; cb.sc_private = NULL; dn = e->e_name; @@ -3794,7 +3914,7 @@ syncrepl_add_glue( op->o_tag = LDAP_REQ_ADD; op->o_callback = &cb; - cb.sc_response = null_callback; + cb.sc_response = syncrepl_null_callback; cb.sc_private = NULL; op->o_req_dn = e->e_name; @@ -3815,7 +3935,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; @@ -3839,6 +3960,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; inumcsns; i++ ) { @@ -3901,44 +4024,56 @@ syncrepl_updateCookie( ch_free( sc.sids ); return 0; } - op->o_bd = si->si_wbe; - slap_queue_csn( op, &first ); - op->o_tag = LDAP_REQ_MODIFY; + si->si_cookieState->cs_updating = 1; + ldap_pvt_thread_mutex_unlock( &si->si_cookieState->cs_mutex ); - cb.sc_response = null_callback; - cb.sc_private = si; + if ( save || !si->si_has_syncprov ) { + op->o_bd = si->si_wbe; + slap_queue_csn( op, &first ); - op->o_callback = &cb; - op->o_req_dn = si->si_contextdn; - op->o_req_ndn = si->si_contextdn; + op->o_tag = LDAP_REQ_MODIFY; + + cb.sc_response = syncrepl_null_callback; + cb.sc_private = si; - /* update contextCSN */ - op->o_dont_replicate = 1; + op->o_callback = &cb; + op->o_req_dn = si->si_contextdn; + op->o_req_ndn = si->si_contextdn; - mod.sml_numvals = sc.numcsns; - mod.sml_values = sc.ctxcsn; + /* update contextCSN */ + op->o_dont_replicate = 1; - op->orm_modlist = &mod; - op->orm_no_opattrs = 1; - rc = op->o_bd->be_modify( op, &rs_modify ); + mod.sml_numvals = sc.numcsns; + mod.sml_values = sc.ctxcsn; - if ( rs_modify.sr_err == LDAP_NO_SUCH_OBJECT && - SLAP_SYNC_SUBENTRY( op->o_bd )) { - const char *text; - char txtbuf[SLAP_TEXT_BUFLEN]; - size_t textlen = sizeof txtbuf; - 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); - op->ora_e = e; - rc = op->o_bd->be_add( op, &rs_modify ); - if ( e == op->ora_e ) - be_entry_release_w( op, op->ora_e ); + op->orm_modlist = &mod; + op->orm_no_opattrs = 1; + rc = op->o_bd->be_modify( op, &rs_modify ); + + if ( rs_modify.sr_err == LDAP_NO_SUCH_OBJECT && + SLAP_SYNC_SUBENTRY( op->o_bd )) { + const char *text; + char txtbuf[SLAP_TEXT_BUFLEN]; + size_t textlen = sizeof txtbuf; + 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); + op->ora_e = e; + rc = op->o_bd->be_add( op, &rs_modify ); + if ( e == op->ora_e ) + be_entry_release_w( op, op->ora_e ); + } + + op->orm_no_opattrs = 0; + op->o_dont_replicate = 0; + } else { + rc = 0; } 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 ); @@ -3971,10 +4106,13 @@ 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; - op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx ); + if ( op->o_csn.bv_val ) + op->o_tmpfree( op->o_csn.bv_val, op->o_tmpmemctx ); BER_BVZERO( &op->o_csn ); if ( mod.sml_next ) slap_mods_free( mod.sml_next, 1 ); @@ -4399,24 +4537,6 @@ nonpresent_callback( return LDAP_SUCCESS; } -static int -null_callback( - Operation* op, - SlapReply* rs ) -{ - if ( rs->sr_err != LDAP_SUCCESS && - rs->sr_err != LDAP_REFERRAL && - rs->sr_err != LDAP_ALREADY_EXISTS && - rs->sr_err != LDAP_NO_SUCH_OBJECT && - rs->sr_err != LDAP_NOT_ALLOWED_ON_NONLEAF ) - { - Debug( LDAP_DEBUG_ANY, - "null_callback : error code 0x%x\n", - rs->sr_err, 0, 0 ); - } - return LDAP_SUCCESS; -} - static struct berval * slap_uuidstr_from_normalized( struct berval* uuidstr, @@ -4573,6 +4693,9 @@ syncinfo_free( syncinfo_t *sie, int free_all ) 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 ); } @@ -4650,6 +4773,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 ); @@ -5294,6 +5418,15 @@ parse_syncrepl_line( 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; } @@ -5447,6 +5580,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; } @@ -5675,7 +5809,7 @@ syncrepl_config( ConfigArgs *c ) * 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 @@ -5695,8 +5829,7 @@ syncrepl_config( ConfigArgs *c ) 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 );