ldap_avl_info_t li_conninfo;
- slap_retry_info_t li_quarantine;
- /* NOTE: quarantine uses the connection mutex */
sig_atomic_t li_isquarantined;
#define LDAP_BACK_FQ_NO (0)
#define LDAP_BACK_FQ_YES (1)
#define LDAP_BACK_FQ_RETRYING (2)
+ slap_retry_info_t li_quarantine;
#define LDAP_BACK_QUARANTINE(li) ( (li)->li_quarantine.ri_num != NULL )
+ ldap_pvt_thread_mutex_t li_quarantine_mutex;
ldap_back_quarantine_f li_quarantine_f;
void *li_quarantine_p;
slap_retry_info_t *ri = &li->li_quarantine;
int dont_retry = 1;
- ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
+ ldap_pvt_thread_mutex_lock( &li->li_quarantine_mutex );
if ( li->li_isquarantined == LDAP_BACK_FQ_YES ) {
dont_retry = ( ri->ri_num[ ri->ri_idx ] == SLAP_RETRYNUM_TAIL
|| slap_get_time() < ri->ri_last + ri->ri_interval[ ri->ri_idx ] );
li->li_isquarantined = LDAP_BACK_FQ_RETRYING;
}
}
- ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
+ ldap_pvt_thread_mutex_unlock( &li->li_quarantine_mutex );
if ( dont_retry ) {
rs->sr_err = LDAP_UNAVAILABLE;
void
ldap_back_quarantine(
Operation *op,
- SlapReply *rs,
- int dolock )
+ SlapReply *rs )
{
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
slap_retry_info_t *ri = &li->li_quarantine;
- if ( dolock ) {
- ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
- }
+ ldap_pvt_thread_mutex_lock( &li->li_quarantine_mutex );
if ( rs->sr_err == LDAP_UNAVAILABLE ) {
switch ( li->li_isquarantined ) {
li->li_isquarantined = LDAP_BACK_FQ_NO;
}
- if ( dolock ) {
- ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
- }
+ ldap_pvt_thread_mutex_unlock( &li->li_quarantine_mutex );
}
/*
}
if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, dolock );
+ ldap_back_quarantine( op, rs );
}
goto done;
rs->sr_err = slap_map_api2result( rs );
if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, dolock );
+ ldap_back_quarantine( op, rs );
}
return 0;
}
}
if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, 1 );
+ ldap_back_quarantine( op, rs );
}
if ( op->o_conn &&
( ( sendok & LDAP_BACK_SENDOK )
goto done;
}
- if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
+ if ( op->o_tag == LDAP_REQ_BIND ) {
+ ndn = op->o_req_ndn;
+
+ } else if ( !BER_BVISNULL( &op->o_conn->c_ndn ) ) {
ndn = op->o_conn->c_ndn;
} else {
}
slap_retry_info_destroy( &li->li_quarantine );
+ ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex );
li->li_isquarantined = 0;
break;
c->msg, sizeof( c->msg ) );
if ( rc ) {
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+
+ } else {
+ ldap_pvt_thread_mutex_init( &li->li_quarantine_mutex );
+ /* give it a chance to retry if the pattern gets reset
+ * via back-config */
+ li->li_isquarantined = 0;
}
- /* give it a chance to retry if the pattern gets reset
- * via back-config */
- li->li_isquarantined = 0;
break;
case LDAP_BACK_CFG_REWRITE:
}
if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, 1 );
+ ldap_back_quarantine( op, rs );
}
if ( text ) rs->sr_text = text;
rc = rs->sr_err = SLAPD_ABANDON;
} else if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, 1 );
+ ldap_back_quarantine( op, rs );
}
/* these have to be freed anyway... */
}
if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, 1 );
+ ldap_back_quarantine( op, rs );
}
if ( text ) rs->sr_text = text;
rc = rs->sr_err = SLAPD_ABANDON;
} else if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, 1 );
+ ldap_back_quarantine( op, rs );
}
/* these have to be freed anyway... */
}
if ( LDAP_BACK_QUARANTINE( li ) ) {
slap_retry_info_destroy( &li->li_quarantine );
+ ldap_pvt_thread_mutex_destroy( &li->li_quarantine_mutex );
}
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
extern void
ldap_back_quarantine(
Operation *op,
- SlapReply *rs,
- int dolock );
+ SlapReply *rs );
extern void slap_retry_info_destroy( slap_retry_info_t *ri );
extern int slap_retry_info_parse( char *in, slap_retry_info_t *ri,
finish:;
if ( LDAP_BACK_QUARANTINE( li ) ) {
- ldap_back_quarantine( op, rs, 1 );
+ ldap_back_quarantine( op, rs );
}
if ( rc != SLAPD_ABANDON ) {
} else {
send_ldap_result( op, rs );
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
}
sig_atomic_t mt_isquarantined;
slap_retry_info_t mt_quarantine;
+ ldap_pvt_thread_mutex_t mt_quarantine_mutex;
+#define META_BACK_TGT_QUARANTINE(mt) ( (mt)->mt_quarantine.ri_num != NULL )
unsigned mt_flags;
#define META_BACK_TGT_ISSET(mt,f) ( ( (mt)->mt_flags & (f) ) == (f) )
meta_back_quarantine(
Operation *op,
SlapReply *rs,
- int candidate,
- int dolock );
+ int candidate );
extern int
meta_back_single_bind(
* invalidCredentials */
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_DONTSEND );
if ( !mc ) {
- char buf[ SLAP_TEXT_BUFLEN ];
-
- snprintf( buf, sizeof( buf ),
- "meta_back_bind: no target "
- "for dn \"%s\" (%d%s%s).",
- op->o_req_dn.bv_val, rs->sr_err,
- rs->sr_text ? ". " : "",
- rs->sr_text ? rs->sr_text : "" );
- Debug( LDAP_DEBUG_ANY,
- "%s %s\n",
- op->o_log_prefix, buf, 0 );
+ if ( LogTest( LDAP_DEBUG_ANY ) ) {
+ char buf[ SLAP_TEXT_BUFLEN ];
+
+ snprintf( buf, sizeof( buf ),
+ "meta_back_bind: no target "
+ "for dn \"%s\" (%d%s%s).",
+ op->o_req_dn.bv_val, rs->sr_err,
+ rs->sr_text ? ". " : "",
+ rs->sr_text ? rs->sr_text : "" );
+ Debug( LDAP_DEBUG_ANY,
+ "%s %s\n",
+ op->o_log_prefix, buf, 0 );
+ }
/* FIXME: there might be cases where we don't want
* to map the error onto invalidCredentials */
free( mdn.bv_val );
}
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mt ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
return rs->sr_err;
}
}
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, dolock );
+ if ( META_BACK_TGT_QUARANTINE( mt ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
return rc;
rerr = rs->sr_err = slap_map_api2result( rs );
Debug(LDAP_DEBUG_ANY,
- "==> meta_back_op_result: target"
- " <%d> sending msg \"%s\""
- " (matched \"%s\")\n",
+ "==> meta_back_op_result[%d] "
+ "text=\"%s\" matched=\"%s\"\n",
candidate, ( rmsg ? rmsg : "" ),
( rmatch ? rmatch : "" ) );
}
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
} else {
rs->sr_err = slap_map_api2result( rs );
Debug(LDAP_DEBUG_ANY,
- "==> meta_back_op_result: target"
- " <%d> sending msg \"%s\""
- " (matched \"%s\")\n",
+ "==> meta_back_op_result[%d] "
+ "text=\"%s\" matched=\"%s\"\n",
i, ( msg ? msg : "" ),
( match ? match : "" ) );
}
}
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, i, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) {
+ meta_back_quarantine( op, rs, i );
}
}
}
mt->mt_nretries = mi->mi_nretries;
mt->mt_quarantine = mi->mi_quarantine;
+ if ( META_BACK_QUARANTINE( mi ) ) {
+ ldap_pvt_thread_mutex_init( &mt->mt_quarantine_mutex );
+ }
mt->mt_flags = mi->mi_flags;
mt->mt_version = mi->mi_version;
mt->mt_network_timeout = mi->mi_network_timeout;
&mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_quarantine
: &mi->mi_quarantine;
- if ( META_BACK_QUARANTINE( mi ) ) {
+ if ( ( mi->mi_ntargets == 0 && META_BACK_QUARANTINE( mi ) )
+ || ( mi->mi_ntargets > 0 && META_BACK_TGT_QUARANTINE( mi->mi_targets[ mi->mi_ntargets - 1 ] ) ) )
+ {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: quarantine already defined.\n",
fname, lineno, 0 );
ri->ri_num = NULL;
}
+ if ( mi->mi_ntargets > 0 && !META_BACK_QUARANTINE( mi ) ) {
+ ldap_pvt_thread_mutex_init( &mi->mi_targets[ mi->mi_ntargets - 1 ]->mt_quarantine_mutex );
+ }
+
if ( slap_retry_info_parse( argv[ 1 ], ri, buf, sizeof( buf ) ) ) {
Debug( LDAP_DEBUG_ANY,
"%s line %d: %s.\n",
goto error_return;
}
- /* copy the DN if needed */
+ /* copy the DN idf needed */
if ( msc->msc_bound_ndn.bv_val == op->o_conn->c_dn.bv_val ) {
ber_dupbv( &msc->msc_bound_ndn, &op->o_conn->c_dn );
}
}
}
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 0 );
+ if ( META_BACK_TGT_QUARANTINE( mt ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
/* Explicit Bind requests always get their own conn */
if ( !( sendok & LDAP_BACK_BINDING ) ) {
/* Searches for a metaconn in the avl tree */
-retry_lock:
- new_conn = 0;
+retry_lock:;
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
(caddr_t)&mc_curr, meta_back_conndn_cmp );
candidates[ i ].sr_err = lerr;
err = lerr;
- Debug( LDAP_DEBUG_ANY, "%s: meta_back_getconn[%d] failed: %d\n",
- op->o_log_prefix, i, lerr );
+ if ( lerr == LDAP_UNAVAILABLE && mt->mt_isquarantined != LDAP_BACK_FQ_NO ) {
+ Debug( LDAP_DEBUG_TRACE, "%s: meta_back_getconn[%d] quarantined: %d\n",
+ op->o_log_prefix, i, lerr );
+
+ } else {
+ Debug( LDAP_DEBUG_ANY, "%s: meta_back_getconn[%d] failed: %d\n",
+ op->o_log_prefix, i, lerr );
+ }
if ( META_BACK_ONERR_STOP( mi ) ) {
if ( sendok & LDAP_BACK_SENDERR ) {
break;
case -1:
+ /* duplicate: free and try to get the newly created one */
if ( !( sendok & LDAP_BACK_BINDING ) ) {
- /* duplicate: free and try to get the newly created one */
+ new_conn = 0;
goto retry_lock;
}
LDAP_BACK_CONN_TAINTED_SET( mc );
meta_back_quarantine(
Operation *op,
SlapReply *rs,
- int candidate,
- int dolock )
+ int candidate )
{
metainfo_t *mi = (metainfo_t *)op->o_bd->be_private;
metatarget_t *mt = mi->mi_targets[ candidate ];
slap_retry_info_t *ri = &mt->mt_quarantine;
- if ( dolock ) {
- ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
- }
+ ldap_pvt_thread_mutex_lock( &mt->mt_quarantine_mutex );
if ( rs->sr_err == LDAP_UNAVAILABLE ) {
switch ( mt->mt_isquarantined ) {
case LDAP_BACK_FQ_NO:
Debug( LDAP_DEBUG_ANY,
- "%s: meta_back_quarantine enter.\n",
- op->o_log_prefix, 0, 0 );
+ "%s: meta_back_quarantine[%d] enter.\n",
+ op->o_log_prefix, candidate, 0 );
ri->ri_idx = 0;
ri->ri_count = 0;
break;
case LDAP_BACK_FQ_RETRYING:
- Debug( LDAP_DEBUG_ANY,
- "%s: meta_back_quarantine block #%d try #%d failed.\n",
- op->o_log_prefix, ri->ri_idx, ri->ri_count );
+ if ( LogTest( LDAP_DEBUG_ANY ) ) {
+ char buf[ SLAP_TEXT_BUFLEN ];
+
+ snprintf( buf, sizeof( buf ),
+ "meta_back_quarantine[%d] block #%d try #%d failed",
+ candidate, ri->ri_idx, ri->ri_count );
+ Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
+ op->o_log_prefix, buf, 0 );
+ }
++ri->ri_count;
if ( ri->ri_num[ ri->ri_idx ] != SLAP_RETRYNUM_FOREVER
mt->mt_isquarantined = LDAP_BACK_FQ_YES;
ri->ri_last = slap_get_time();
- } else if ( mt->mt_isquarantined != LDAP_BACK_FQ_NO ) {
+ } else if ( mt->mt_isquarantined == LDAP_BACK_FQ_RETRYING ) {
Debug( LDAP_DEBUG_ANY,
- "%s: meta_back_quarantine exit.\n",
- op->o_log_prefix, ri->ri_idx, ri->ri_count );
+ "%s: meta_back_quarantine[%d] exit.\n",
+ op->o_log_prefix, candidate, 0 );
if ( mi->mi_quarantine_f ) {
(void)mi->mi_quarantine_f( mi, candidate,
mt->mt_isquarantined = LDAP_BACK_FQ_NO;
}
- if ( dolock ) {
- ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
- }
+ ldap_pvt_thread_mutex_unlock( &mt->mt_quarantine_mutex );
}
} else {
send_ldap_result( op, rs );
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
}
*/
if ( mi->mi_targets != NULL ) {
for ( i = 0; i < mi->mi_ntargets; i++ ) {
- if ( META_BACK_QUARANTINE( mi )
- && mi->mi_targets[ i ]->mt_quarantine.ri_num != mi->mi_quarantine.ri_num )
- {
- slap_retry_info_destroy( &mi->mi_targets[ i ]->mt_quarantine );
+ metatarget_t *mt = mi->mi_targets[ i ];
+
+ if ( META_BACK_TGT_QUARANTINE( mt ) ) {
+ if ( mt->mt_quarantine.ri_num != mi->mi_quarantine.ri_num )
+ {
+ slap_retry_info_destroy( &mt->mt_quarantine );
+ }
+
+ ldap_pvt_thread_mutex_destroy( &mt->mt_quarantine_mutex );
}
- target_free( mi->mi_targets[ i ] );
+ target_free( mt );
}
free( mi->mi_targets );
} else {
send_ldap_result( op, rs );
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
}
} else {
send_ldap_result( op, rs );
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, rs, candidate, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ candidate ] ) ) {
+ meta_back_quarantine( op, rs, candidate );
}
}
candidates[ i ].sr_ctrls = NULL;
}
- if ( META_BACK_QUARANTINE( mi ) ) {
- meta_back_quarantine( op, &candidates[ i ], i, 1 );
+ if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) {
+ meta_back_quarantine( op, &candidates[ i ], i );
}
}