improve timeout support (ITS#4157, ITS#4663)

This commit is contained in:
Pierangelo Masarati 2006-09-04 08:26:09 +00:00
parent 150a4f106c
commit 84d6a04c91
8 changed files with 122 additions and 36 deletions

View File

@ -68,17 +68,16 @@ lastmod off
.fi
.RE
.LP
for every
for
.B ldap
and
.B meta
database.
This is because operational attributes related to entry creation and
modification should not be proxied, as they could be mistakenly written
databases.
This was required because operational attributes related to entry creation
and modification should not be proxied, as they could be mistakenly written
to the target server(s), generating an error.
The current implementation automatically sets lastmod to off, so its use
is redundant and should be omitted, because the lastmod directive will
be deprecated in the future.
The current implementation automatically sets lastmod to \fBoff\fP,
so its use is redundant and should be omitted.
.SH SPECIAL CONFIGURATION DIRECTIVES
Target configuration starts with the "uri" directive.

View File

@ -179,7 +179,7 @@ retry:;
rs->sr_err = ldap_add_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
attrs, ctrls, NULL, &msgid );
rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
mt->mt_timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT );
mt->mt_timeout[ SLAP_OP_ADD ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {

View File

@ -273,7 +273,7 @@ typedef struct metatarget_t {
time_t mt_network_timeout;
struct timeval mt_bind_timeout;
#define META_BIND_TIMEOUT LDAP_BACK_RESULT_UTIMEOUT
time_t mt_timeout[ LDAP_BACK_OP_LAST ];
time_t mt_timeout[ SLAP_OP_LAST ];
} metatarget_t;
typedef struct metadncache_t {
@ -334,7 +334,7 @@ typedef struct metainfo_t {
time_t mi_conn_ttl;
time_t mi_idle_timeout;
struct timeval mi_bind_timeout;
time_t mi_timeout[ LDAP_BACK_OP_LAST ];
time_t mi_timeout[ SLAP_OP_LAST ];
} metainfo_t;
typedef enum meta_op_type {

View File

@ -319,6 +319,43 @@ meta_back_bind_op_result(
op->o_log_prefix, candidate, 0 );
if ( rs->sr_err == LDAP_SUCCESS ) {
time_t stoptime = (time_t)(-1),
timeout;
int timeout_err = op->o_protocol >= LDAP_VERSION3 ?
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
const char *timeout_text = "Operation timed out";
slap_op_t opidx = slap_req2op( op->o_tag );
/* since timeout is not specified, compute and use
* the one specific to the ongoing operation */
if ( opidx == LDAP_REQ_SEARCH ) {
if ( op->ors_tlimit <= 0 ) {
timeout = 0;
} else {
timeout = op->ors_tlimit;
timeout_err = LDAP_TIMELIMIT_EXCEEDED;
timeout_text = NULL;
}
} else {
timeout = mt->mt_timeout[ opidx ];
}
/* better than nothing :) */
if ( timeout == 0 ) {
if ( mi->mi_idle_timeout ) {
timeout = mi->mi_idle_timeout;
} else if ( mi->mi_conn_ttl ) {
timeout = mi->mi_conn_ttl;
}
}
if ( timeout ) {
stoptime = op->o_time + timeout;
}
LDAP_BACK_TV_SET( &tv );
/*
@ -328,11 +365,15 @@ retry:;
rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
switch ( rc ) {
case 0:
#if 0
Debug( LDAP_DEBUG_ANY,
"%s meta_back_bind_op_result[%d]: ldap_result=0 nretries=%d.\n",
op->o_log_prefix, candidate, nretries );
#endif
if ( nretries != META_RETRY_NEVER ) {
if ( nretries != META_RETRY_NEVER
|| ( timeout && slap_get_time() <= stoptime ) )
{
ldap_pvt_thread_yield();
if ( nretries > 0 ) {
nretries--;
@ -341,16 +382,17 @@ retry:;
goto retry;
}
/* FIXME: binds cannot be abandoned */
/* don't let anyone else use this handler,
* because there's a pending bind that will not
* be acknowledged */
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
ldap_unbind_ext( msc->msc_ld, NULL, NULL );
msc->msc_ld = NULL;
rs->sr_err = LDAP_BUSY;
LDAP_BACK_CONN_BINDING_CLEAR( msc );
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
rs->sr_err = timeout_err;
rs->sr_text = timeout_text;
break;
case -1:
@ -876,24 +918,55 @@ meta_back_op_result(
int rc;
struct timeval tv;
LDAPMessage *res = NULL;
time_t stoptime = (time_t)(-1);
int timeout_err = op->o_protocol >= LDAP_VERSION3 ?
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
const char *timeout_text = "Operation timed out";
/* if timeout is not specified, compute and use
* the one specific to the ongoing operation */
if ( timeout == (time_t)(-1) ) {
slap_op_t opidx = slap_req2op( op->o_tag );
if ( opidx == SLAP_OP_SEARCH ) {
if ( op->ors_tlimit <= 0 ) {
timeout = 0;
} else {
timeout = op->ors_tlimit;
timeout_err = LDAP_TIMELIMIT_EXCEEDED;
timeout_text = NULL;
}
} else {
timeout = mt->mt_timeout[ opidx ];
}
}
/* better than nothing :) */
if ( timeout == 0 ) {
if ( mi->mi_idle_timeout ) {
timeout = mi->mi_idle_timeout;
} else if ( mi->mi_conn_ttl ) {
timeout = mi->mi_conn_ttl;
}
}
if ( timeout ) {
tv.tv_sec = timeout;
tv.tv_usec = 0;
} else {
LDAP_BACK_TV_SET( &tv );
stoptime = op->o_time + timeout;
}
LDAP_BACK_TV_SET( &tv );
retry:;
rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
switch ( rc ) {
case 0:
if ( timeout ) {
if ( timeout && slap_get_time() > stoptime ) {
(void)meta_back_cancel( mc, op, rs, msgid, candidate, sendok );
rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
rs->sr_text = "Operation timed out";
rs->sr_err = timeout_err;
rs->sr_text = timeout_text;
break;
}

View File

@ -186,7 +186,7 @@ meta_back_db_config(
mt->mt_version = mi->mi_version;
mt->mt_network_timeout = mi->mi_network_timeout;
mt->mt_bind_timeout = mi->mi_bind_timeout;
for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
for ( c = 0; c < SLAP_OP_LAST; c++ ) {
mt->mt_timeout[ c ] = mi->mi_timeout[ c ];
}
@ -890,7 +890,7 @@ meta_back_db_config(
if ( argc < 2 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
"%s: line %d: \"timeout [{add|bind|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
fname, lineno, 0 );
return( 1 );
}
@ -903,19 +903,33 @@ meta_back_db_config(
if ( sep != NULL ) {
size_t len = sep - argv[ c ];
if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
t = &tv[ LDAP_BACK_OP_ADD ];
if ( strncasecmp( argv[ c ], "bind", len ) == 0 ) {
t = &tv[ SLAP_OP_BIND ];
/* unbind makes little sense */
} else if ( strncasecmp( argv[ c ], "add", len ) == 0 ) {
t = &tv[ SLAP_OP_ADD ];
} else if ( strncasecmp( argv[ c ], "delete", len ) == 0 ) {
t = &tv[ LDAP_BACK_OP_DELETE ];
} else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
t = &tv[ LDAP_BACK_OP_MODIFY ];
t = &tv[ SLAP_OP_DELETE ];
} else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
t = &tv[ LDAP_BACK_OP_MODRDN ];
t = &tv[ SLAP_OP_MODRDN ];
} else if ( strncasecmp( argv[ c ], "modify", len ) == 0 ) {
t = &tv[ SLAP_OP_MODIFY ];
} else if ( strncasecmp( argv[ c ], "compare", len ) == 0 ) {
t = &tv[ SLAP_OP_COMPARE ];
#if 0 /* uses timelimit instead */
} else if ( strncasecmp( argv[ c ], "search", len ) == 0 ) {
t = &tv[ SLAP_OP_SEARCH ];
#endif
/* abandon makes little sense */
#if 0 /* not implemented yet */
} else if ( strncasecmp( argv[ c ], "extended", len ) == 0 ) {
t = &tv[ SLAP_OP_EXTENDED ];
#endif
} else {
char buf[ SLAP_TEXT_BUFLEN ];
snprintf( buf, sizeof( buf ),
"unknown operation \"%s\" for timeout #%d",
argv[ c ], c );
"unknown/unhandled operation \"%s\" for timeout #%d",
argv[ c ], c - 1 );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s.\n",
fname, lineno, buf );
@ -940,7 +954,7 @@ meta_back_db_config(
} else {
int i;
for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
for ( i = 0; i < SLAP_OP_LAST; i++ ) {
tv[ i ] = (time_t)val;
}
}

View File

@ -77,7 +77,7 @@ retry:;
rs->sr_err = ldap_delete_ext( mc->mc_conns[ candidate ].msc_ld,
mdn.bv_val, ctrls, NULL, &msgid );
rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
mt->mt_timeout[ LDAP_BACK_OP_DELETE ], LDAP_BACK_SENDRESULT );
mt->mt_timeout[ SLAP_OP_DELETE ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {

View File

@ -188,7 +188,7 @@ retry:;
rs->sr_err = ldap_modify_ext( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
modv, ctrls, NULL, &msgid );
rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
mt->mt_timeout[ LDAP_BACK_OP_MODIFY ], LDAP_BACK_SENDRESULT );
mt->mt_timeout[ SLAP_OP_MODIFY ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {

View File

@ -132,7 +132,7 @@ retry:;
mnewSuperior.bv_val, op->orr_deleteoldrdn,
ctrls, NULL, &msgid );
rs->sr_err = meta_back_op_result( mc, op, rs, candidate, msgid,
mt->mt_timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT );
mt->mt_timeout[ SLAP_OP_MODRDN ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {