summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2010-05-09 09:51:26 +0000
committerArthur de Jong <arthur@arthurdejong.org>2010-05-09 09:51:26 +0000
commit3769da0f8a8f8f04ec523d555177b69b8e3a136a (patch)
tree74625840902a620058202d3e734b4a3cc5e2d13d
parent3de75ef335b1f7b552d2420bbf7e489aae1a131d (diff)
refactor retry timing mechanism to use time between first and last error to determin when to rerty and only try once (and don't sleep) when we have been failing for a long time
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1091 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--man/nslcd.conf.5.xml6
-rw-r--r--nslcd/cfg.c2
-rw-r--r--nslcd/cfg.h4
-rw-r--r--nslcd/myldap.c61
4 files changed, 43 insertions, 30 deletions
diff --git a/man/nslcd.conf.5.xml b/man/nslcd.conf.5.xml
index 216fca0..fe5a3d4 100644
--- a/man/nslcd.conf.5.xml
+++ b/man/nslcd.conf.5.xml
@@ -470,9 +470,9 @@
<term><option>reconnect_maxsleeptime</option> <replaceable>SECONDS</replaceable></term>
<listitem>
<para>
- Specified the time after the last successful operation from which the
- <acronym>LDAP</acronym> server is considered permanently unavailable.
- Retries will be done only once in this time period.
+ Specifies the time after which the <acronym>LDAP</acronym> server is
+ considered to be permanently unavailable.
+ Once this time is reached retries will be done only once per this time period.
The default value is 10 seconds.
</para>
</listitem>
diff --git a/nslcd/cfg.c b/nslcd/cfg.c
index 3302682..a13e3c4 100644
--- a/nslcd/cfg.c
+++ b/nslcd/cfg.c
@@ -86,7 +86,7 @@ static void cfg_defaults(struct ldap_config *cfg)
for (i=0;i<(NSS_LDAP_CONFIG_URI_MAX+1);i++)
{
cfg->ldc_uris[i].uri=NULL;
- cfg->ldc_uris[i].lastok=0;
+ cfg->ldc_uris[i].firstfail=0;
cfg->ldc_uris[i].lastfail=0;
}
#ifdef LDAP_VERSION3
diff --git a/nslcd/cfg.h b/nslcd/cfg.h
index 50751a1..9785926 100644
--- a/nslcd/cfg.h
+++ b/nslcd/cfg.h
@@ -71,8 +71,8 @@ enum ldap_map_selector
struct myldap_uri
{
char *uri;
- /* time of last successful operation */
- time_t lastok;
+ /* time of first failed operation */
+ time_t firstfail;
/* time of last failed operation */
time_t lastfail;
};
diff --git a/nslcd/myldap.c b/nslcd/myldap.c
index a1be5dc..742f2b7 100644
--- a/nslcd/myldap.c
+++ b/nslcd/myldap.c
@@ -795,30 +795,45 @@ static int do_retry_search(MYLDAP_SEARCH *search)
time_t nexttry;
time_t t;
int rc=LDAP_UNAVAILABLE;
+ struct myldap_uri *current_uri;
+ int dotry[NSS_LDAP_CONFIG_URI_MAX];
+ /* clear time stamps */
+ for (start_uri=0;start_uri<NSS_LDAP_CONFIG_URI_MAX;start_uri++)
+ dotry[start_uri]=1;
/* keep trying until we time out */
endtime=time(NULL)+nslcd_cfg->ldc_reconnect_maxsleeptime;
- nexttry=endtime;
while (1)
{
+ nexttry=endtime;
/* try each configured URL once */
pthread_mutex_lock(&uris_mutex);
start_uri=search->session->current_uri;
do
{
- /* only try if we haven't just had an error and it was a long tme
- since the last ok */
- if ( ( ( nslcd_cfg->ldc_uris[search->session->current_uri].lastfail -
- nslcd_cfg->ldc_uris[search->session->current_uri].lastok ) < nslcd_cfg->ldc_reconnect_maxsleeptime) ||
- ( time(NULL) >= (nslcd_cfg->ldc_uris[search->session->current_uri].lastfail+nslcd_cfg->ldc_reconnect_maxsleeptime) ) )
+ current_uri=&(nslcd_cfg->ldc_uris[search->session->current_uri]);
+ /* only try this URI if we should */
+ if (!dotry[search->session->current_uri])
+ { /* skip this URI */ }
+ else if ( (current_uri->lastfail > (current_uri->firstfail+nslcd_cfg->ldc_reconnect_maxsleeptime)) &&
+ ((t=time(NULL)) < (current_uri->lastfail+nslcd_cfg->ldc_reconnect_maxsleeptime)) )
+ {
+ /* we are in a hard fail state and have retried not long ago */
+ log_log(LOG_DEBUG,"not retrying server %s which failed just %d second(s) ago and has been failing for %d seconds",
+ current_uri->uri,(int)(t-current_uri->lastfail),
+ (int)(t-current_uri->firstfail));
+ dotry[search->session->current_uri]=0;
+ }
+ else
{
- pthread_mutex_unlock(&uris_mutex);
/* try to start the search */
+ pthread_mutex_unlock(&uris_mutex);
rc=do_try_search(search);
if (rc==LDAP_SUCCESS)
{
- /* update ok time and return search handle */
+ /* update ok time */
pthread_mutex_lock(&uris_mutex);
- nslcd_cfg->ldc_uris[search->session->current_uri].lastok=time(NULL);
+ current_uri->firstfail=0;
+ current_uri->lastfail=0;
pthread_mutex_unlock(&uris_mutex);
/* flag the search as valid */
search->valid=1;
@@ -829,17 +844,17 @@ static int do_retry_search(MYLDAP_SEARCH *search)
/* update time of failure and figure out when we should retry */
pthread_mutex_lock(&uris_mutex);
t=time(NULL);
- nslcd_cfg->ldc_uris[search->session->current_uri].lastfail=t;
- t+=nslcd_cfg->ldc_reconnect_sleeptime;
- if (t<nexttry)
- nexttry=t;
- }
- else if (nslcd_cfg->ldc_uris[search->session->current_uri].lastfail>0)
- {
- /* we are in a hard fail state, figure out when we can retry */
- t=(nslcd_cfg->ldc_uris[search->session->current_uri].lastfail+nslcd_cfg->ldc_reconnect_maxsleeptime);
- if (t<nexttry)
- nexttry=t;
+ /* update timestaps */
+ if (current_uri->firstfail==0)
+ current_uri->firstfail=t;
+ current_uri->lastfail=t;
+ /* check whether we should try this URI again */
+ if (t <= (current_uri->firstfail+nslcd_cfg->ldc_reconnect_maxsleeptime))
+ {
+ t+=nslcd_cfg->ldc_reconnect_sleeptime;
+ if (t<nexttry)
+ nexttry=t;
+ }
}
/* try the next URI (with wrap-around) */
search->session->current_uri++;
@@ -851,19 +866,17 @@ static int do_retry_search(MYLDAP_SEARCH *search)
/* see if it is any use sleeping */
if (nexttry>=endtime)
{
- log_log(LOG_ERR,"no available LDAP server found");
+ if (search->session->binddn[0]=='\0')
+ log_log(LOG_ERR,"no available LDAP server found");
return rc;
}
/* sleep between tries */
sleeptime=nexttry-time(NULL);
- if (sleeptime>nslcd_cfg->ldc_reconnect_maxsleeptime)
- sleeptime=nslcd_cfg->ldc_reconnect_maxsleeptime;
if (sleeptime>0)
{
log_log(LOG_WARNING,"no available LDAP server found, sleeping %d seconds",sleeptime);
(void)sleep(sleeptime);
}
- nexttry=time(NULL)+nslcd_cfg->ldc_reconnect_maxsleeptime;
}
}