diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2013-08-21 21:47:28 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2013-08-21 21:47:28 +0200 |
commit | b0358f74944cd5d7e984700d61da989b5f98cb18 (patch) | |
tree | e6e160d6423d3af0ad805c76834fe0f80ec08035 | |
parent | d58f163b5aceb570aa7bd41b2c8edb3307a3a980 (diff) | |
parent | ebbe8a6fd1b4559f064d79016b3571abc2bf54c4 (diff) |
Retry LDAP servers quickly after receiving SIGUSR1
When nslcd receives the SIGUSR1 signal it will retry connecting to
unavailable LDAP servers sooner.
This signal can for example be sent when (re)stablishing a network
connection.
-rw-r--r-- | man/nslcd.8.xml | 20 | ||||
-rw-r--r-- | nslcd/myldap.c | 22 | ||||
-rw-r--r-- | nslcd/myldap.h | 4 | ||||
-rw-r--r-- | nslcd/nslcd.c | 35 |
4 files changed, 67 insertions, 14 deletions
diff --git a/man/nslcd.8.xml b/man/nslcd.8.xml index 9b7ff90..ce725ab 100644 --- a/man/nslcd.8.xml +++ b/man/nslcd.8.xml @@ -137,6 +137,26 @@ </variablelist> </refsect1> + <refsect1 id="signals"> + <title>Signals</title> + <variablelist remap="IP"> + <varlistentry id="sigterm"> + <term><option>SIGTERM</option>/<option>SIGINT</option></term> + <listitem> + <para>Cancel any running queries and exit.</para> + </listitem> + </varlistentry> + <varlistentry id="sigusr1"> <!-- since 0.9.1 --> + <term><option>SIGUSR1</option></term> + <listitem> + <para>Cause <command>nslcd</command> to retry any failing connections + to the LDAP server, regardless of the <option>reconnect_sleeptime</option> + and <option>reconnect_retrytime</option> options.</para> + </listitem> + </varlistentry> + </variablelist> + </refsect1> + <refsect1 id="files"> <title>Files</title> <para> diff --git a/nslcd/myldap.c b/nslcd/myldap.c index b2258d4..757eb20 100644 --- a/nslcd/myldap.c +++ b/nslcd/myldap.c @@ -1257,6 +1257,28 @@ static int do_retry_search(MYLDAP_SEARCH *search) } } +/* force quick retries of all failing LDAP servers */ +void myldap_immediate_reconnect(void) +{ + int i; + time_t t; + t = time(NULL) - nslcd_cfg->reconnect_retrytime; + pthread_mutex_lock(&uris_mutex); + for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++) + { + /* only adjust failing connections that are in a hard fail state */ + if ((nslcd_cfg->uris[i].lastfail > t) && + (nslcd_cfg->uris[i].lastfail > (nslcd_cfg->uris[i].firstfail + nslcd_cfg->reconnect_retrytime))) + { + /* move lastfail back to ensure quick retry */ + log_log(LOG_DEBUG, "moving lastfail of %s %d second(s) back to force retry", + nslcd_cfg->uris[i].uri, (int)(nslcd_cfg->uris[i].lastfail - t)); + nslcd_cfg->uris[i].lastfail = t; + } + } + pthread_mutex_unlock(&uris_mutex); +} + MYLDAP_SEARCH *myldap_search(MYLDAP_SESSION *session, const char *base, int scope, const char *filter, const char **attrs, int *rcp) diff --git a/nslcd/myldap.h b/nslcd/myldap.h index 9367b43..8c4551a 100644 --- a/nslcd/myldap.h +++ b/nslcd/myldap.h @@ -90,6 +90,10 @@ void myldap_session_check(MYLDAP_SESSION *session); After a call to this function the referenced handle is invalid. */ void myldap_session_close(MYLDAP_SESSION *session); +/* Mark all failing LDAP servers as needing quick retries. This ensures that the + reconnect_sleeptime and reconnect_retrytime sleeping period is cut short. */ +void myldap_immediate_reconnect(void); + /* Do an LDAP search and return a reference to the results (returns NULL on error). This function uses paging, and does reconnects to the configured URLs transparently. The function returns an LDAP status code in the diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c index 073f38c..98aee6b 100644 --- a/nslcd/nslcd.c +++ b/nslcd/nslcd.c @@ -87,8 +87,8 @@ static int nslcd_nofork = 0; /* flag to indicate user requested the --check option */ static int nslcd_checkonly = 0; -/* the exit flag to indicate that a signal was received */ -static volatile int nslcd_exitsignal = 0; +/* the flag to indicate that a signal was received */ +static volatile int nslcd_receivedsignal = 0; /* the server socket used for communication */ static int nslcd_serversocket = -1; @@ -186,11 +186,11 @@ static void parse_cmdline(int argc, char *argv[]) } } -/* signal handler for closing down */ -static void sigexit_handler(int signum) +/* signal handler for storing information on received signals */ +static void sig_handler(int signum) { /* just save the signal to indicate that we're stopping */ - nslcd_exitsignal = signum; + nslcd_receivedsignal = signum; } /* do some cleaning up before terminating */ @@ -803,22 +803,29 @@ int main(int argc, char *argv[]) } pthread_sigmask(SIG_SETMASK, &oldmask, NULL); /* install signalhandlers for some signals */ - install_sighandler(SIGHUP, sigexit_handler); - install_sighandler(SIGINT, sigexit_handler); - install_sighandler(SIGQUIT, sigexit_handler); - install_sighandler(SIGABRT, sigexit_handler); + install_sighandler(SIGHUP, sig_handler); + install_sighandler(SIGINT, sig_handler); + install_sighandler(SIGQUIT, sig_handler); + install_sighandler(SIGABRT, sig_handler); install_sighandler(SIGPIPE, SIG_IGN); - install_sighandler(SIGTERM, sigexit_handler); - install_sighandler(SIGUSR1, sigexit_handler); - install_sighandler(SIGUSR2, sigexit_handler); + install_sighandler(SIGTERM, sig_handler); + install_sighandler(SIGUSR1, sig_handler); + install_sighandler(SIGUSR2, sig_handler); /* wait until we received a signal */ - while (nslcd_exitsignal == 0) + while ((nslcd_receivedsignal == 0) || (nslcd_receivedsignal == SIGUSR1)) { sleep(INT_MAX); /* sleep as long as we can or until we receive a signal */ + if (nslcd_receivedsignal == SIGUSR1) + { + log_log(LOG_INFO, "caught signal %s (%d), refresh retries", + signame(nslcd_receivedsignal), nslcd_receivedsignal); + myldap_immediate_reconnect(); + nslcd_receivedsignal = 0; + } } /* print something about received signal */ log_log(LOG_INFO, "caught signal %s (%d), shutting down", - signame(nslcd_exitsignal), nslcd_exitsignal); + signame(nslcd_receivedsignal), nslcd_receivedsignal); /* cancel all running threads */ for (i = 0; i < nslcd_cfg->threads; i++) if (pthread_cancel(nslcd_threads[i])) |