mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-06-09 08:42:22 -04:00
ITS#10363 - Implement a target connection time-to-live in asyncmeta
This commit is contained in:
parent
d1848e54ae
commit
add3df9da4
14 changed files with 776 additions and 24 deletions
|
|
@ -268,6 +268,47 @@ irrespective of the client's request. See
|
|||
.B slapd\-meta(5)
|
||||
for details.
|
||||
|
||||
.TP
|
||||
.B conn\-ttl <time> [<interval>]
|
||||
This directive causes a persistent connection to be dropped after
|
||||
it has been established for the specified
|
||||
.I time,
|
||||
no more often that one connection per
|
||||
.I interval
|
||||
per target. The connection will be re-created the next time it is selected for use.
|
||||
If there are pending requests in its queue, the connection will be
|
||||
marked as closing and no new requests will be proxied through it.
|
||||
It will be dropped after the last request one has either received a result or has timed out.
|
||||
To avoid too many connections being dropped at the same time, the \fBinterval\fP
|
||||
directive is introduced, to specify the minimum time interval between resetting a connection
|
||||
to the same target.
|
||||
The default value is 1 second. If
|
||||
.I time
|
||||
is set to 0, the oldest connection will be chosen for reset at every interval period. If
|
||||
.I interval
|
||||
is set to 0, all connections exceeding their ttl will be dropped as soon as there are no more
|
||||
pending operations.
|
||||
|
||||
[<d>d][<h>h][<m>m][<s>[s]]
|
||||
|
||||
where <d>, <h>, <m> and <s> are respectively treated as days, hours,
|
||||
minutes and seconds.
|
||||
|
||||
.B EXAMPLES
|
||||
|
||||
.B conn\-ttl 60s 5s
|
||||
- Connections older that 60 seconds will be reset, no more often that one connection per
|
||||
target every 5 seconds.
|
||||
|
||||
.B conn\-ttl 0 5s
|
||||
- Every 5 seconds, the oldest connection of each target will be reset.
|
||||
|
||||
.B conn\-ttl 1h
|
||||
- Connection older than 1h will be reset, no more often than once a second per target.
|
||||
|
||||
If set before any target specification, it affects all targets, unless
|
||||
overridden by any per-target directive. It is disabled by default.
|
||||
|
||||
.TP
|
||||
.B default\-target [<target>]
|
||||
The "default\-target" directive can also be used during target specification.
|
||||
|
|
@ -331,7 +372,7 @@ for details.
|
|||
|
||||
.TP
|
||||
.B idle\-timeout <time>
|
||||
This directive causes a a persistent connection to be dropped after
|
||||
This directive causes a persistent connection to be dropped after
|
||||
it has been idle for the specified time. The connection will be re-created
|
||||
the next time it is selected for use. A connection is considered idle if no
|
||||
attempts have been made by the backend to use it to send a request to
|
||||
|
|
|
|||
|
|
@ -63,7 +63,11 @@ LDAP_BEGIN_DECL
|
|||
|
||||
#define META_BACK_FCONN_INITED (0x00100000U)
|
||||
#define META_BACK_FCONN_CREATING (0x00200000U)
|
||||
/* connection is invalid, do not read or send, close as soon as possible */
|
||||
#define META_BACK_FCONN_INVALID (0x00400000U)
|
||||
/* connection is closing, do not send, but keep open for reading, reset
|
||||
when no more data is expected */
|
||||
#define META_BACK_FCONN_CLOSING (0x00800000U)
|
||||
|
||||
#define META_BACK_CONN_INITED(lc) LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_INITED)
|
||||
#define META_BACK_CONN_INITED_SET(lc) LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_INITED)
|
||||
|
|
@ -76,6 +80,10 @@ LDAP_BEGIN_DECL
|
|||
#define META_BACK_CONN_INVALID(lc) LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_INVALID)
|
||||
#define META_BACK_CONN_INVALID_SET(lc) LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_INVALID)
|
||||
#define META_BACK_CONN_INVALID_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_INVALID)
|
||||
#define META_BACK_CONN_CLOSING(lc) LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_CLOSING)
|
||||
#define META_BACK_CONN_CLOSING_SET(lc) LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_CLOSING)
|
||||
#define META_BACK_CONN_CLOSING_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_CLOSING)
|
||||
|
||||
|
||||
struct a_metainfo_t;
|
||||
struct a_metaconn_t;
|
||||
|
|
@ -129,14 +137,17 @@ typedef struct a_metasingleconn_t {
|
|||
time_t msc_time;
|
||||
time_t msc_binding_time;
|
||||
time_t msc_result_time;
|
||||
time_t msc_reset_time;
|
||||
time_t msc_established_time;
|
||||
struct berval msc_bound_ndn;
|
||||
struct berval msc_cred;
|
||||
unsigned msc_mscflags;
|
||||
|
||||
int msc_pending_ops;
|
||||
/* NOTE: lc_lcflags is redefined to msc_mscflags to reuse the macros
|
||||
* defined for back-ldap */
|
||||
#define lc_lcflags msc_mscflags
|
||||
volatile int msc_active;
|
||||
struct a_metaconn_t *mc;
|
||||
/* Connection for the select */
|
||||
Connection *conn;
|
||||
} a_metasingleconn_t;
|
||||
|
|
@ -240,6 +251,8 @@ typedef struct a_metacommon_t {
|
|||
slap_retry_info_t mc_quarantine;
|
||||
time_t mc_network_timeout;
|
||||
struct timeval mc_bind_timeout;
|
||||
time_t mc_conn_ttl;
|
||||
time_t mc_conn_reset_interval;
|
||||
#define META_BIND_TIMEOUT LDAP_BACK_RESULT_UTIMEOUT
|
||||
time_t mc_timeout[ SLAP_OP_LAST ];
|
||||
} a_metacommon_t;
|
||||
|
|
@ -299,6 +312,8 @@ typedef struct a_metatarget_t {
|
|||
#define mt_bind_timeout mt_mc.mc_bind_timeout
|
||||
#define mt_timeout mt_mc.mc_timeout
|
||||
#define mt_quarantine mt_mc.mc_quarantine
|
||||
#define mt_conn_ttl mt_mc.mc_conn_ttl
|
||||
#define mt_conn_reset_interval mt_mc.mc_conn_reset_interval
|
||||
|
||||
#define META_BACK_TGT_ISSET(mt,f) ( ( (mt)->mt_flags & (f) ) == (f) )
|
||||
#define META_BACK_TGT_ISMASK(mt,m,f) ( ( (mt)->mt_flags & (m) ) == (f) )
|
||||
|
|
@ -337,6 +352,8 @@ typedef struct a_metatarget_t {
|
|||
#define META_BACK_CFG_MAX_TIMEOUT_LOOP 0x70000
|
||||
slap_mask_t mt_rep_flags;
|
||||
int mt_timeout_ops;
|
||||
/* last time a connection for this target was reset */
|
||||
time_t msc_reset_time;
|
||||
} a_metatarget_t;
|
||||
|
||||
typedef struct a_metadncache_t {
|
||||
|
|
@ -382,7 +399,8 @@ typedef struct a_metainfo_t {
|
|||
#define mi_bind_timeout mi_mc.mc_bind_timeout
|
||||
#define mi_timeout mi_mc.mc_timeout
|
||||
#define mi_quarantine mi_mc.mc_quarantine
|
||||
|
||||
#define mi_conn_ttl mi_mc.mc_conn_ttl
|
||||
#define mi_conn_reset_interval mi_mc.mc_conn_reset_interval
|
||||
a_metatarget_t **mi_targets;
|
||||
a_metacandidates_t *mi_candidates;
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ enum {
|
|||
LDAP_BACK_CFG_CANCEL,
|
||||
LDAP_BACK_CFG_CHASE,
|
||||
LDAP_BACK_CFG_CLIENT_PR,
|
||||
LDAP_BACK_CFG_CONN_TTL,
|
||||
LDAP_BACK_CFG_DEFAULT_T,
|
||||
LDAP_BACK_CFG_NETWORK_TIMEOUT,
|
||||
LDAP_BACK_CFG_NOREFS,
|
||||
|
|
@ -171,6 +172,15 @@ static ConfigTable a_metacfg[] = {
|
|||
"SYNTAX OMsDirectoryString "
|
||||
"SINGLE-VALUE )",
|
||||
NULL, NULL },
|
||||
{ "conn-ttl", "ttl", 2, 3, 0,
|
||||
ARG_MAGIC|LDAP_BACK_CFG_CONN_TTL,
|
||||
asyncmeta_back_cf_gen, "( OLcfgDbAt:3.16 "
|
||||
"NAME 'olcDbConnTtl' "
|
||||
"DESC 'connection ttl' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SYNTAX OMsDirectoryString "
|
||||
"SINGLE-VALUE )",
|
||||
NULL, NULL },
|
||||
{ "network-timeout", "timeout", 2, 2, 0,
|
||||
ARG_MAGIC|LDAP_BACK_CFG_NETWORK_TIMEOUT,
|
||||
asyncmeta_back_cf_gen, "( OLcfgDbAt:3.17 "
|
||||
|
|
@ -412,7 +422,8 @@ static ConfigTable a_metacfg[] = {
|
|||
"$ olcDbRebindAsUser " \
|
||||
ST_ATTR \
|
||||
"$ olcDbStartTLS " \
|
||||
"$ olcDbTFSupport "
|
||||
"$ olcDbTFSupport " \
|
||||
"$ olcDbConnTtl "
|
||||
|
||||
static ConfigOCs a_metaocs[] = {
|
||||
{ "( OLcfgDbOc:3.4 "
|
||||
|
|
@ -518,6 +529,7 @@ asyncmeta_back_new_target(
|
|||
a_metaconn_t *mc = &mi->mi_conns[i];
|
||||
mc->mc_conns = ch_realloc( mc->mc_conns, sizeof( a_metasingleconn_t ) * mi->mi_ntargets);
|
||||
memset( &(mc->mc_conns[mi->mi_ntargets-1]), 0, sizeof( a_metasingleconn_t ) );
|
||||
mc->mc_conns[mi->mi_ntargets-1].mc = mc;
|
||||
}
|
||||
/* If this is the first target, start the timeout loop */
|
||||
if ( mi->mi_ntargets == 1 ) {
|
||||
|
|
@ -1149,7 +1161,22 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
|
|||
value_add_one( &c->rvalue_vals, &bv );
|
||||
break;
|
||||
#endif /* SLAPD_META_CLIENT_PR */
|
||||
|
||||
case LDAP_BACK_CFG_CONN_TTL:
|
||||
if ( mc->mc_conn_ttl == 0 && mc->mc_conn_reset_interval == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
char buf[ SLAP_TEXT_BUFLEN ];
|
||||
char *p = buf;
|
||||
lutil_unparse_time( p, sizeof( p ), mc->mc_conn_ttl );
|
||||
if (mc->mc_conn_reset_interval != 0) {
|
||||
p += strlen( buf );
|
||||
*p = ' ';
|
||||
lutil_unparse_time( p, sizeof( p ), mc->mc_conn_reset_interval );
|
||||
}
|
||||
ber_str2bv( buf, 0, 0, &bv );
|
||||
value_add_one( &c->rvalue_vals, &bv );
|
||||
}
|
||||
break;
|
||||
case LDAP_BACK_CFG_DEFAULT_T:
|
||||
if ( mt || mi->mi_defaulttarget == META_DEFAULT_TARGET_NONE )
|
||||
return 1;
|
||||
|
|
@ -1598,7 +1625,10 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
|
|||
mc->mc_ps = META_CLIENT_PR_DISABLE;
|
||||
break;
|
||||
#endif /* SLAPD_META_CLIENT_PR */
|
||||
|
||||
case LDAP_BACK_CFG_CONN_TTL:
|
||||
mc->mc_conn_ttl = 0;
|
||||
mc->mc_conn_reset_interval = 0;
|
||||
break;
|
||||
case LDAP_BACK_CFG_DEFAULT_T:
|
||||
mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
|
||||
break;
|
||||
|
|
@ -2390,7 +2420,28 @@ asyncmeta_back_cf_gen( ConfigArgs *c )
|
|||
}
|
||||
}
|
||||
break;
|
||||
case LDAP_BACK_CFG_CONN_TTL: {
|
||||
unsigned long t;
|
||||
|
||||
if ( lutil_parse_time( c->argv[ 1 ], &t ) ) {
|
||||
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||
"unable to parse conn ttl \"%s\"",
|
||||
c->argv[ 1 ] );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
|
||||
return 1;
|
||||
|
||||
}
|
||||
mc->mc_conn_ttl = (time_t)t;
|
||||
if ( ( c->argv[ 2 ] != NULL ) && lutil_parse_time( c->argv[ 2 ], &t ) ) {
|
||||
snprintf( c->cr_msg, sizeof( c->cr_msg ),
|
||||
"unable to parse conn ttl reset interval \"%s\"",
|
||||
c->argv[ 2 ] );
|
||||
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
|
||||
return 1;
|
||||
|
||||
}
|
||||
mc->mc_conn_reset_interval = (time_t)t;
|
||||
} break;
|
||||
case LDAP_BACK_CFG_IDASSERT_BIND:
|
||||
/* idassert-bind */
|
||||
rc = mi->mi_ldap_extra->idassert_parse( c, &mt->mt_idassert );
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ asyncmeta_conn_alloc(
|
|||
{
|
||||
a_metaconn_t *mc;
|
||||
int ntargets = mi->mi_ntargets;
|
||||
|
||||
int j;
|
||||
assert( ntargets > 0 );
|
||||
|
||||
/* malloc all in one */
|
||||
|
|
@ -56,6 +56,10 @@ asyncmeta_conn_alloc(
|
|||
ldap_pvt_thread_mutex_init( &mc->mc_om_mutex);
|
||||
mc->mc_authz_target = META_BOUND_NONE;
|
||||
mc->mc_conns = (a_metasingleconn_t *)(mc+1);
|
||||
|
||||
for (j = 0; j < mi->mi_ntargets; j++) {
|
||||
mc->mc_conns[j].mc = mc;
|
||||
}
|
||||
return mc;
|
||||
}
|
||||
|
||||
|
|
@ -120,13 +124,17 @@ asyncmeta_init_one_conn(
|
|||
return rs->sr_err;
|
||||
}
|
||||
}
|
||||
msc = &mc->mc_conns[candidate];
|
||||
/*
|
||||
* Already init'ed
|
||||
*/
|
||||
if ( LDAP_BACK_CONN_ISBOUND( msc )
|
||||
|| LDAP_BACK_CONN_ISANON( msc ) )
|
||||
{
|
||||
msc = &mc->mc_conns[candidate];
|
||||
|
||||
if ( META_BACK_CONN_CLOSING( msc ) ) {
|
||||
rs->sr_err = -1;
|
||||
return rs->sr_err;
|
||||
|
||||
} else if ( LDAP_BACK_CONN_ISBOUND( msc )
|
||||
|| LDAP_BACK_CONN_ISANON( msc ) ) {
|
||||
/*
|
||||
* Already init'ed
|
||||
*/
|
||||
assert( msc->msc_ld != NULL );
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
return rs->sr_err;
|
||||
|
|
@ -176,6 +184,8 @@ asyncmeta_init_one_conn(
|
|||
goto error_return;
|
||||
}
|
||||
|
||||
msc->msc_established_time = slap_get_time();
|
||||
|
||||
/*
|
||||
* Set LDAP version. This will always succeed: If the client
|
||||
* bound with a particular version, then so can we.
|
||||
|
|
@ -506,7 +516,8 @@ asyncmeta_getconn(
|
|||
i = META_TARGET_NONE,
|
||||
err = LDAP_SUCCESS,
|
||||
new_conn = 0,
|
||||
ncandidates = 0;
|
||||
ncandidates = 0,
|
||||
num_conns = mi->mi_num_conns;
|
||||
|
||||
|
||||
meta_op_type op_type = META_OP_REQUIRE_SINGLE;
|
||||
|
|
@ -518,6 +529,11 @@ asyncmeta_getconn(
|
|||
struct berval ndn = op->o_req_ndn,
|
||||
pndn;
|
||||
|
||||
choose_again:
|
||||
/* in case we are sent here because the connection is set to closing */
|
||||
if ( mc != NULL && alloc_new > 0 ) {
|
||||
asyncmeta_back_conn_free( mc );
|
||||
}
|
||||
if (alloc_new > 0) {
|
||||
mc = asyncmeta_conn_alloc(mi);
|
||||
new_conn = 0;
|
||||
|
|
@ -613,6 +629,19 @@ asyncmeta_getconn(
|
|||
candidates[ i ].sr_err = asyncmeta_init_one_conn( op,
|
||||
rs, mc, i, LDAP_BACK_CONN_ISPRIV( &mc_curr ),
|
||||
!new_conn );
|
||||
if ( candidates[ i ].sr_err == -1 ) {
|
||||
if ( num_conns -1 > 0 ) {
|
||||
num_conns--;
|
||||
ldap_pvt_thread_mutex_unlock(&mc->mc_om_mutex);
|
||||
goto choose_again;
|
||||
} else {
|
||||
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
rs->sr_text = "Unable to find a valid connection";
|
||||
ldap_pvt_thread_mutex_unlock(&mc->mc_om_mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
|
||||
if ( new_conn ) {
|
||||
LDAP_BACK_CONN_BINDING_SET( &mc->mc_conns[ i ] );
|
||||
|
|
@ -714,6 +743,18 @@ asyncmeta_getconn(
|
|||
*/
|
||||
err = asyncmeta_init_one_conn( op, rs, mc, i,
|
||||
LDAP_BACK_CONN_ISPRIV( &mc_curr ), !new_conn );
|
||||
if ( err == -1 ) {
|
||||
if ( num_conns-1 > 0 ) {
|
||||
num_conns--;
|
||||
ldap_pvt_thread_mutex_unlock(&mc->mc_om_mutex);
|
||||
goto choose_again;
|
||||
} else {
|
||||
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
rs->sr_text = "Unable to find a valid connection";
|
||||
ldap_pvt_thread_mutex_unlock(&mc->mc_om_mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ( err != LDAP_SUCCESS ) {
|
||||
/*
|
||||
* FIXME: in case one target cannot
|
||||
|
|
@ -764,6 +805,19 @@ asyncmeta_getconn(
|
|||
int lerr = asyncmeta_init_one_conn( op, rs, mc, i,
|
||||
LDAP_BACK_CONN_ISPRIV( &mc_curr ),
|
||||
!new_conn );
|
||||
/* the chosen connection is closing */
|
||||
if ( lerr == -1 ) {
|
||||
if ( num_conns-1 > 0 ) {
|
||||
num_conns--;
|
||||
ldap_pvt_thread_mutex_unlock(&mc->mc_om_mutex);
|
||||
goto choose_again;
|
||||
} else {
|
||||
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
|
||||
rs->sr_text = "Unable to find a valid connection";
|
||||
ldap_pvt_thread_mutex_unlock(&mc->mc_om_mutex);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
candidates[ i ].sr_err = lerr;
|
||||
if ( lerr == LDAP_SUCCESS ) {
|
||||
META_CANDIDATE_SET( &candidates[ i ] );
|
||||
|
|
@ -1055,6 +1109,10 @@ asyncmeta_clear_one_msc(
|
|||
msc->msc_time = 0;
|
||||
msc->msc_binding_time = 0;
|
||||
msc->msc_result_time = 0;
|
||||
msc->msc_established_time = 0;
|
||||
msc->msc_reset_time = slap_get_time();
|
||||
if ( mt )
|
||||
mt->msc_reset_time = msc->msc_reset_time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -231,6 +231,7 @@ asyncmeta_target_finish(
|
|||
mi->mi_flags &= ~META_BACK_F_PROXYAUTHZ_NOANON;
|
||||
}
|
||||
|
||||
mt->msc_reset_time = slap_get_time();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -241,7 +242,7 @@ asyncmeta_back_db_open(
|
|||
{
|
||||
a_metainfo_t *mi = (a_metainfo_t *)be->be_private;
|
||||
char msg[SLAP_TEXT_BUFLEN];
|
||||
int i;
|
||||
int i,j;
|
||||
|
||||
mi->mi_disabled = 0;
|
||||
if ( mi->mi_ntargets == 0 ) {
|
||||
|
|
@ -270,6 +271,9 @@ asyncmeta_back_db_open(
|
|||
|
||||
if ( mi->mi_ntargets > 0 ) {
|
||||
mc->mc_conns = ch_calloc( mi->mi_ntargets, sizeof( a_metasingleconn_t ));
|
||||
for (j = 0; j < mi->mi_ntargets; j++) {
|
||||
mc->mc_conns[j].mc = mc;
|
||||
}
|
||||
} else {
|
||||
mc->mc_conns = NULL;
|
||||
}
|
||||
|
|
@ -277,7 +281,6 @@ asyncmeta_back_db_open(
|
|||
mc->mc_info = mi;
|
||||
LDAP_STAILQ_INIT( &mc->mc_om_list );
|
||||
}
|
||||
|
||||
|
||||
ber_dupbv ( &mi->mi_suffix, &be->be_suffix[0] );
|
||||
|
||||
|
|
|
|||
|
|
@ -1656,15 +1656,44 @@ void asyncmeta_set_msc_time(a_metasingleconn_t *msc)
|
|||
msc->msc_time = slap_get_time();
|
||||
}
|
||||
|
||||
static void
|
||||
asyncmeta_update_msc_pending_ops( a_metaconn_t *mc,
|
||||
bm_context_t *bc)
|
||||
{
|
||||
int i;
|
||||
a_metainfo_t *mi = mc->mc_info;
|
||||
for (i=0; i<mi->mi_ntargets; i++) {
|
||||
if ( !META_IS_CANDIDATE( &bc->candidates[ i ] ) ||
|
||||
bc->candidates[i].sr_msgid == META_MSGID_IGNORE ||
|
||||
bc->candidates[i].sr_type == REP_RESULT) {
|
||||
continue;
|
||||
}
|
||||
mc->mc_conns[i].msc_pending_ops++;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
asyncmeta_reset_msc_pending_ops( a_metaconn_t *mc )
|
||||
{
|
||||
int i;
|
||||
a_metainfo_t *mi = mc->mc_info;
|
||||
for (i=0; i<mi->mi_ntargets; i++) {
|
||||
mc->mc_conns[i].msc_pending_ops = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void* asyncmeta_timeout_loop(void *ctx, void *arg)
|
||||
{
|
||||
struct re_s* rtask = arg;
|
||||
a_metainfo_t *mi = rtask->arg;
|
||||
bm_context_t *bc, *onext;
|
||||
time_t current_time = slap_get_time();
|
||||
time_t conn_ttl;
|
||||
time_t conn_reset_interval;
|
||||
int i, j;
|
||||
LDAP_STAILQ_HEAD(BCList, bm_context_t) timeout_list;
|
||||
LDAP_STAILQ_INIT( &timeout_list );
|
||||
a_metasingleconn_t* oldest[mi->mi_ntargets];
|
||||
|
||||
Debug( asyncmeta_debug, "asyncmeta_timeout_loop[%p] start at [%ld] \n", rtask, current_time );
|
||||
if ( mi->mi_disabled > 0 && asyncmeta_db_has_pending_ops( mi ) == 0 ) {
|
||||
|
|
@ -1676,12 +1705,18 @@ void* asyncmeta_timeout_loop(void *ctx, void *arg)
|
|||
return NULL;
|
||||
}
|
||||
void *oldctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx, 0);
|
||||
|
||||
for (i=0; i<mi->mi_ntargets; i++ ) {
|
||||
oldest[i] = NULL;
|
||||
}
|
||||
for (i=0; i<mi->mi_num_conns; i++) {
|
||||
a_metaconn_t * mc= &mi->mi_conns[i];
|
||||
ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
|
||||
asyncmeta_reset_msc_pending_ops(mc);
|
||||
for (bc = LDAP_STAILQ_FIRST(&mc->mc_om_list); bc; bc = onext) {
|
||||
onext = LDAP_STAILQ_NEXT(bc, bc_next);
|
||||
if (bc->bc_active > 0) {
|
||||
asyncmeta_update_msc_pending_ops( mc, bc);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1703,7 +1738,8 @@ void* asyncmeta_timeout_loop(void *ctx, void *arg)
|
|||
for (j=0; j<mi->mi_ntargets; j++) {
|
||||
if (bc->candidates[j].sr_msgid >= 0) {
|
||||
a_metasingleconn_t *msc = &mc->mc_conns[j];
|
||||
if ( op->o_tag == LDAP_REQ_SEARCH ) {
|
||||
if ( op->o_tag == LDAP_REQ_SEARCH &&
|
||||
!META_BACK_CONN_CLOSING(msc) ) {
|
||||
msc->msc_active++;
|
||||
asyncmeta_back_cancel( mc, op,
|
||||
bc->candidates[ j ].sr_msgid, j );
|
||||
|
|
@ -1730,7 +1766,8 @@ void* asyncmeta_timeout_loop(void *ctx, void *arg)
|
|||
if (bc->candidates[j].sr_msgid >= 0) {
|
||||
a_metasingleconn_t *msc = &mc->mc_conns[j];
|
||||
asyncmeta_set_msc_time(msc);
|
||||
if ( op->o_tag == LDAP_REQ_SEARCH ) {
|
||||
if ( op->o_tag == LDAP_REQ_SEARCH &&
|
||||
!META_BACK_CONN_CLOSING(msc) ) {
|
||||
msc->msc_active++;
|
||||
asyncmeta_back_cancel( mc, op,
|
||||
bc->candidates[ j ].sr_msgid, j );
|
||||
|
|
@ -1739,7 +1776,17 @@ void* asyncmeta_timeout_loop(void *ctx, void *arg)
|
|||
}
|
||||
}
|
||||
}
|
||||
asyncmeta_update_msc_pending_ops( mc, bc);
|
||||
}
|
||||
for (j=0; j<mi->mi_ntargets; j++) {
|
||||
a_metasingleconn_t *msc = &mc->mc_conns[j];
|
||||
if ( META_BACK_CONN_CLOSING(msc) &&
|
||||
msc->msc_pending_ops == 0 &&
|
||||
msc->msc_active <= 0 ) {
|
||||
asyncmeta_clear_one_msc (mi->mi_targets[j], msc, __FUNCTION__ );
|
||||
}
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
|
||||
|
||||
for (bc = LDAP_STAILQ_FIRST(&timeout_list); bc; bc = onext) {
|
||||
|
|
@ -1827,9 +1874,36 @@ void* asyncmeta_timeout_loop(void *ctx, void *arg)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* find the oldest connection to reset */
|
||||
for (j=0; j<mi->mi_ntargets; j++) {
|
||||
a_metasingleconn_t *msc = &mc->mc_conns[j];
|
||||
if ( msc->msc_established_time > 0 &&
|
||||
( oldest[j] == NULL || oldest[j]->msc_established_time > msc->msc_established_time ) ) {
|
||||
oldest[j] = msc;
|
||||
}
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
|
||||
}
|
||||
|
||||
current_time = slap_get_time();
|
||||
for (j=0; j<mi->mi_ntargets; j++) {
|
||||
a_metasingleconn_t *msc = oldest[j];
|
||||
a_metatarget_t *mt = mi->mi_targets[j];
|
||||
conn_ttl = (mt->mt_conn_ttl > 0)?mt->mt_conn_ttl:mi->mi_conn_ttl;
|
||||
conn_reset_interval = (mt->mt_conn_reset_interval > 0) ?
|
||||
mt->mt_conn_reset_interval:mi->mi_conn_reset_interval;
|
||||
|
||||
if ( conn_ttl || conn_reset_interval ) {
|
||||
if ( (current_time - mt->msc_reset_time) <= conn_reset_interval )
|
||||
continue;
|
||||
if ( msc != NULL && msc->msc_established_time
|
||||
&& (msc->msc_established_time + conn_ttl <= current_time) ) {
|
||||
ldap_pvt_thread_mutex_lock( &msc->mc->mc_om_mutex );
|
||||
META_BACK_CONN_CLOSING_SET( msc );
|
||||
ldap_pvt_thread_mutex_unlock( &msc->mc->mc_om_mutex );
|
||||
}
|
||||
}
|
||||
}
|
||||
slap_sl_mem_setctx(ctx, oldctx);
|
||||
current_time = slap_get_time();
|
||||
Debug( asyncmeta_debug, "asyncmeta_timeout_loop[%p] stop at [%ld] \n", rtask, current_time );
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ static AttributeDescription *ad_olmDbNextConnectionGroup; /*mi_next_conn*/
|
|||
/* Target Attributes */
|
||||
static AttributeDescription *ad_olmTgtURIList; /* mt_uri */
|
||||
static AttributeDescription *ad_olmTgtQuarantined; /*mt_isquarantined*/
|
||||
static AttributeDescription *ad_olmTgtConnLastReset; /*msc_reset_time*/
|
||||
static AttributeDescription *ad_olmTgtTimeoutOps; /*mt_timeout_ops*/
|
||||
/* Connection Group (a_metaconn_t) attributes */
|
||||
static AttributeDescription *ad_olmCGID;
|
||||
|
|
@ -55,6 +56,8 @@ static AttributeDescription *ad_olmCGPendingOps;
|
|||
static AttributeDescription *ad_olmTargetConnLastUseTime; /* msc_time */
|
||||
static AttributeDescription *ad_olmTargetConnBoundTime; /* msc_binding_time */
|
||||
static AttributeDescription *ad_olmTargetConnResultTime; /* msc_result_time */
|
||||
static AttributeDescription *ad_olmTargetConnEstablishedTime; /* msc_established_time */
|
||||
static AttributeDescription *ad_olmTargetConnResetTime; /* msc_reset_time */
|
||||
static AttributeDescription *ad_olmTargetConnFlags; /* msc_mscflags */
|
||||
static AttributeDescription *ad_olmTargetConnURI;
|
||||
static AttributeDescription *ad_olmTargetConnPeerAddress;
|
||||
|
|
@ -77,6 +80,7 @@ static struct {
|
|||
{ META_BACK_FCONN_INITED, BER_BVC( "initialized" ) },
|
||||
{ META_BACK_FCONN_CREATING, BER_BVC( "creating" ) },
|
||||
{ META_BACK_FCONN_INVALID, BER_BVC( "invalid" ) },
|
||||
{ META_BACK_FCONN_CLOSING, BER_BVC( "closing" ) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
|
@ -204,6 +208,33 @@ static struct {
|
|||
"NO-USER-MODIFICATION "
|
||||
"USAGE dSAOperation )",
|
||||
&ad_olmTargetConnPeerAddress },
|
||||
{ "( olmAsyncmetaAttributes:13 "
|
||||
"NAME ( 'olmTargetConnEstablishedTime' ) "
|
||||
"DESC 'Time the connection was established' "
|
||||
"EQUALITY integerMatch "
|
||||
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
|
||||
"SINGLE-VALUE "
|
||||
"NO-USER-MODIFICATION "
|
||||
"USAGE dSAOperation )",
|
||||
&ad_olmTargetConnEstablishedTime },
|
||||
{ "( olmAsyncmetaAttributes:14 "
|
||||
"NAME ( 'olmTargetConnResetTime' ) "
|
||||
"DESC 'Last time the connection was reset' "
|
||||
"EQUALITY integerMatch "
|
||||
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
|
||||
"SINGLE-VALUE "
|
||||
"NO-USER-MODIFICATION "
|
||||
"USAGE dSAOperation )",
|
||||
&ad_olmTargetConnResetTime },
|
||||
{ "( olmAsyncmetaAttributes:15 "
|
||||
"NAME ( 'olmTgtConnLastReset' ) "
|
||||
"DESC 'Last time a connection to this target was reset' "
|
||||
"EQUALITY integerMatch "
|
||||
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 "
|
||||
"SINGLE-VALUE "
|
||||
"NO-USER-MODIFICATION "
|
||||
"USAGE dSAOperation )",
|
||||
&ad_olmTgtConnLastReset },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
@ -235,6 +266,7 @@ static struct {
|
|||
"MAY ( "
|
||||
"olmTgtURIList "
|
||||
"$ olmTgtQuarantined "
|
||||
"$ olmTgtConnLastReset "
|
||||
"$ olmTgtTimeoutOps "
|
||||
") )",
|
||||
&oc_olmAsyncmetaTarget },
|
||||
|
|
@ -253,9 +285,11 @@ static struct {
|
|||
"olmTargetConnLastUseTime "
|
||||
"$ olmTargetConnBoundTime "
|
||||
"$ olmTargetConnResultTime "
|
||||
"$ olmTargetConnFlags "
|
||||
"$ olmTargetConnURI "
|
||||
"$ olmTargetConnPeerAddress"
|
||||
"$ olmTargetConnResetTime "
|
||||
"$ olmTargetConnEstablishedTime "
|
||||
"$ olmTargetConnFlags "
|
||||
"$ olmTargetConnURI "
|
||||
"$ olmTargetConnPeerAddress"
|
||||
") )",
|
||||
&oc_olmAsyncmetaTargetConnection },
|
||||
|
||||
|
|
@ -431,6 +465,18 @@ asyncmeta_back_monitor_target_conn_update(
|
|||
bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", msc->msc_result_time );
|
||||
ber_bvreplace( &a->a_vals[ 0 ], &bv );
|
||||
|
||||
a = attr_find( e->e_attrs, ad_olmTargetConnResetTime );
|
||||
assert( a != NULL );
|
||||
bv.bv_val = buf;
|
||||
bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", msc->msc_reset_time );
|
||||
ber_bvreplace( &a->a_vals[ 0 ], &bv );
|
||||
|
||||
a = attr_find( e->e_attrs, ad_olmTargetConnEstablishedTime );
|
||||
assert( a != NULL );
|
||||
bv.bv_val = buf;
|
||||
bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", msc->msc_established_time );
|
||||
ber_bvreplace( &a->a_vals[ 0 ], &bv );
|
||||
|
||||
a = attr_find( e->e_attrs, ad_olmTargetConnFlags );
|
||||
assert( a != NULL );
|
||||
bv.bv_val = buf;
|
||||
|
|
@ -531,7 +577,7 @@ asyncmeta_back_monitor_target_conn_init(
|
|||
cb->mc_free = asyncmeta_back_monitor_target_conn_free;
|
||||
cb->mc_private = (void *)&mc->mc_conns[i];
|
||||
|
||||
a = attrs_alloc( 1 + 6 );
|
||||
a = attrs_alloc( 1 + 8 );
|
||||
|
||||
a->a_desc = slap_schema.si_ad_objectClass;
|
||||
attr_valadd( a, &oc_olmAsyncmetaTargetConnection->soc_cname, NULL, 1 );
|
||||
|
|
@ -559,6 +605,14 @@ asyncmeta_back_monitor_target_conn_init(
|
|||
|
||||
next->a_desc = ad_olmTargetConnPeerAddress;
|
||||
attr_valadd( next, &bv, NULL, 1 );
|
||||
next = next->a_next;
|
||||
|
||||
next->a_desc = ad_olmTargetConnResetTime;
|
||||
attr_valadd( next, &bv, NULL, 1 );
|
||||
next = next->a_next;
|
||||
|
||||
next->a_desc = ad_olmTargetConnEstablishedTime;
|
||||
attr_valadd( next, &bv, NULL, 1 );
|
||||
|
||||
rc = mbe->register_entry( e, NULL, ms, MONITOR_F_PERSISTENT_CH );
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
|
|
@ -791,6 +845,12 @@ asyncmeta_back_monitor_targets_update(
|
|||
bv.bv_len = snprintf( buf, sizeof( buf ), "%i", mt->mt_timeout_ops );
|
||||
ber_bvreplace( &a->a_vals[ 0 ], &bv );
|
||||
|
||||
a = attr_find( e->e_attrs, ad_olmTgtConnLastReset );
|
||||
assert( a != NULL );
|
||||
bv.bv_val = buf;
|
||||
bv.bv_len = snprintf( buf, sizeof( buf ), "%lu", mt->msc_reset_time );
|
||||
ber_bvreplace( &a->a_vals[ 0 ], &bv );
|
||||
|
||||
return SLAP_CB_CONTINUE;
|
||||
}
|
||||
|
||||
|
|
@ -866,7 +926,7 @@ asyncmeta_back_monitor_targets_init(
|
|||
cb->mc_free = asyncmeta_back_monitor_targets_free;
|
||||
cb->mc_private = (void *)&mi->mi_targets[i];
|
||||
|
||||
a = attrs_alloc( 1 + 3 );
|
||||
a = attrs_alloc( 1 + 4 );
|
||||
|
||||
a->a_desc = slap_schema.si_ad_objectClass;
|
||||
attr_valadd( a, &oc_olmAsyncmetaTarget->soc_cname, NULL, 1 );
|
||||
|
|
@ -880,6 +940,10 @@ asyncmeta_back_monitor_targets_init(
|
|||
attr_valadd( next, &bv, NULL, 1 );
|
||||
next = next->a_next;
|
||||
|
||||
next->a_desc = ad_olmTgtConnLastReset;
|
||||
attr_valadd( next, &bv, NULL, 1 );
|
||||
next = next->a_next;
|
||||
|
||||
next->a_desc = ad_olmTgtTimeoutOps;
|
||||
attr_valadd( next, &bv, NULL, 1 );
|
||||
|
||||
|
|
|
|||
7
tests/data/asyncmeta.1.out
Normal file
7
tests/data/asyncmeta.1.out
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
dn: cn=Target Connection 1,cn=Connection Group 1,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 1,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
7
tests/data/asyncmeta.2.out
Normal file
7
tests/data/asyncmeta.2.out
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
dn: cn=Target Connection 1,cn=Connection Group 2,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 2,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
31
tests/data/asyncmeta.allopen.out
Normal file
31
tests/data/asyncmeta.allopen.out
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
dn: cn=Connections,cn=database 1,cn=databases,cn=monitor
|
||||
|
||||
dn: cn=Connection Group 1,cn=Connections,cn=database 1,cn=databases,cn=monitor
|
||||
|
||||
dn: cn=Target Connection 1,cn=Connection Group 1,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: anonymous,initialized
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 1,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: anonymous,initialized
|
||||
|
||||
dn: cn=Connection Group 2,cn=Connections,cn=database 1,cn=databases,cn=monitor
|
||||
|
||||
dn: cn=Target Connection 1,cn=Connection Group 2,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: anonymous,initialized
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 2,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: anonymous,initialized
|
||||
|
||||
dn: cn=Connection Group 3,cn=Connections,cn=database 1,cn=databases,cn=monitor
|
||||
|
||||
dn: cn=Target Connection 1,cn=Connection Group 3,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: anonymous,initialized
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 3,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: anonymous,initialized
|
||||
23
tests/data/asyncmeta.closed.out
Normal file
23
tests/data/asyncmeta.closed.out
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
dn: cn=Target Connection 1,cn=Connection Group 1,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 1,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 1,cn=Connection Group 2,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 2,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 1,cn=Connection Group 3,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
|
||||
dn: cn=Target Connection 2,cn=Connection Group 3,cn=Connections,cn=database 1,
|
||||
cn=databases,cn=monitor
|
||||
olmTargetConnFlags: closed
|
||||
79
tests/data/slapd-asyncmeta-conttl.conf
Normal file
79
tests/data/slapd-asyncmeta-conttl.conf
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# provider slapd config -- for testing
|
||||
# $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 1998-2025 The OpenLDAP Foundation.
|
||||
## All rights reserved.
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted only as authorized by the OpenLDAP
|
||||
## Public License.
|
||||
##
|
||||
## A copy of this license is available in the file LICENSE in the
|
||||
## top-level directory of the distribution or, alternatively, at
|
||||
## <http://www.OpenLDAP.org/license.html>.
|
||||
|
||||
include @SCHEMADIR@/core.schema
|
||||
include @SCHEMADIR@/cosine.schema
|
||||
include @SCHEMADIR@/inetorgperson.schema
|
||||
include @SCHEMADIR@/openldap.schema
|
||||
include @SCHEMADIR@/nis.schema
|
||||
pidfile @TESTDIR@/slapd.m.pid
|
||||
argsfile @TESTDIR@/slapd.m.args
|
||||
|
||||
#ldapmod#modulepath ../servers/slapd/back-ldap/
|
||||
#ldapmod#moduleload back_ldap.la
|
||||
#asyncmetamod#modulepath ../servers/slapd/back-asyncmeta/
|
||||
#asyncmetamod#moduleload back_asyncmeta.la
|
||||
|
||||
# seems to improve behavior under very heavy load
|
||||
# (i.e. it alleviates load on target systems)
|
||||
threads 8
|
||||
|
||||
#######################################################################
|
||||
# database definitions
|
||||
#######################################################################
|
||||
|
||||
database asyncmeta
|
||||
suffix "o=Example,c=US"
|
||||
rootdn "cn=Manager,o=Example,c=US"
|
||||
rootpw secret
|
||||
chase-referrals no
|
||||
#nretries forever
|
||||
nretries 100
|
||||
#norefs true
|
||||
network-timeout 500
|
||||
#max-timeout-ops 50
|
||||
#max-pending-ops 128
|
||||
max-target-conns 3
|
||||
conn-ttl 10s 5s
|
||||
|
||||
monitoring on
|
||||
|
||||
# local
|
||||
uri "@URI2@ou=Meta,o=Example,c=US"
|
||||
subtree-exclude "ou=Excluded,ou=Meta,o=Example,c=US"
|
||||
suffixmassage "ou=Meta,o=Example,c=US" "ou=Meta,dc=example,dc=com"
|
||||
###pseudorootdn "cn=manager,ou=meta,dc=example,dc=com"
|
||||
###pseudorootpw secret
|
||||
idassert-bind bindmethod=simple
|
||||
binddn="cn=manager,ou=meta,dc=example,dc=com"
|
||||
credentials="secret"
|
||||
mode=self
|
||||
flags=non-prescriptive
|
||||
idassert-authzFrom "dn.exact:cn=Manager,o=Local"
|
||||
|
||||
# remote
|
||||
uri "@URI1@o=Example,c=US"
|
||||
subtree-include "dn.subtree:o=Example,c=US"
|
||||
suffixmassage "o=Example,c=US" "dc=example,dc=com"
|
||||
###pseudorootdn "cn=manager,dc=example,dc=com"
|
||||
###pseudorootpw secret
|
||||
idassert-bind bindmethod=simple
|
||||
binddn="cn=manager,dc=example,dc=com"
|
||||
credentials="secret"
|
||||
mode=self
|
||||
flags=non-prescriptive
|
||||
idassert-authzFrom "dn.exact:cn=Manager,o=Local"
|
||||
|
||||
database monitor
|
||||
|
|
@ -166,6 +166,7 @@ METACONF=$DATADIR/slapd-meta.conf
|
|||
METACONF1=$DATADIR/slapd-meta-target1.conf
|
||||
METACONF2=$DATADIR/slapd-meta-target2.conf
|
||||
ASYNCMETACONF=$DATADIR/slapd-asyncmeta.conf
|
||||
ASYNCMETACONF2=$DATADIR/slapd-asyncmeta-conttl.conf
|
||||
GLUELDAPCONF=$DATADIR/slapd-glue-ldap.conf
|
||||
ACICONF=$DATADIR/slapd-aci.conf
|
||||
VALSORTCONF=$DATADIR/slapd-valsort.conf
|
||||
|
|
|
|||
295
tests/scripts/test090-asyncmeta-conttl
Executable file
295
tests/scripts/test090-asyncmeta-conttl
Executable file
|
|
@ -0,0 +1,295 @@
|
|||
#! /bin/sh
|
||||
# $OpenLDAP$
|
||||
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
|
||||
##
|
||||
## Copyright 1998-2025 The OpenLDAP Foundation.
|
||||
## All rights reserved.
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted only as authorized by the OpenLDAP
|
||||
## Public License.
|
||||
##
|
||||
## A copy of this license is available in the file LICENSE in the
|
||||
## top-level directory of the distribution or, alternatively, at
|
||||
## <http://www.OpenLDAP.org/license.html>.
|
||||
|
||||
echo "running defines.sh"
|
||||
. $SRCDIR/scripts/defines.sh
|
||||
|
||||
echo ""
|
||||
|
||||
if test $BACKASYNCMETA = asyncmetano ; then
|
||||
echo "asyncmeta backend not available, test skipped"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if test $BACKLDAP = ldapno ; then
|
||||
echo "ldap backend not available, test skipped"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
rm -rf $TESTDIR
|
||||
|
||||
mkdir -p $TESTDIR $DBDIR1 $DBDIR2
|
||||
|
||||
$SLAPPASSWD -g -n >$CONFIGPWF
|
||||
echo "rootpw `$SLAPPASSWD -T $CONFIGPWF`" >$TESTDIR/configpw.conf
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT1..."
|
||||
. $CONFFILTER $BACKEND < $METACONF1 > $CONF1
|
||||
$SLAPD -f $CONF1 -h $URI1 -d $LVL > $LOG1 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
KILLPIDS="$PID"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "Using ldapsearch to check that slapd is running..."
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI1 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting 5 seconds for slapd to start..."
|
||||
sleep 5
|
||||
done
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Using ldapadd to populate the database..."
|
||||
$LDAPADD -D "$MANAGERDN" -H $URI1 -w $PASSWD < \
|
||||
$LDIFORDERED > $TESTOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapadd failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT2..."
|
||||
. $CONFFILTER $BACKEND < $METACONF2 > $CONF2
|
||||
$SLAPD -f $CONF2 -h $URI2 -d $LVL > $LOG2 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
KILLPIDS="$KILLPIDS $PID"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "Using ldapsearch to check that slapd is running..."
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI2 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting 5 seconds for slapd to start..."
|
||||
sleep 5
|
||||
done
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Using ldapadd to populate the database..."
|
||||
$LDAPADD -D "$METAMANAGERDN" -H $URI2 -w $PASSWD < \
|
||||
$LDIFMETA >> $TESTOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapadd failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Starting slapd on TCP/IP port $PORT3..."
|
||||
. $CONFFILTER $BACKEND < $ASYNCMETACONF2 > $CONF3
|
||||
$SLAPD -f $CONF3 -h $URI3 -d $LVL > $LOG3 2>&1 &
|
||||
PID=$!
|
||||
if test $WAIT != 0 ; then
|
||||
echo PID $PID
|
||||
read foo
|
||||
fi
|
||||
KILLPIDS="$KILLPIDS $PID"
|
||||
|
||||
sleep 1
|
||||
|
||||
echo "Using ldapsearch to check that slapd is running..."
|
||||
for i in 0 1 2 3 4 5; do
|
||||
$LDAPSEARCH -s base -b "$MONITOR" -H $URI3 \
|
||||
'objectclass=*' > /dev/null 2>&1
|
||||
RC=$?
|
||||
if test $RC = 0 ; then
|
||||
break
|
||||
fi
|
||||
echo "Waiting 5 seconds for slapd to start..."
|
||||
sleep 5
|
||||
done
|
||||
if test $RC != 0 ; then
|
||||
echo "ldapsearch failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
#search cn=monitor, all connections are closed
|
||||
SEARCHDN="cn=Connections,cn=database 1,cn=databases,cn=monitor"
|
||||
echo "Verifying that all target connections are closed..."
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
echo " base=\"$SEARCHDN\"..."
|
||||
echo "# base=\"$SEARCHDN\"..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -H $URI3 \
|
||||
-b "$SEARCHDN" \
|
||||
"olmTargetConnFlags=closed" 'olmTargetConnFlags' >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "Unable to read monitor ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER < $SEARCHOUT > $SEARCHFLT
|
||||
$LDIFFILTER < data/asyncmeta.closed.out > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
|
||||
#run 3 searches
|
||||
for i in 0 1 2; do
|
||||
BASEDN="o=Example,c=US"
|
||||
echo "Searching base=\"$BASEDN\"..."
|
||||
echo "# searching base=\"$BASEDN\"..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -S "" -H $URI3 -b "$BASEDN" >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
#if test $RC != 0 ; then
|
||||
# echo "Search failed ($RC)!"
|
||||
# test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
# exit $RC
|
||||
#fi
|
||||
case $RC in
|
||||
0)
|
||||
;;
|
||||
51)
|
||||
echo "### Hit LDAP_BUSY problem; you may want to re-run the test"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Search failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
sleep 2
|
||||
done
|
||||
# search cn=monitor - no connections should be closed yet
|
||||
SEARCHDN="cn=Connections,cn=database 1,cn=databases,cn=monitor"
|
||||
echo "Verifying that all target connections are open..."
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
echo " base=\"$SEARCHDN\"..."
|
||||
echo "# base=\"$SEARCHDN\"..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -H $URI3 \
|
||||
-b "$SEARCHDN" \
|
||||
'olmTargetConnFlags' >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "Unable to read monitor ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER < $SEARCHOUT > $SEARCHFLT
|
||||
$LDIFFILTER < data/asyncmeta.allopen.out > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
|
||||
# wait 6 seconds and search cn=monitor - connection group 1 is closed
|
||||
SEARCHDN="cn=Connections,cn=database 1,cn=databases,cn=monitor"
|
||||
echo "Verifying that connection group 1 is closed..."
|
||||
sleep 5
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
echo " base=\"$SEARCHDN\"..."
|
||||
echo "# base=\"$SEARCHDN\"..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -H $URI3 \
|
||||
-b "$SEARCHDN" \
|
||||
"olmTargetConnFlags=closed" 'olmTargetConnFlags' >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "Unable to read monitor ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER < $SEARCHOUT > $SEARCHFLT
|
||||
$LDIFFILTER < data/asyncmeta.1.out > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
SEARCHDN="cn=Connections,cn=database 1,cn=databases,cn=monitor"
|
||||
echo "Verifying that target connection group 2 is closed..."
|
||||
sleep 6
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
echo " base=\"$SEARCHDN\"..."
|
||||
echo "# base=\"$SEARCHDN\"..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -H $URI3 \
|
||||
-b "cn=Connection Group 2,$SEARCHDN" \
|
||||
"olmTargetConnFlags=closed" 'olmTargetConnFlags' >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "Unable to read monitor ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER < $SEARCHOUT > $SEARCHFLT
|
||||
$LDIFFILTER < data/asyncmeta.2.out > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
|
||||
SEARCHDN="cn=Connections,cn=database 1,cn=databases,cn=monitor"
|
||||
echo "Verifying that all target connections are closed..."
|
||||
# wait 6 seconds, search, all connections should be closed
|
||||
sleep 6
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
echo " base=\"$SEARCHDN\"..."
|
||||
echo "# base=\"$SEARCHDN\"..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -H $URI3 \
|
||||
-b "$SEARCHDN" \
|
||||
"olmTargetConnFlags=closed" 'olmTargetConnFlags' >> $SEARCHOUT 2>&1
|
||||
RC=$?
|
||||
if test $RC != 0 ; then
|
||||
echo "Unable to read monitor ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
fi
|
||||
echo "Filtering ldapsearch results..."
|
||||
$LDIFFILTER < $SEARCHOUT > $SEARCHFLT
|
||||
$LDIFFILTER < data/asyncmeta.closed.out > $LDIFFLT
|
||||
echo "Comparing filter output..."
|
||||
$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
|
||||
|
||||
cat /dev/null > $SEARCHOUT
|
||||
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
|
||||
echo ">>>>> Test succeeded"
|
||||
|
||||
test $KILLSERVERS != no && wait
|
||||
|
||||
exit 0
|
||||
Loading…
Reference in a new issue