Commit 0eacc4a7 authored by Tero Saarni's avatar Tero Saarni Committed by Quanah Gibson-Mount
Browse files

ITS#9197 back-ldap: added task that prunes expired connections

parent b57d317f
...@@ -180,7 +180,7 @@ typedef struct ldapconn_t { ...@@ -180,7 +180,7 @@ typedef struct ldapconn_t {
typedef struct ldap_avl_info_t { typedef struct ldap_avl_info_t {
ldap_pvt_thread_mutex_t lai_mutex; ldap_pvt_thread_mutex_t lai_mutex;
Avlnode *lai_tree; TAvlnode *lai_tree;
} ldap_avl_info_t; } ldap_avl_info_t;
typedef struct slap_retry_info_t { typedef struct slap_retry_info_t {
...@@ -417,6 +417,7 @@ typedef struct ldapinfo_t { ...@@ -417,6 +417,7 @@ typedef struct ldapinfo_t {
ldap_pvt_thread_mutex_t li_counter_mutex; ldap_pvt_thread_mutex_t li_counter_mutex;
ldap_pvt_mp_t li_ops_completed[SLAP_OP_LAST]; ldap_pvt_mp_t li_ops_completed[SLAP_OP_LAST];
struct re_s* li_conn_expire_task;
} ldapinfo_t; } ldapinfo_t;
#define LDAP_ERR_OK(err) ((err) == LDAP_SUCCESS || (err) == LDAP_COMPARE_FALSE || (err) == LDAP_COMPARE_TRUE) #define LDAP_ERR_OK(err) ((err) == LDAP_SUCCESS || (err) == LDAP_COMPARE_FALSE || (err) == LDAP_COMPARE_TRUE)
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "back-ldap.h" #include "back-ldap.h"
#include "lutil.h" #include "lutil.h"
#include "lutil_ldap.h" #include "lutil_ldap.h"
#include "ldap_rq.h"
#define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ "2.16.840.1.113730.3.4.12" #define LDAP_CONTROL_OBSOLETE_PROXY_AUTHZ "2.16.840.1.113730.3.4.12"
...@@ -60,7 +61,7 @@ static const struct { ...@@ -60,7 +61,7 @@ static const struct {
}; };
static void static void
ldap_back_conn_print( ldapconn_t *lc, const char *avlstr ) ldap_back_conn_print( ldapconn_t *lc )
{ {
char buf[ SLAP_TEXT_BUFLEN ]; char buf[ SLAP_TEXT_BUFLEN ];
char fbuf[ sizeof("BAPTIENSC") ]; char fbuf[ sizeof("BAPTIENSC") ];
...@@ -77,31 +78,10 @@ ldap_back_conn_print( ldapconn_t *lc, const char *avlstr ) ...@@ -77,31 +78,10 @@ ldap_back_conn_print( ldapconn_t *lc, const char *avlstr )
} }
fbuf[i] = '\0'; fbuf[i] = '\0';
fprintf( stderr, "lc=%p %s %s flags=0x%08x (%s)\n", fprintf( stderr, "lc=%p %s flags=0x%08x (%s)\n",
(void *)lc, buf, avlstr, lc->lc_lcflags, fbuf ); (void *)lc, buf, lc->lc_lcflags, fbuf );
} }
static void
ldap_back_ravl_print( Avlnode *root, int depth )
{
int i;
ldapconn_t *lc;
if ( root == 0 ) {
return;
}
ldap_back_ravl_print( root->avl_right, depth+1 );
for ( i = 0; i < depth; i++ ) {
fprintf( stderr, "-" );
}
lc = root->avl_data;
ldap_back_conn_print( lc, avl_bf2str( root->avl_bf ) );
ldap_back_ravl_print( root->avl_left, depth + 1 );
}
static char* priv2str[] = { static char* priv2str[] = {
"privileged", "privileged",
...@@ -129,7 +109,7 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg ) ...@@ -129,7 +109,7 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg )
LDAP_TAILQ_FOREACH( lc, &li->li_conn_priv[ c ].lic_priv, lc_q ) LDAP_TAILQ_FOREACH( lc, &li->li_conn_priv[ c ].lic_priv, lc_q )
{ {
fprintf( stderr, " [%d] ", i ); fprintf( stderr, " [%d] ", i );
ldap_back_conn_print( lc, "" ); ldap_back_conn_print( lc );
i++; i++;
} }
} }
...@@ -138,7 +118,11 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg ) ...@@ -138,7 +118,11 @@ ldap_back_print_conntree( ldapinfo_t *li, char *msg )
fprintf( stderr, "\t(empty)\n" ); fprintf( stderr, "\t(empty)\n" );
} else { } else {
ldap_back_ravl_print( li->li_conninfo.lai_tree, 0 ); TAvlnode *edge = tavl_end( li->li_conninfo.lai_tree, TAVL_DIR_LEFT );
while ( edge ) {
ldap_back_conn_print( (ldapconn_t *)edge->avl_data );
edge = tavl_next( edge, TAVL_DIR_RIGHT );
}
} }
fprintf( stderr, "<======== %s\n", msg ); fprintf( stderr, "<======== %s\n", msg );
...@@ -167,6 +151,12 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs, ...@@ -167,6 +151,12 @@ ldap_back_prepare_conn( ldapconn_t *lc, Operation *op, SlapReply *rs,
static int static int
ldap_back_conndnlc_cmp( const void *c1, const void *c2 ); ldap_back_conndnlc_cmp( const void *c1, const void *c2 );
static void
ldap_back_conn_prune( ldapinfo_t *li );
static void
ldap_back_schedule_conn_expiry( ldapinfo_t *li, ldapconn_t *lc );
ldapconn_t * ldapconn_t *
ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc ) ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc )
{ {
...@@ -189,7 +179,7 @@ ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc ) ...@@ -189,7 +179,7 @@ ldap_back_conn_delete( ldapinfo_t *li, ldapconn_t *lc )
if ( LDAP_BACK_CONN_CACHED( lc ) ) { if ( LDAP_BACK_CONN_CACHED( lc ) ) {
assert( !LDAP_BACK_CONN_TAINTED( lc ) ); assert( !LDAP_BACK_CONN_TAINTED( lc ) );
tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, tmplc = tavl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conndnlc_cmp ); ldap_back_conndnlc_cmp );
assert( tmplc == lc ); assert( tmplc == lc );
LDAP_BACK_CONN_CACHED_CLEAR( lc ); LDAP_BACK_CONN_CACHED_CLEAR( lc );
...@@ -343,7 +333,7 @@ retry_lock:; ...@@ -343,7 +333,7 @@ retry_lock:;
/* delete all cached connections with the current connection */ /* delete all cached connections with the current connection */
if ( LDAP_BACK_SINGLECONN( li ) ) { if ( LDAP_BACK_SINGLECONN( li ) ) {
while ( ( tmplc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ) ) != NULL ) while ( ( tmplc = tavl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc, ldap_back_conn_cmp ) ) != NULL )
{ {
assert( !LDAP_BACK_PCONN_ISPRIV( lc ) ); assert( !LDAP_BACK_PCONN_ISPRIV( lc ) );
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
...@@ -371,7 +361,7 @@ retry_lock:; ...@@ -371,7 +361,7 @@ retry_lock:;
if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) { if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) ) {
LDAP_BACK_PCONN_ROOTDN_SET( lc, op ); LDAP_BACK_PCONN_ROOTDN_SET( lc, op );
} }
lerr = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, lerr = tavl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conndn_cmp, ldap_back_conndn_dup ); ldap_back_conndn_cmp, ldap_back_conndn_dup );
} }
...@@ -934,7 +924,7 @@ retry_lock: ...@@ -934,7 +924,7 @@ retry_lock:
} else { } else {
/* Searches for a ldapconn in the avl tree */ /* Searches for a ldapconn in the avl tree */
lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree, lc = (ldapconn_t *)tavl_find( li->li_conninfo.lai_tree,
(caddr_t)&lc_curr, ldap_back_conndn_cmp ); (caddr_t)&lc_curr, ldap_back_conndn_cmp );
} }
...@@ -1080,7 +1070,7 @@ retry_lock: ...@@ -1080,7 +1070,7 @@ retry_lock:
rs->sr_err = 0; rs->sr_err = 0;
} else { } else {
rs->sr_err = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc, rs->sr_err = tavl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conndn_cmp, ldap_back_conndn_dup ); ldap_back_conndn_cmp, ldap_back_conndn_dup );
LDAP_BACK_CONN_CACHED_SET( lc ); LDAP_BACK_CONN_CACHED_SET( lc );
} }
...@@ -1126,6 +1116,7 @@ retry_lock: ...@@ -1126,6 +1116,7 @@ retry_lock:
return NULL; return NULL;
} }
} }
ldap_back_schedule_conn_expiry( li, lc );
} else { } else {
int expiring = 0; int expiring = 0;
...@@ -3054,3 +3045,156 @@ ldap_back_connid2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen ) ...@@ -3054,3 +3045,156 @@ ldap_back_connid2str( const ldapconn_base_t *lc, char *buf, ber_len_t buflen )
return len; return len;
} }
void *
ldap_back_conn_expire_fn( void *ctx, void *arg )
{
struct re_s *rtask = arg;
ldapinfo_t *li = (ldapinfo_t *)rtask->arg;
ldap_back_conn_prune( li );
return NULL;
}
/* Pick which expires first: connection TTL or idle timeout */
static time_t
ldap_back_conn_expire_time( ldapinfo_t *li, ldapconn_t *lc) {
if ( li->li_conn_ttl != 0 && li->li_idle_timeout != 0 ) {
return ( lc->lc_create_time + li->li_conn_ttl ) < ( lc->lc_time + li->li_idle_timeout ) ?
( lc->lc_create_time + li->li_conn_ttl ) : ( lc->lc_time + li->li_idle_timeout );
} else if ( li->li_conn_ttl != 0 ) {
return lc->lc_create_time + li->li_conn_ttl;
} else if ( li->li_idle_timeout != 0 ) {
return lc->lc_time + li->li_idle_timeout;
}
return -1;
}
static void
ldap_back_conn_prune( ldapinfo_t *li )
{
time_t now = slap_get_time();
time_t next_timeout = -1; /* -1 means uninitialized */
TAvlnode *edge;
int c;
/*
* Iterate though connections and close those that are pass the expiry time.
* Also calculate the time for next connection to to expire.
*/
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
for ( c = LDAP_BACK_PCONN_FIRST; c < LDAP_BACK_PCONN_LAST; c++ ) {
ldapconn_t *lc = LDAP_TAILQ_FIRST( &li->li_conn_priv[ c ].lic_priv );
while ( lc ) {
ldapconn_t *next = LDAP_TAILQ_NEXT( lc, lc_q );
time_t conn_expires = ldap_back_conn_expire_time( li, lc );
if ( now >= conn_expires ) {
if ( lc->lc_refcnt == 0 ) {
Debug( LDAP_DEBUG_TRACE,
"ldap_back_conn_prune: closing expired connection lc=%p\n",
lc );
ldap_back_freeconn( li, lc, 0 );
} else {
Debug( LDAP_DEBUG_TRACE,
"ldap_back_conn_prune: tainting expired connection lc=%p\n",
lc );
LDAP_BACK_CONN_TAINTED_SET( lc );
}
} else if ( next_timeout == -1 || conn_expires < next_timeout ) {
/* next_timeout was not yet initialized or current connection expires sooner */
next_timeout = conn_expires;
}
lc = next;
}
}
edge = tavl_end( li->li_conninfo.lai_tree, TAVL_DIR_LEFT );
while ( edge ) {
TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT );
ldapconn_t *lc = (ldapconn_t *)edge->avl_data;
time_t conn_expires = ldap_back_conn_expire_time( li, lc );
if ( now >= conn_expires ) {
if ( lc->lc_refcnt == 0 ) {
Debug( LDAP_DEBUG_TRACE,
"ldap_back_conn_prune: closing expired connection lc=%p\n",
lc );
ldap_back_freeconn( li, lc, 0 );
} else {
Debug( LDAP_DEBUG_TRACE,
"ldap_back_conn_prune: tainting expired connection lc=%p\n",
lc );
LDAP_BACK_CONN_TAINTED_SET( lc );
}
} else if ( next_timeout == -1 || conn_expires < next_timeout ) {
next_timeout = conn_expires;
}
edge = next;
}
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
/* Reschedule for next timeout or cancel the task */
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
if ( next_timeout > 0 ) {
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, li->li_conn_expire_task ) ) {
ldap_pvt_runqueue_stoptask( &slapd_rq, li->li_conn_expire_task );
}
li->li_conn_expire_task->interval.tv_sec = next_timeout - now;
ldap_pvt_runqueue_resched( &slapd_rq, li->li_conn_expire_task, 0 );
/*
* The thread that handles runqueue might have already processed all tasks
* before we insertered new task or rescheduled the existing task with new
* timeout period. Wake it up to ensure that the task will be picked up.
*/
slap_wake_listener();
Debug( LDAP_DEBUG_TRACE,
"ldap_back_conn_prune: scheduled connection expiry timer to %ld sec\n",
li->li_conn_expire_task->interval.tv_sec );
} else if ( next_timeout == -1 && li->li_conn_expire_task != NULL ) {
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, li->li_conn_expire_task ) ) {
ldap_pvt_runqueue_stoptask( &slapd_rq, li->li_conn_expire_task );
}
ldap_pvt_runqueue_remove( &slapd_rq, li->li_conn_expire_task );
li->li_conn_expire_task = NULL;
}
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
return;
}
static void
ldap_back_schedule_conn_expiry( ldapinfo_t *li, ldapconn_t *lc ) {
/* Do nothing if timeouts are not set. */
if ( li->li_conn_ttl == 0 && li->li_idle_timeout == 0 ) {
return;
}
/*
* If connection expire task is not running, create it and schedule for
* timeout of this connection.
*
* If the task is already running, this connection cannot be next one
* to expire and therefore timeout does not need to be re-calculated.
*/
ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
if ( li->li_conn_expire_task == NULL ) {
li->li_conn_expire_task = ldap_pvt_runqueue_insert( &slapd_rq,
ldap_back_conn_expire_time( li, lc ) - slap_get_time(),
ldap_back_conn_expire_fn, li, "ldap_back_conn_expire_fn",
"ldap_back_conn_expire_timer" );
slap_wake_listener();
Debug( LDAP_DEBUG_TRACE,
"ldap_back_conn_prune: scheduled connection expiry timer to %ld sec\n",
li->li_conn_expire_task->interval.tv_sec );
}
ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
return;
}
\ No newline at end of file
...@@ -558,7 +558,7 @@ Document: RFC 4511 ...@@ -558,7 +558,7 @@ Document: RFC 4511
/* Searches for a ldapinfo in the avl tree */ /* Searches for a ldapinfo in the avl tree */
ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, lip = (ldapinfo_t *)tavl_find( lc->lc_lai.lai_tree,
(caddr_t)&li, ldap_chain_uri_cmp ); (caddr_t)&li, ldap_chain_uri_cmp );
ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
...@@ -590,7 +590,7 @@ Document: RFC 4511 ...@@ -590,7 +590,7 @@ Document: RFC 4511
if ( LDAP_CHAIN_CACHE_URI( lc ) ) { if ( LDAP_CHAIN_CACHE_URI( lc ) ) {
ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
if ( avl_insert( &lc->lc_lai.lai_tree, if ( tavl_insert( &lc->lc_lai.lai_tree,
(caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) (caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
{ {
/* someone just inserted another; /* someone just inserted another;
...@@ -830,7 +830,7 @@ ldap_chain_search( ...@@ -830,7 +830,7 @@ ldap_chain_search(
/* Searches for a ldapinfo in the avl tree */ /* Searches for a ldapinfo in the avl tree */
ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
lip = (ldapinfo_t *)avl_find( lc->lc_lai.lai_tree, lip = (ldapinfo_t *)tavl_find( lc->lc_lai.lai_tree,
(caddr_t)&li, ldap_chain_uri_cmp ); (caddr_t)&li, ldap_chain_uri_cmp );
ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex ); ldap_pvt_thread_mutex_unlock( &lc->lc_lai.lai_mutex );
...@@ -863,7 +863,7 @@ ldap_chain_search( ...@@ -863,7 +863,7 @@ ldap_chain_search(
if ( LDAP_CHAIN_CACHE_URI( lc ) ) { if ( LDAP_CHAIN_CACHE_URI( lc ) ) {
ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex ); ldap_pvt_thread_mutex_lock( &lc->lc_lai.lai_mutex );
if ( avl_insert( &lc->lc_lai.lai_tree, if ( tavl_insert( &lc->lc_lai.lai_tree,
(caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) (caddr_t)lip, ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
{ {
/* someone just inserted another; /* someone just inserted another;
...@@ -1387,7 +1387,7 @@ fail: ...@@ -1387,7 +1387,7 @@ fail:
li->li_uri = ch_strdup( at->a_vals[ 0 ].bv_val ); li->li_uri = ch_strdup( at->a_vals[ 0 ].bv_val );
value_add_one( &li->li_bvuri, &at->a_vals[ 0 ] ); value_add_one( &li->li_bvuri, &at->a_vals[ 0 ] );
if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li, if ( tavl_insert( &lc->lc_lai.lai_tree, (caddr_t)li,
ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
{ {
Debug( LDAP_DEBUG_ANY, "slapd-chain: " Debug( LDAP_DEBUG_ANY, "slapd-chain: "
...@@ -1410,34 +1410,27 @@ done:; ...@@ -1410,34 +1410,27 @@ done:;
return rc; return rc;
} }
typedef struct ldap_chain_cfadd_apply_t { static void
Operation *op; ldap_chain_cfadd_apply(
SlapReply *rs; ldapinfo_t *li,
Entry *p; Operation *op,
ConfigArgs *ca; SlapReply *rs,
int count; Entry *p,
} ldap_chain_cfadd_apply_t; ConfigArgs *ca,
int count )
static int
ldap_chain_cfadd_apply( void *datum, void *arg )
{ {
ldapinfo_t *li = (ldapinfo_t *)datum;
ldap_chain_cfadd_apply_t *lca = (ldap_chain_cfadd_apply_t *)arg;
struct berval bv; struct berval bv;
/* FIXME: should not hardcode "olcDatabase" here */ /* FIXME: should not hardcode "olcDatabase" here */
bv.bv_len = snprintf( lca->ca->cr_msg, sizeof( lca->ca->cr_msg ), bv.bv_len = snprintf( ca->cr_msg, sizeof( ca->cr_msg ),
"olcDatabase={%d}%s", lca->count, lback->bi_type ); "olcDatabase={%d}%s", count, lback->bi_type );
bv.bv_val = lca->ca->cr_msg; bv.bv_val = ca->cr_msg;
lca->ca->be->be_private = (void *)li; ca->be->be_private = (void *)li;
config_build_entry( lca->op, lca->rs, lca->p->e_private, lca->ca, config_build_entry( op, rs, p->e_private, ca,
&bv, lback->bi_cf_ocs, &chainocs[1] ); &bv, lback->bi_cf_ocs, &chainocs[1] );
lca->count++; return;
return 0;
} }
static int static int
...@@ -1447,20 +1440,20 @@ chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca ) ...@@ -1447,20 +1440,20 @@ chain_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
slap_overinst *on = (slap_overinst *)pe->ce_bi; slap_overinst *on = (slap_overinst *)pe->ce_bi;
ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private; ldap_chain_t *lc = (ldap_chain_t *)on->on_bi.bi_private;
void *priv = (void *)ca->be->be_private; void *priv = (void *)ca->be->be_private;
TAvlnode *edge;
int count = 0;
if ( lback->bi_cf_ocs ) { if ( lback->bi_cf_ocs ) {
ldap_chain_cfadd_apply_t lca = { 0 };
lca.op = op;
lca.rs = rs;
lca.p = p;
lca.ca = ca;
lca.count = 0;
(void)ldap_chain_cfadd_apply( (void *)lc->lc_common_li, (void *)&lca ); ldap_chain_cfadd_apply( lc->lc_common_li, op, rs, p, ca, count++ );
(void)avl_apply( lc->lc_lai.lai_tree, ldap_chain_cfadd_apply, edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT );
&lca, 1, AVL_INORDER ); while ( edge ) {
TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT );
ldapinfo_t *li = (ldapinfo_t *)edge->avl_data;
ldap_chain_cfadd_apply( li, op, rs, p, ca, count++ );
edge = next;
}
ca->be->be_private = priv; ca->be->be_private = priv;
} }
...@@ -1480,7 +1473,7 @@ chain_lddel( CfEntryInfo *ce, Operation *op ) ...@@ -1480,7 +1473,7 @@ chain_lddel( CfEntryInfo *ce, Operation *op )
ldapinfo_t *li = (ldapinfo_t *) ce->ce_be->be_private; ldapinfo_t *li = (ldapinfo_t *) ce->ce_be->be_private;
if ( li != lc->lc_common_li ) { if ( li != lc->lc_common_li ) {
if (! avl_delete( &lc->lc_lai.lai_tree, li, ldap_chain_uri_cmp ) ) { if (! tavl_delete( &lc->lc_lai.lai_tree, li, ldap_chain_uri_cmp ) ) {
Debug( LDAP_DEBUG_ANY, "slapd-chain: avl_delete failed. " Debug( LDAP_DEBUG_ANY, "slapd-chain: avl_delete failed. "
"\"%s\" not found.\n", li->li_uri ); "\"%s\" not found.\n", li->li_uri );
return -1; return -1;
...@@ -1889,7 +1882,7 @@ private_destroy:; ...@@ -1889,7 +1882,7 @@ private_destroy:;
goto private_destroy; goto private_destroy;
} }
if ( avl_insert( &lc->lc_lai.lai_tree, if ( tavl_insert( &lc->lc_lai.lai_tree,
(caddr_t)lc->lc_cfg_li, (caddr_t)lc->lc_cfg_li,
ldap_chain_uri_cmp, ldap_chain_uri_dup ) ) ldap_chain_uri_cmp, ldap_chain_uri_dup ) )
{ {
...@@ -1914,22 +1907,6 @@ enum db_which { ...@@ -1914,22 +1907,6 @@ enum db_which {
db_last db_last
}; };
typedef struct ldap_chain_db_apply_t {
BackendDB *be;
BI_db_func *func;
} ldap_chain_db_apply_t;
static int
ldap_chain_db_apply( void *datum, void *arg )
{
ldapinfo_t *li = (ldapinfo_t *)datum;
ldap_chain_db_apply_t *lca = (ldap_chain_db_apply_t *)arg;
lca->be->be_private = (void *)li;
return lca->func( lca->be, NULL );
}
static int static int
ldap_chain_db_func( ldap_chain_db_func(
BackendDB *be, BackendDB *be,
...@@ -1957,14 +1934,17 @@ ldap_chain_db_func( ...@@ -1957,14 +1934,17 @@ ldap_chain_db_func(
} }
if ( lc->lc_lai.lai_tree != NULL ) { if ( lc->lc_lai.lai_tree != NULL ) {
ldap_chain_db_apply_t lca; TAvlnode *edge = tavl_end( lc->lc_lai.lai_tree, TAVL_DIR_LEFT );
while ( edge ) {
lca.be = &db; TAvlnode *next = tavl_next( edge, TAVL_DIR_RIGHT );
lca.func = func; ldapinfo_t *li = (ldapinfo_t *)edge->avl_data;