From 46cb141185d5a04c43d3707baff0df0b8358f50b Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 1 Apr 2006 18:56:39 +0000 Subject: [PATCH] seems to fix the equivalent of ITS#4429 in back-meta; had to give up per-target conn-ttl and idle-timeout --- servers/slapd/back-meta/add.c | 7 +- servers/slapd/back-meta/back-meta.h | 29 ++--- servers/slapd/back-meta/bind.c | 22 ++-- servers/slapd/back-meta/config.c | 12 +- servers/slapd/back-meta/conn.c | 185 ++++++++++++++++------------ servers/slapd/back-meta/delete.c | 7 +- servers/slapd/back-meta/init.c | 1 - servers/slapd/back-meta/modify.c | 20 +-- servers/slapd/back-meta/modrdn.c | 20 +-- servers/slapd/back-meta/search.c | 12 +- 10 files changed, 174 insertions(+), 141 deletions(-) diff --git a/servers/slapd/back-meta/add.c b/servers/slapd/back-meta/add.c index 0d32ac7eb9..2b08958374 100644 --- a/servers/slapd/back-meta/add.c +++ b/servers/slapd/back-meta/add.c @@ -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; } diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index 2cf8369c7c..78bc791c3c 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -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 ); diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c index 9f5c0962da..1ec7217ab5 100644 --- a/servers/slapd/back-meta/bind.c +++ b/servers/slapd/back-meta/bind.c @@ -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 ); diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index cf26945dfe..4e5997a64c 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -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 ) { diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c index 1bb5fedc48..9f6313eef3 100644 --- a/servers/slapd/back-meta/conn.c +++ b/servers/slapd/back-meta/conn.c @@ -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 ); } diff --git a/servers/slapd/back-meta/delete.c b/servers/slapd/back-meta/delete.c index aaeaa3837c..d9461ac4e4 100644 --- a/servers/slapd/back-meta/delete.c +++ b/servers/slapd/back-meta/delete.c @@ -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; } diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index 3697f41fd0..a4962515d3 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -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 ); } diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index 20f04e28c2..c17af5e928 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -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; } diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index 6536cab579..a490553b64 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -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; } diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 729db9cd73..00cd89f1f4 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -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; } -- 2.39.5