refine fix to ITS#4315; apply it to back-meta as well

This commit is contained in:
Pierangelo Masarati 2006-01-09 14:20:37 +00:00
parent a2933d10d4
commit 6995603a3d
3 changed files with 48 additions and 28 deletions

View File

@ -468,7 +468,7 @@ ldapconn_t *
ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{
ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
ldapconn_t *lc,
ldapconn_t *lc = NULL,
lc_curr = { 0 };
int refcnt = 1;
@ -490,9 +490,7 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
}
/* Explicit Bind requests always get their own conn */
if ( sendok & LDAP_BACK_BINDING ) {
lc = NULL;
} else {
if ( !( sendok & LDAP_BACK_BINDING ) ) {
/* Searches for a ldapconn in the avl tree */
retry_lock:
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
@ -500,13 +498,13 @@ retry_lock:
lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree,
(caddr_t)&lc_curr, ldap_back_conn_cmp );
if ( lc != NULL ) {
refcnt = ++lc->lc_refcnt;
/* Don't reuse connections while they're still binding */
if ( LDAP_BACK_CONN_BINDING( lc )) {
if ( LDAP_BACK_CONN_BINDING( lc ) ) {
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
ldap_pvt_thread_yield();
goto retry_lock;
}
refcnt = ++lc->lc_refcnt;
}
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
}
@ -516,9 +514,9 @@ retry_lock:
if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
return NULL;
}
if ( sendok & LDAP_BACK_BINDING )
if ( sendok & LDAP_BACK_BINDING ) {
LDAP_BACK_CONN_BINDING_SET( lc );
}
lc->lc_conn = lc_curr.lc_conn;
ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );

View File

@ -91,7 +91,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
/* we need meta_back_getconn() not send result even on error,
* because we want to intercept the error and make it
* invalidCredentials */
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_DONTSEND );
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_SERR );
if ( !mc ) {
char buf[ SLAP_TEXT_BUFLEN ];

View File

@ -755,21 +755,31 @@ meta_back_getconn(
}
}
/* Searches for a metaconn in the avl tree */
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_conn_cmp );
if ( mc ) {
if ( mc->mc_tainted ) {
rs->sr_err = LDAP_UNAVAILABLE;
rs->sr_text = "remote server unavailable";
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
return NULL;
}
/* Explicit Bind requests always get their own conn */
if ( !( sendok & LDAP_BACK_BINDING ) ) {
/* Searches for a metaconn in the avl tree */
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_conn_cmp );
if ( mc ) {
if ( mc->mc_tainted ) {
rs->sr_err = LDAP_UNAVAILABLE;
rs->sr_text = "remote server unavailable";
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
return NULL;
}
mc->mc_refcnt++;
/* Don't reuse connections while they're still binding */
if ( LDAP_BACK_CONN_BINDING( mc ) ) {
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_yield();
goto retry_lock;
}
mc->mc_refcnt++;
}
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
}
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
switch ( op->o_tag ) {
case LDAP_REQ_ADD:
@ -822,6 +832,9 @@ meta_back_getconn(
mc->mc_conn = mc_curr.mc_conn;
ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
new_conn = 1;
if ( sendok & LDAP_BACK_BINDING ) {
LDAP_BACK_CONN_BINDING_SET( mc );
}
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
@ -947,13 +960,15 @@ meta_back_getconn(
/* Retries searching for a metaconn in the avl tree
* the reason is that the connection might have been
* created by meta_back_get_candidate() */
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_conn_cmp );
if ( mc != NULL ) {
mc->mc_refcnt++;
if ( !( sendok & LDAP_BACK_BINDING ) ) {
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_conn_cmp );
if ( mc != NULL ) {
mc->mc_refcnt++;
}
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
}
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
/* Looks like we didn't get a bind. Open a new session... */
if ( mc == NULL ) {
@ -961,6 +976,9 @@ meta_back_getconn(
mc->mc_conn = mc_curr.mc_conn;
ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
new_conn = 1;
if ( sendok & LDAP_BACK_BINDING ) {
LDAP_BACK_CONN_BINDING_SET( mc );
}
}
}
@ -1015,6 +1033,9 @@ meta_back_getconn(
mc->mc_conn = mc_curr.mc_conn;
ber_dupbv( &mc->mc_local_ndn, &mc_curr.mc_local_ndn );
new_conn = 1;
if ( sendok & LDAP_BACK_BINDING ) {
LDAP_BACK_CONN_BINDING_SET( mc );
}
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
@ -1165,6 +1186,7 @@ meta_back_release_conn(
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
assert( mc->mc_refcnt > 0 );
mc->mc_refcnt--;
LDAP_BACK_CONN_BINDING_CLEAR( mc );
if ( mc->mc_refcnt == 0 && mc->mc_tainted ) {
(void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
meta_back_conn_cmp );