Doug,
The connection has changed a bit for 266. I'll send you a snapshot when Howard Wilkinson has finished testing, and then we can see how your changes apply to it.
-- Luke On 18/03/2010, at 8:10 PM, Douglas E. Engert wrote: The following was submitted as bugs to Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libnss-ldap/+bug/292971 and original source developers: http://bugzilla.padl.com/show_bug.cgi?id=418
Using valgrind with nscd might also be of interest to others.
A memory leak in libnss-ldap over time can cause the nscd process to grow extremely large. For example one nscd process that had been running for three months was using 6GB of swap!
The problem is in the original Padl nss-ldap in at least versions 258, 261 and 265. Ubuntu Hardy uses 258, Karmic uses 261, and the Padl current release is 265.
The ldap-nss.c do_init() may be called more then once, to initialize an ldap session and save the session in in __session.ls_conn and set the __session.ls_stat = LD_INITIALIZED But it does not check the state to see if has be initialized, and at line 1239: __session.ls_conn = NULL;
The attached patch to to the libnss-ldap_261-2.1Ubuntu4 fixes the problem, by testing __session.ls_stat == LD_INITIALIZED
The ldap-nss.c also has a patch to call do_close twice that I had previously turned it to Padl and is now in 265.
For testing purposes, the patch also adds atexit(do_atexit); and a do_atexit routine to call do_close. This will then cause the last session to be be freed. This make it much easier to use valgrind to check for memory leaks. (in the nscd.c in lib6c the _exit was change to exit so the atexit would be called.)
Debug versions of nscd and libnss-ldap where created, and and used with valgrind to track down the memory leaks. Attached is a script used with valgrind. The LD_PRELOAD was needed so dynamic libs would not be unloaded, and valgrind could find the symbol tables.
--
Douglas E. Engert <DEEngert [at] anl.gov> Argonne National Laboratory 9700 South Cass Avenue Argonne, Illinois 60439 (630) 252-5444
--- libc6/eglibc-2.10.1/nscd/,nscd.c 2009-07-29 11:29:54.000000000 -0500 +++ libc6/eglibc-2.10.1/nscd/nscd.c 2010-03-15 15:02:53.429225933 -0500 @@ -491,7 +491,9 @@ msync (dbs[cnt].head, dbs[cnt].memsize, MS_ASYNC); }
- _exit (EXIT_SUCCESS); +/* for testing to let libnss-ldap cleanup, we use exit */ + exit (EXIT_SUCCESS); +// _exit (EXIT_SUCCESS); }
/* Returns 1 if the process in pid file FILE is running, 0 if not. */
--- libnss-ldap/libnss-ldap-261/build-tree/nss_ldap-261/,ldap-nss.c 2010-03-15 10:04:47.593727549 -0500 +++ libnss-ldap/libnss-ldap-261/build-tree/nss_ldap-261/ldap-nss.c 2010-03-17 16:04:16.165226755 -0500 @@ -184,6 +184,7 @@ static void do_atfork_setup (void); #endif
+static void do_atexit (void); /* allow exit to cleanup to help valgrind */ /* * Close the global session, sending an unbind. */ @@ -553,11 +554,25 @@ (void) __libc_atfork (do_atfork_prepare, do_atfork_parent, do_atfork_child); #endif
+atexit(do_atexit); /* allow exit to cleanup to help valgrind */ + debug ("<== do_atfork_setup"); } #endif
/* + * allow exit to cleanup to help valgrind + */ +void +do_atexit (void) +{ + debug ("<== do_atexit"); + _nss_ldap_enter(); + do_close(); + debug ("==> do_atexit (should be no more activity)"); +} + +/* * Acquires global lock, blocks SIGPIPE. */ void @@ -1107,6 +1122,7 @@
debug ("==> do_init");
+ if (_nss_ldap_validateconfig (__config) != NSS_SUCCESS) { do_close (); @@ -1236,9 +1252,9 @@ } }
- __session.ls_conn = NULL; +/* LOOKS LIKE A PROBLEM. COULD BE INITIALIZED, BUT NOT CONNECTED */ + if (__session.ls_state == LS_UNINITIALIZED) { __session.ls_timestamp = 0; - __session.ls_state = LS_UNINITIALIZED;
#if defined(HAVE_PTHREAD_ONCE) && defined(HAVE_PTHREAD_ATFORK) if (pthread_once (&__once, do_atfork_setup) != 0) @@ -1357,6 +1373,10 @@ __session.ls_state = LS_INITIALIZED;
debug ("<== do_init (initialized session)"); + } /* if already initialized but not connected */ + else { + debug ("<== do_init (already initialized)"); + }
return NSS_SUCCESS; } @@ -1577,6 +1597,7 @@ } else { + syslog(LOG_ERR, "nss-ldap: do_open: do_start_tls failed:stat=%d", stat); do_close (); debug ("<== do_open (TLS startup failed)"); return stat; @@ -2472,6 +2493,7 @@ #endif /* LDAP_OPT_ERROR_NUMBER */ syslog (LOG_AUTHPRIV | LOG_ERR, "nss_ldap: could not get LDAP result - %s", ldap_err2string (rc)); + do_close(); stat = NSS_UNAVAIL; break; case LDAP_RES_SEARCH_ENTRY: @@ -2507,6 +2529,7 @@ syslog (LOG_AUTHPRIV | LOG_ERR, "nss_ldap: could not get LDAP result - %s", ldap_err2string (rc)); + do_close(); } else if (resultControls != NULL) {
# #remove this# !/bin/bash # Above line was modified to would make it via e-mail filters # that wont allow schee scripts # # my options #
LOG=/tmp/valgrind.nscd.exit.$$ echo log=$LOG LOG2=/tmp/valgrind.nscd.exit.stderr.$$
export LD_LIBRARY_PATH=/usr/lib/debug/lib
LD_PRELOAD=/lib/libnss_ldap-2.10.1.so:/lib/tls/i686/cmov/libnss_compat-2.10.1.so:/lib/tls/i686/cmov/libnss_files-2.10.1.so:/lib/tls/i686/cmov/libnss_dns-2.10.1.so \ /usr/bin/valgrind -v --log-file=$LOG \ --leak-check=full --leak-resolution=high \ --show-reachable=yes \ --num-callers=40 --track-origins=yes\ /home/rootdee/source/libc6/eglibc-2.10.1/build-tree/i386-libc/nscd/nscd\ 2> $LOG2
|