mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-24 00:29:35 -05:00
ITS#5836, add writetimeout keyword for timing out hung writers
This commit is contained in:
parent
a77e7a47cf
commit
f2cc7e8a0a
6 changed files with 76 additions and 22 deletions
|
|
@ -706,6 +706,9 @@ static ConfigTable config_back_cf_table[] = {
|
|||
&config_updateref, "( OLcfgDbAt:0.13 NAME 'olcUpdateRef' "
|
||||
"EQUALITY caseIgnoreMatch "
|
||||
"SUP labeledURI )", NULL, NULL },
|
||||
{ "writetimeout", "timeout", 2, 2, 0, ARG_INT,
|
||||
&global_writetimeout, "( OLcfgGlAt:88 NAME 'olcWriteTimeout' "
|
||||
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
|
||||
{ NULL, NULL, 0, 0, 0, ARG_IGNORED,
|
||||
NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
|
@ -764,7 +767,7 @@ static ConfigOCs cf_ocs[] = {
|
|||
"olcTLSCACertificatePath $ olcTLSCertificateFile $ "
|
||||
"olcTLSCertificateKeyFile $ olcTLSCipherSuite $ olcTLSCRLCheck $ "
|
||||
"olcTLSRandFile $ olcTLSVerifyClient $ olcTLSDHParamFile $ "
|
||||
"olcTLSCRLFile $ olcToolThreads $ "
|
||||
"olcTLSCRLFile $ olcToolThreads $ olcWriteTimeout $ "
|
||||
"olcObjectIdentifier $ olcAttributeTypes $ olcObjectClasses $ "
|
||||
"olcDitContentRules $ olcLdapSyntaxes ) )", Cft_Global },
|
||||
{ "( OLcfgGlOc:2 "
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ slap_mask_t global_allows = 0;
|
|||
slap_mask_t global_disallows = 0;
|
||||
int global_gentlehup = 0;
|
||||
int global_idletimeout = 0;
|
||||
int global_writetimeout = 0;
|
||||
char *global_host = NULL;
|
||||
char *global_realm = NULL;
|
||||
char *sasl_host = NULL;
|
||||
|
|
|
|||
|
|
@ -218,9 +218,12 @@ int connections_shutdown(void)
|
|||
*/
|
||||
int connections_timeout_idle(time_t now)
|
||||
{
|
||||
int i = 0;
|
||||
int i = 0, writers = 0;
|
||||
int connindex;
|
||||
Connection* c;
|
||||
time_t old;
|
||||
|
||||
old = slapd_get_writetime();
|
||||
|
||||
for( c = connection_first( &connindex );
|
||||
c != NULL;
|
||||
|
|
@ -240,9 +243,21 @@ int connections_timeout_idle(time_t now)
|
|||
connection_closing( c, "idletimeout" );
|
||||
connection_close( c );
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
if ( c->c_writewaiter ) {
|
||||
writers = 1;
|
||||
if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) {
|
||||
/* close it */
|
||||
connection_closing( c, "writetimeout" );
|
||||
connection_close( c );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
connection_done( c );
|
||||
if ( !writers )
|
||||
slapd_clr_writetime( old );
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ static ber_socket_t wake_sds[2]
|
|||
;
|
||||
static int emfile;
|
||||
|
||||
static time_t chk_writetime;
|
||||
|
||||
static volatile int waking;
|
||||
#ifdef NO_THREADS
|
||||
#define WAKE_LISTENER(w) do { \
|
||||
|
|
@ -954,6 +956,9 @@ slapd_set_write( ber_socket_t s, int wake )
|
|||
SLAP_SOCK_SET_WRITE( s );
|
||||
slap_daemon.sd_nwriters++;
|
||||
}
|
||||
if (( wake & 2 ) && global_writetimeout ) {
|
||||
chk_writetime = slap_get_time();
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
WAKE_LISTENER(wake);
|
||||
|
|
@ -987,6 +992,25 @@ slapd_set_read( ber_socket_t s, int wake )
|
|||
WAKE_LISTENER(wake);
|
||||
}
|
||||
|
||||
time_t
|
||||
slapd_get_writetime()
|
||||
{
|
||||
time_t cur;
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
cur = chk_writetime;
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
return cur;
|
||||
}
|
||||
|
||||
void
|
||||
slapd_clr_writetime( time_t old )
|
||||
{
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
if ( chk_writetime == old )
|
||||
chk_writetime = 0;
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
}
|
||||
|
||||
static void
|
||||
slapd_close( ber_socket_t s )
|
||||
{
|
||||
|
|
@ -2033,24 +2057,12 @@ slapd_daemon_task(
|
|||
{
|
||||
int l;
|
||||
time_t last_idle_check = 0;
|
||||
struct timeval idle;
|
||||
int ebadf = 0;
|
||||
|
||||
#define SLAPD_IDLE_CHECK_LIMIT 4
|
||||
|
||||
if ( global_idletimeout > 0 ) {
|
||||
last_idle_check = slap_get_time();
|
||||
/* Set the select timeout.
|
||||
* Don't just truncate, preserve the fractions of
|
||||
* seconds to prevent sleeping for zero time.
|
||||
*/
|
||||
idle.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
|
||||
idle.tv_usec = global_idletimeout - \
|
||||
( idle.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
|
||||
idle.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
|
||||
} else {
|
||||
idle.tv_sec = 0;
|
||||
idle.tv_usec = 0;
|
||||
}
|
||||
|
||||
slapd_add( wake_sds[0], 0, NULL );
|
||||
|
|
@ -2155,14 +2167,34 @@ slapd_daemon_task(
|
|||
|
||||
now = slap_get_time();
|
||||
|
||||
if ( ( global_idletimeout > 0 ) &&
|
||||
difftime( last_idle_check +
|
||||
global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 )
|
||||
{
|
||||
connections_timeout_idle( now );
|
||||
last_idle_check = now;
|
||||
if ( global_idletimeout > 0 || chk_writetime ) {
|
||||
int check = 0;
|
||||
/* Set the select timeout.
|
||||
* Don't just truncate, preserve the fractions of
|
||||
* seconds to prevent sleeping for zero time.
|
||||
*/
|
||||
if ( chk_writetime ) {
|
||||
tv.tv_sec = global_writetimeout;
|
||||
tv.tv_usec = global_writetimeout;
|
||||
if ( difftime( chk_writetime, now ) < 0 )
|
||||
check = 2;
|
||||
} else {
|
||||
tv.tv_sec = global_idletimeout / SLAPD_IDLE_CHECK_LIMIT;
|
||||
tv.tv_usec = global_idletimeout - \
|
||||
( tv.tv_sec * SLAPD_IDLE_CHECK_LIMIT );
|
||||
tv.tv_usec *= 1000000 / SLAPD_IDLE_CHECK_LIMIT;
|
||||
if ( difftime( last_idle_check +
|
||||
global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 )
|
||||
check = 1;
|
||||
}
|
||||
if ( check ) {
|
||||
connections_timeout_idle( now );
|
||||
last_idle_check = now;
|
||||
}
|
||||
} else {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
}
|
||||
tv = idle;
|
||||
|
||||
#ifdef SIGHUP
|
||||
if ( slapd_gentle_shutdown ) {
|
||||
|
|
|
|||
|
|
@ -842,6 +842,8 @@ LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
|
|||
LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
|
||||
LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
|
||||
LDAP_SLAPD_F (int) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
|
||||
LDAP_SLAPD_F (void) slapd_clr_writetime LDAP_P((time_t old));
|
||||
LDAP_SLAPD_F (time_t) slapd_get_writetime LDAP_P((void));
|
||||
|
||||
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
|
||||
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;
|
||||
|
|
@ -1930,6 +1932,7 @@ LDAP_SLAPD_V (const char) Versionstr[];
|
|||
|
||||
LDAP_SLAPD_V (int) global_gentlehup;
|
||||
LDAP_SLAPD_V (int) global_idletimeout;
|
||||
LDAP_SLAPD_V (int) global_writetimeout;
|
||||
LDAP_SLAPD_V (char *) global_host;
|
||||
LDAP_SLAPD_V (char *) global_realm;
|
||||
LDAP_SLAPD_V (char *) sasl_host;
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ static long send_ldap_ber(
|
|||
/* wait for socket to be write-ready */
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_write2_mutex );
|
||||
conn->c_writewaiter = 1;
|
||||
slapd_set_write( conn->c_sd, 1 );
|
||||
slapd_set_write( conn->c_sd, 2 );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
|
|
|
|||
Loading…
Reference in a new issue