From a75cfb9d5f67dd4be325f151f9e0fc9af0864ac2 Mon Sep 17 00:00:00 2001 From: Arthur de Jong Date: Fri, 29 Mar 2013 20:14:49 +0100 Subject: Detect and handle connection failure and recovery Logs a connection recovery message and run a nscd cache invalidation if configured. --- pynslcd/nscd.py | 7 ++++++- pynslcd/search.py | 22 ++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pynslcd/nscd.py b/pynslcd/nscd.py index 89cb483..19e5ceb 100644 --- a/pynslcd/nscd.py +++ b/pynslcd/nscd.py @@ -24,6 +24,8 @@ import os import subprocess import struct +import cfg + # the file descriptor used for sending messages to the child process signalfd = None @@ -100,7 +102,10 @@ def start_invalidator(): def invalidate(db=None): if signalfd is None: return # nothing to do - db = _db_to_char.get(db, '') + if db: + db = _db_to_char.get(db, '') + else: + db = ''.join(_db_to_char[x] for x in cfg.nscd_invalidate) try: os.write(signalfd, db) except: diff --git a/pynslcd/search.py b/pynslcd/search.py index 9629bec..219929b 100644 --- a/pynslcd/search.py +++ b/pynslcd/search.py @@ -25,6 +25,11 @@ import ldap import ldap.ldapobject import cfg +import nscd + + +# global indicator that there was some error connection to an LDAP server +server_error = False class Connection(ldap.ldapobject.ReconnectLDAPObject): @@ -50,6 +55,23 @@ class Connection(ldap.ldapobject.ReconnectLDAPObject): if cfg.ssl or cfg.uri.startswith('ldaps://'): self.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_HARD) + def reconnect_after_fail(self): + logging.info('connected to LDAP server %s', cfg.uri) + nscd.invalidate() + + def search_s(self, *args, **kwargs): + # wrapper function to keep the global server_error state + global server_error + try: + res = ldap.ldapobject.ReconnectLDAPObject.search_s(self, *args, **kwargs) + except ldap.SERVER_DOWN: + server_error = True + raise + if server_error: + self.reconnect_after_fail() + server_error = False + return res + class LDAPSearch(object): """ -- cgit v1.2.3