mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-24 13:24:56 +08:00
seems to fix the equivalent of ITS#4429 in back-meta; had to give up per-target conn-ttl and idle-timeout
This commit is contained in:
parent
d9afc113c5
commit
46cb141185
@ -170,9 +170,10 @@ retry:;
|
||||
attrs, op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
goto cleanup;
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
@ -234,7 +235,9 @@ cleanup:;
|
||||
}
|
||||
|
||||
done:;
|
||||
meta_back_release_conn( op, mc );
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
@ -174,17 +174,15 @@ typedef struct metasingleconn_t {
|
||||
#define META_ANONYMOUS 2
|
||||
#endif
|
||||
|
||||
time_t msc_create_time;
|
||||
time_t msc_time;
|
||||
|
||||
struct metainfo_t *msc_info;
|
||||
} metasingleconn_t;
|
||||
|
||||
typedef struct metaconn_t {
|
||||
struct slap_conn *mc_conn;
|
||||
ldap_pvt_thread_mutex_t mc_mutex;
|
||||
unsigned mc_refcnt;
|
||||
int mc_tainted;
|
||||
|
||||
time_t mc_create_time;
|
||||
time_t mc_time;
|
||||
|
||||
struct berval mc_local_ndn;
|
||||
/* NOTE: msc_mscflags is used to recycle the #define
|
||||
@ -230,8 +228,6 @@ typedef struct metatarget_t {
|
||||
unsigned mt_flags;
|
||||
int mt_version;
|
||||
time_t mt_network_timeout;
|
||||
time_t mt_conn_ttl;
|
||||
time_t mt_idle_timeout;
|
||||
struct timeval mt_bind_timeout;
|
||||
#define META_BIND_TIMEOUT LDAP_BACK_RESULT_UTIMEOUT
|
||||
time_t mt_timeout[ LDAP_BACK_OP_LAST ];
|
||||
@ -300,20 +296,19 @@ meta_back_getconn(
|
||||
ldap_back_send_t sendok );
|
||||
|
||||
extern void
|
||||
meta_back_release_conn(
|
||||
meta_back_release_conn_lock(
|
||||
Operation *op,
|
||||
metaconn_t *mc );
|
||||
metaconn_t *mc,
|
||||
int dolock );
|
||||
#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 1 )
|
||||
|
||||
extern int
|
||||
meta_back_retry_lock(
|
||||
meta_back_retry(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
metaconn_t *mc,
|
||||
metaconn_t **mcp,
|
||||
int candidate,
|
||||
ldap_back_send_t sendok,
|
||||
int dolock );
|
||||
#define meta_back_retry(op, rs, mc, candidate, sendok) \
|
||||
meta_back_retry_lock((op), (rs), (mc), (candidate), (sendok), 1)
|
||||
ldap_back_send_t sendok );
|
||||
|
||||
extern void
|
||||
meta_back_conn_free(
|
||||
@ -372,12 +367,12 @@ meta_back_conn_cmp(
|
||||
const void *c2 );
|
||||
|
||||
extern int
|
||||
meta_back_dnconn_cmp(
|
||||
meta_back_conndn_cmp(
|
||||
const void *c1,
|
||||
const void *c2 );
|
||||
|
||||
extern int
|
||||
meta_back_dnconn_dup(
|
||||
meta_back_conndn_dup(
|
||||
void *c1,
|
||||
void *c2 );
|
||||
|
||||
|
@ -192,6 +192,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
||||
}
|
||||
|
||||
if ( !dn_match( &op->o_req_ndn, &mc->mc_local_ndn ) ) {
|
||||
metaconn_t *tmpmc;
|
||||
int lerr;
|
||||
|
||||
/* wait for all other ops to release the connection */
|
||||
@ -204,13 +205,13 @@ retry_lock:;
|
||||
}
|
||||
|
||||
assert( mc->mc_refcnt == 1 );
|
||||
mc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
|
||||
meta_back_dnconn_cmp );
|
||||
assert( mc != NULL );
|
||||
tmpmc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
|
||||
meta_back_conndn_cmp );
|
||||
assert( tmpmc == mc );
|
||||
|
||||
ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
|
||||
lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
|
||||
meta_back_dnconn_cmp, meta_back_dnconn_dup );
|
||||
meta_back_conndn_cmp, meta_back_conndn_dup );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
if ( lerr == -1 ) {
|
||||
for ( i = 0; i < mi->mi_ntargets; ++i ) {
|
||||
@ -383,7 +384,7 @@ retry:;
|
||||
|
||||
rc = slap_map_api2result( rs );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
|
||||
rc = meta_back_retry( op, rs, mc, candidate, LDAP_BACK_DONTSEND );
|
||||
rc = meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_DONTSEND );
|
||||
if ( rc ) {
|
||||
if ( nretries > 0 ) {
|
||||
nretries--;
|
||||
@ -391,6 +392,7 @@ retry:;
|
||||
ldap_pvt_thread_yield();
|
||||
goto rebind;
|
||||
}
|
||||
goto return_results;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -539,9 +541,6 @@ retry:;
|
||||
|
||||
rc = slap_map_api2result( rs );
|
||||
if ( rc == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
|
||||
/* NOTE: we do not use meta_back_retry() here
|
||||
* to avoid circular loops; mc_mutex is set
|
||||
* by the caller */
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
@ -628,8 +627,6 @@ meta_back_dobind(
|
||||
LDAP_BACK_PCONN_ID( mc->mc_conn ),
|
||||
isroot ? " (isroot)" : "" );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
|
||||
|
||||
/*
|
||||
* all the targets are bound as pseudoroot
|
||||
*/
|
||||
@ -686,9 +683,10 @@ retry:;
|
||||
|
||||
if ( rc == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry_lock( op, rs, mc, i, LDAP_BACK_DONTSEND, 0 ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
|
||||
goto retry;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf( buf, sizeof( buf ),
|
||||
@ -729,8 +727,6 @@ retry:;
|
||||
}
|
||||
|
||||
done:;
|
||||
ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"%s meta_back_dobind: conn=%ld bound=%d\n",
|
||||
op->o_log_prefix, LDAP_BACK_PCONN_ID( mc->mc_conn ), bound );
|
||||
|
@ -158,8 +158,6 @@ meta_back_db_config(
|
||||
mi->mi_targets[ i ].mt_flags = mi->mi_flags;
|
||||
mi->mi_targets[ i ].mt_version = mi->mi_version;
|
||||
mi->mi_targets[ i ].mt_network_timeout = mi->mi_network_timeout;
|
||||
mi->mi_targets[ i ].mt_conn_ttl = mi->mi_conn_ttl;
|
||||
mi->mi_targets[ i ].mt_idle_timeout = mi->mi_idle_timeout;
|
||||
mi->mi_targets[ i ].mt_bind_timeout = mi->mi_bind_timeout;
|
||||
for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
|
||||
mi->mi_targets[ i ].mt_timeout[ c ] = mi->mi_timeout[ c ];
|
||||
@ -448,9 +446,6 @@ meta_back_db_config(
|
||||
/* idle timeout when connecting to ldap servers */
|
||||
} else if ( strcasecmp( argv[ 0 ], "idle-timeout" ) == 0 ) {
|
||||
unsigned long t;
|
||||
time_t *tp = mi->mi_ntargets ?
|
||||
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_idle_timeout
|
||||
: &mi->mi_idle_timeout;
|
||||
|
||||
switch ( argc ) {
|
||||
case 1:
|
||||
@ -475,14 +470,11 @@ meta_back_db_config(
|
||||
|
||||
}
|
||||
|
||||
*tp = (time_t)t;
|
||||
mi->mi_idle_timeout = (time_t)t;
|
||||
|
||||
/* conn ttl */
|
||||
} else if ( strcasecmp( argv[ 0 ], "conn-ttl" ) == 0 ) {
|
||||
unsigned long t;
|
||||
time_t *tp = mi->mi_ntargets ?
|
||||
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_conn_ttl
|
||||
: &mi->mi_conn_ttl;
|
||||
|
||||
switch ( argc ) {
|
||||
case 1:
|
||||
@ -507,7 +499,7 @@ meta_back_db_config(
|
||||
|
||||
}
|
||||
|
||||
*tp = (time_t)t;
|
||||
mi->mi_conn_ttl = (time_t)t;
|
||||
|
||||
/* bind timeout when connecting to ldap servers */
|
||||
} else if ( strcasecmp( argv[ 0 ], "bind-timeout" ) == 0 ) {
|
||||
|
@ -40,13 +40,13 @@
|
||||
#define PRINT_CONNTREE 0
|
||||
|
||||
/*
|
||||
* meta_back_dnconn_cmp
|
||||
* meta_back_conndn_cmp
|
||||
*
|
||||
* compares two struct metaconn based on the value of the conn pointer
|
||||
* and of the local DN; used by avl stuff
|
||||
*/
|
||||
int
|
||||
meta_back_dnconn_cmp(
|
||||
meta_back_conndn_cmp(
|
||||
const void *c1,
|
||||
const void *c2 )
|
||||
{
|
||||
@ -66,6 +66,36 @@ meta_back_dnconn_cmp(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* meta_back_conndnmc_cmp
|
||||
*
|
||||
* compares two struct metaconn based on the value of the conn pointer,
|
||||
* the local DN and the struct pointer; used by avl stuff
|
||||
*/
|
||||
static int
|
||||
meta_back_conndnmc_cmp(
|
||||
const void *c1,
|
||||
const void *c2 )
|
||||
{
|
||||
metaconn_t *mc1 = ( metaconn_t * )c1;
|
||||
metaconn_t *mc2 = ( metaconn_t * )c2;
|
||||
int rc;
|
||||
|
||||
/* If local DNs don't match, it is definitely not a match */
|
||||
/* For shared sessions, conn is NULL. Only explicitly
|
||||
* bound sessions will have non-NULL conn.
|
||||
*/
|
||||
rc = SLAP_PTRCMP( mc1->mc_conn, mc2->mc_conn );
|
||||
if ( rc == 0 ) {
|
||||
rc = ber_bvcmp( &mc1->mc_local_ndn, &mc2->mc_local_ndn );
|
||||
if ( rc == 0 ) {
|
||||
rc = SLAP_PTRCMP( mc1, mc2 );
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* meta_back_conn_cmp
|
||||
*
|
||||
@ -87,13 +117,13 @@ meta_back_conn_cmp(
|
||||
}
|
||||
|
||||
/*
|
||||
* meta_back_dnconn_dup
|
||||
* meta_back_conndn_dup
|
||||
*
|
||||
* returns -1 in case a duplicate struct metaconn has been inserted;
|
||||
* used by avl stuff
|
||||
*/
|
||||
int
|
||||
meta_back_dnconn_dup(
|
||||
meta_back_conndn_dup(
|
||||
void *c1,
|
||||
void *c2 )
|
||||
{
|
||||
@ -190,9 +220,7 @@ metaconn_alloc(
|
||||
BER_BVZERO( &mc->mc_local_ndn );
|
||||
mc->msc_mscflags = 0;
|
||||
mc->mc_authz_target = META_BOUND_NONE;
|
||||
ldap_pvt_thread_mutex_init( &mc->mc_mutex );
|
||||
mc->mc_refcnt = 1;
|
||||
mc->mc_tainted = 0;
|
||||
|
||||
return mc;
|
||||
}
|
||||
@ -240,28 +268,7 @@ meta_back_init_one_conn(
|
||||
* Already init'ed
|
||||
*/
|
||||
if ( msc->msc_ld != NULL ) {
|
||||
int doreturn = 1;
|
||||
|
||||
if ( ( mt->mt_idle_timeout != 0 && op->o_time > msc->msc_time + mt->mt_idle_timeout )
|
||||
|| ( mt->mt_conn_ttl != 0 && op->o_time > msc->msc_create_time + mt->mt_conn_ttl ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"%s meta_back_init_one_conn[%d]: idle timeout/ttl.\n",
|
||||
op->o_log_prefix, candidate, 0 );
|
||||
if ( meta_back_retry( op, rs, mc, candidate, sendok ) ) {
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
doreturn = 0;
|
||||
}
|
||||
|
||||
if ( mt->mt_idle_timeout != 0 ) {
|
||||
msc->msc_time = op->o_time;
|
||||
}
|
||||
|
||||
if ( doreturn ) {
|
||||
return rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
return rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -455,14 +462,6 @@ error_return:;
|
||||
*/
|
||||
( void )rewrite_session_init( mt->mt_rwmap.rwm_rw, op->o_conn );
|
||||
|
||||
if ( mt->mt_idle_timeout ) {
|
||||
msc->msc_time = op->o_time;
|
||||
}
|
||||
|
||||
if ( mt->mt_conn_ttl ) {
|
||||
msc->msc_create_time = op->o_time;
|
||||
}
|
||||
|
||||
} else {
|
||||
rs->sr_err = slap_map_api2result( rs );
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
@ -475,38 +474,30 @@ error_return:;
|
||||
}
|
||||
|
||||
/*
|
||||
* meta_back_retry_lock
|
||||
* meta_back_retry
|
||||
*
|
||||
* Retries one connection
|
||||
*/
|
||||
int
|
||||
meta_back_retry_lock(
|
||||
meta_back_retry(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
metaconn_t *mc,
|
||||
metaconn_t **mcp,
|
||||
int candidate,
|
||||
ldap_back_send_t sendok,
|
||||
int dolock )
|
||||
ldap_back_send_t sendok )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt = &mi->mi_targets[ candidate ];
|
||||
int rc = LDAP_UNAVAILABLE;
|
||||
metaconn_t *mc = *mcp;
|
||||
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
|
||||
|
||||
retry_lock:;
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
assert( mc->mc_refcnt > 0 );
|
||||
|
||||
if ( mc->mc_refcnt == 1 ) {
|
||||
char buf[ SLAP_TEXT_BUFLEN ];
|
||||
|
||||
while ( dolock && ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_lock;
|
||||
}
|
||||
|
||||
snprintf( buf, sizeof( buf ),
|
||||
"retrying URI=\"%s\" DN=\"%s\"",
|
||||
mt->mt_uri,
|
||||
@ -544,13 +535,15 @@ retry_lock:;
|
||||
}
|
||||
}
|
||||
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
*mcp = NULL;
|
||||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
mc->mc_tainted = 1;
|
||||
if ( sendok ) {
|
||||
rs->sr_err = LDAP_UNAVAILABLE;
|
||||
rs->sr_text = "unable to retry";
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
@ -778,8 +771,11 @@ meta_back_getconn(
|
||||
|
||||
|
||||
meta_op_type op_type = META_OP_REQUIRE_SINGLE;
|
||||
int parent = 0,
|
||||
newparent = 0;
|
||||
enum {
|
||||
META_DNTYPE_ENTRY,
|
||||
META_DNTYPE_PARENT,
|
||||
META_DNTYPE_NEWPARENT
|
||||
} dn_type = META_DNTYPE_ENTRY;
|
||||
struct berval ndn = op->o_req_ndn,
|
||||
pndn;
|
||||
|
||||
@ -810,21 +806,26 @@ meta_back_getconn(
|
||||
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_dnconn_cmp );
|
||||
(caddr_t)&mc_curr, meta_back_conndn_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;
|
||||
if ( ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
|
||||
|| ( mi->mi_idle_timeout != 0 && op->o_time > mc->mc_time + mi->mi_idle_timeout ) )
|
||||
{
|
||||
/* don't let anyone else use this expired connection */
|
||||
(void)avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
(caddr_t)mc, meta_back_conndnmc_cmp );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "%s meta_back_getconn: mc=%p conn=%ld expired.\n",
|
||||
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc->mc_conn ) );
|
||||
}
|
||||
|
||||
|
||||
/* 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 );
|
||||
@ -834,7 +835,7 @@ retry_lock:
|
||||
case LDAP_REQ_ADD:
|
||||
/* if we go to selection, the entry must not exist,
|
||||
* and we must be able to resolve the parent */
|
||||
parent = 1;
|
||||
dn_type = META_DNTYPE_PARENT;
|
||||
dnParent( &ndn, &pndn );
|
||||
break;
|
||||
|
||||
@ -842,7 +843,7 @@ retry_lock:
|
||||
/* if nnewSuperior is not NULL, it must resolve
|
||||
* to the same candidate as the req_ndn */
|
||||
if ( op->orr_nnewSup ) {
|
||||
newparent = 1;
|
||||
dn_type = META_DNTYPE_NEWPARENT;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -963,7 +964,7 @@ retry_lock:
|
||||
if ( i == META_TARGET_NONE ) {
|
||||
i = meta_back_get_candidate( op, rs, &ndn );
|
||||
|
||||
if ( rs->sr_err == LDAP_NO_SUCH_OBJECT && parent ) {
|
||||
if ( rs->sr_err == LDAP_NO_SUCH_OBJECT && dn_type == META_DNTYPE_PARENT ) {
|
||||
i = meta_back_get_candidate( op, rs, &pndn );
|
||||
}
|
||||
|
||||
@ -985,7 +986,7 @@ retry_lock:
|
||||
}
|
||||
}
|
||||
|
||||
if ( newparent && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
|
||||
if ( dn_type == META_DNTYPE_NEWPARENT && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
|
||||
{
|
||||
if ( mc != NULL ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
@ -1010,10 +1011,18 @@ retry_lock:
|
||||
* the reason is that the connection might have been
|
||||
* created by meta_back_get_candidate() */
|
||||
if ( !( sendok & LDAP_BACK_BINDING ) ) {
|
||||
retry_lock2:;
|
||||
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_dnconn_cmp );
|
||||
(caddr_t)&mc_curr, meta_back_conndn_cmp );
|
||||
if ( mc != NULL ) {
|
||||
/* 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_lock2;
|
||||
}
|
||||
|
||||
mc->mc_refcnt++;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
@ -1172,14 +1181,23 @@ done:;
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
rs->sr_text = NULL;
|
||||
|
||||
/* touch the timestamp */
|
||||
if ( mi->mi_idle_timeout != 0 ) {
|
||||
mc->mc_time = op->o_time;
|
||||
}
|
||||
|
||||
if ( new_conn ) {
|
||||
|
||||
if ( mi->mi_conn_ttl ) {
|
||||
mc->mc_create_time = op->o_time;
|
||||
}
|
||||
|
||||
/*
|
||||
* Inserts the newly created metaconn in the avl tree
|
||||
*/
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
|
||||
meta_back_dnconn_cmp, meta_back_dnconn_dup );
|
||||
meta_back_conndn_cmp, meta_back_conndn_dup );
|
||||
|
||||
#if PRINT_CONNTREE > 0
|
||||
myprint( mi->mi_conninfo.lai_tree );
|
||||
@ -1225,22 +1243,33 @@ done:;
|
||||
}
|
||||
|
||||
void
|
||||
meta_back_release_conn(
|
||||
meta_back_release_conn_lock(
|
||||
Operation *op,
|
||||
metaconn_t *mc )
|
||||
metaconn_t *mc,
|
||||
int dolock )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
|
||||
assert( mc != NULL );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
if ( dolock ) {
|
||||
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_dnconn_cmp );
|
||||
meta_back_conn_free( mc );
|
||||
if ( ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
|
||||
|| ( mi->mi_idle_timeout != 0 && op->o_time > mc->mc_time + mi->mi_idle_timeout ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld expired.\n",
|
||||
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc->mc_conn ) );
|
||||
(void)avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
( caddr_t )mc, meta_back_conndnmc_cmp );
|
||||
if ( mc->mc_refcnt == 0 ) {
|
||||
meta_back_conn_free( mc );
|
||||
}
|
||||
}
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
@ -68,9 +68,10 @@ retry:;
|
||||
mdn.bv_val, op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
goto cleanup;
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
@ -128,7 +129,9 @@ cleanup:;
|
||||
}
|
||||
|
||||
done:;
|
||||
meta_back_release_conn( op, mc );
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
@ -164,7 +164,6 @@ meta_back_conn_free(
|
||||
(void)meta_clear_one_candidate( &mc->mc_conns[ i ] );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_destroy( &mc->mc_mutex );
|
||||
free( mc );
|
||||
}
|
||||
|
||||
|
@ -179,9 +179,10 @@ retry:;
|
||||
modv, op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
goto done;
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
@ -226,6 +227,14 @@ retry:;
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
if ( maperr ) {
|
||||
rc = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
|
||||
done:;
|
||||
if ( mdn.bv_val != op->o_req_dn.bv_val ) {
|
||||
free( mdn.bv_val );
|
||||
BER_BVZERO( &mdn );
|
||||
@ -238,15 +247,10 @@ cleanup:;
|
||||
free( mods );
|
||||
free( modv );
|
||||
|
||||
if ( maperr ) {
|
||||
rc = meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
}
|
||||
|
||||
meta_back_release_conn( op, mc );
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -111,9 +111,10 @@ retry:;
|
||||
op->o_ctrls, NULL, &msgid );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
|
||||
do_retry = 0;
|
||||
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
goto retry;
|
||||
}
|
||||
goto done;
|
||||
|
||||
} else if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
struct timeval tv, *tvp = NULL;
|
||||
@ -157,6 +158,14 @@ retry:;
|
||||
}
|
||||
|
||||
cleanup:;
|
||||
if ( maperr ) {
|
||||
meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
|
||||
done:;
|
||||
if ( mdn.bv_val != op->o_req_dn.bv_val ) {
|
||||
free( mdn.bv_val );
|
||||
BER_BVZERO( &mdn );
|
||||
@ -169,15 +178,10 @@ cleanup:;
|
||||
BER_BVZERO( &mnewSuperior );
|
||||
}
|
||||
|
||||
if ( maperr ) {
|
||||
meta_back_op_result( mc, op, rs, candidate );
|
||||
|
||||
} else {
|
||||
send_ldap_result( op, rs );
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
}
|
||||
|
||||
meta_back_release_conn( op, mc );
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -416,7 +416,7 @@ really_bad:;
|
||||
if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
|
||||
candidates[ i ].sr_type = REP_RESULT;
|
||||
|
||||
if ( meta_back_retry( op, rs, mc, i, LDAP_BACK_DONTSEND ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, i, LDAP_BACK_DONTSEND ) ) {
|
||||
switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) )
|
||||
{
|
||||
case META_SEARCH_CANDIDATE:
|
||||
@ -427,6 +427,12 @@ really_bad:;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
savepriv = op->o_private;
|
||||
op->o_private = (void *)i;
|
||||
send_ldap_result( op, rs );
|
||||
op->o_private = savepriv;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -888,7 +894,9 @@ finish:;
|
||||
}
|
||||
}
|
||||
|
||||
meta_back_release_conn( op, mc );
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( op, mc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user