mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
improve timeout support (ITS#4157, ITS#4663)
This commit is contained in:
parent
150a4f106c
commit
84d6a04c91
@ -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.
|
||||
|
@ -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 ) ) {
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 ) ) {
|
||||
|
@ -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 ) ) {
|
||||
|
@ -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 ) ) {
|
||||
|
Loading…
Reference in New Issue
Block a user