From owner-freebsd-current@FreeBSD.ORG Mon Mar 29 18:32:49 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 211B816A4CE for ; Mon, 29 Mar 2004 18:32:49 -0800 (PST) Received: from gw.celabo.org (gw.celabo.org [208.42.49.153]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8608743D2D for ; Mon, 29 Mar 2004 18:32:48 -0800 (PST) (envelope-from nectar@celabo.org) Received: from madman.celabo.org (madman.celabo.org [10.0.1.111]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "madman.celabo.org", Issuer "celabo.org CA" (not verified)) by gw.celabo.org (Postfix) with ESMTP id 16A0054840; Mon, 29 Mar 2004 20:32:48 -0600 (CST) Received: by madman.celabo.org (Postfix, from userid 1001) id A22CE6D465; Mon, 29 Mar 2004 20:32:47 -0600 (CST) Date: Mon, 29 Mar 2004 20:32:47 -0600 From: "Jacques A. Vidrine" To: Daniel Eischen Message-ID: <20040330023247.GA5637@madman.celabo.org> Mail-Followup-To: "Jacques A. Vidrine" , Daniel Eischen , Sean McNeil , freebsd-current@freebsd.org References: <1080334840.11426.12.camel@server.mcneil.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Url: http://www.celabo.org/ User-Agent: Mutt/1.5.6i cc: freebsd-current@freebsd.org cc: Sean McNeil Subject: Re: nss_ldap broken X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Mar 2004 02:32:49 -0000 On Fri, Mar 26, 2004 at 05:51:02PM -0500, Daniel Eischen wrote: > I think I made a comment about how you should always > prefix _pthread_foo() calls with 'if (__isthreaded)'. Yes, I'm sure you did. My recollection was that it was an optimization only, but it seems either I misunderstood or my recollection is poor (or both) :-) > When the thread libraries are initialized, then overrwrite > the function pointers in libc's thread jumptable. If you > unload the library, libc still retains those pointers. OK, so we guard calls to threading routines with __isthreaded. (Patch below.) Uglifies things a bit, but I can deal. Maybe some day we'll rewrite reentrant.h so that it doesn't lose the return code (they should all be like mutex_trylock?). So, if I understand correctly: (1) __isthreaded starts out 0 (2) When a threading library is loaded (by any cause? DT_NEEDED? dlopen RTLD_GLOBAL? dlopen RTLD_LOCAL?), __isthreaded is set to 1 (3) When a threading library is unloaded, __isthreaded is reset to 0 Only, I don't immediately see where (3) happens... Sean, could you report how this patch works for you? Hmm, actually, it looks almost identical to what you posted :-) Is there a reason that you stored the value of `__isthreaded' in a local variable? Did that make a difference for your case? Cheers, -- Jacques Vidrine / nectar@celabo.org / jvidrine@verio.net / nectar@freebsd.org Index: net/nsdispatch.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/nsdispatch.c,v retrieving revision 1.10 diff -c -r1.10 nsdispatch.c *** net/nsdispatch.c 15 Mar 2004 08:14:35 -0000 1.10 --- net/nsdispatch.c 30 Mar 2004 02:19:19 -0000 *************** *** 319,324 **** --- 319,325 ---- int result; const char *path; + result = 0; #if defined(_NSS_DEBUG) && defined(_NSS_SHOOT_FOOT) /* NOTE WELL: THIS IS A SECURITY HOLE. This must only be built * for debugging purposes and MUST NEVER be used in production. *************** *** 331,346 **** return (0); if (statbuf.st_mtime <= confmod) return (0); ! result = _pthread_mutex_trylock(&conf_lock); ! if (result != 0) ! return (0); ! (void)_pthread_rwlock_unlock(&nss_lock); ! result = _pthread_rwlock_wrlock(&nss_lock); ! if (result != 0) ! goto fin2; _nsyyin = fopen(path, "r"); ! if (_nsyyin == NULL) goto fin; VECTOR_FREE(_nsmap, &_nsmapsize, sizeof(*_nsmap), (vector_free_elem)ns_dbt_free); VECTOR_FREE(_nsmod, &_nsmodsize, sizeof(*_nsmod), --- 332,351 ---- return (0); if (statbuf.st_mtime <= confmod) return (0); ! if (__isthreaded) { ! result = _pthread_mutex_trylock(&conf_lock); ! if (result != 0) ! return (0); ! (void)_pthread_rwlock_unlock(&nss_lock); ! result = _pthread_rwlock_wrlock(&nss_lock); ! if (result != 0) ! goto fin2; ! } _nsyyin = fopen(path, "r"); ! if (_nsyyin == NULL) { ! result = errno; goto fin; + } VECTOR_FREE(_nsmap, &_nsmapsize, sizeof(*_nsmap), (vector_free_elem)ns_dbt_free); VECTOR_FREE(_nsmod, &_nsmodsize, sizeof(*_nsmod), *************** *** 353,362 **** (void)atexit(nss_atexit); confmod = statbuf.st_mtime; fin: ! (void)_pthread_rwlock_unlock(&nss_lock); ! result = _pthread_rwlock_rdlock(&nss_lock); fin2: ! (void)_pthread_mutex_unlock(&conf_lock); return (result); } --- 358,371 ---- (void)atexit(nss_atexit); confmod = statbuf.st_mtime; fin: ! if (__isthreaded) { ! (void)_pthread_rwlock_unlock(&nss_lock); ! if (result == 0) ! result = _pthread_rwlock_rdlock(&nss_lock); ! } fin2: ! if (__isthreaded) ! (void)_pthread_mutex_unlock(&conf_lock); return (result); } *************** *** 510,521 **** static void nss_atexit(void) { ! (void)_pthread_rwlock_wrlock(&nss_lock); VECTOR_FREE(_nsmap, &_nsmapsize, sizeof(*_nsmap), (vector_free_elem)ns_dbt_free); VECTOR_FREE(_nsmod, &_nsmodsize, sizeof(*_nsmod), (vector_free_elem)ns_mod_free); ! (void)_pthread_rwlock_unlock(&nss_lock); } --- 519,532 ---- static void nss_atexit(void) { ! if (__isthreaded) ! (void)_pthread_rwlock_wrlock(&nss_lock); VECTOR_FREE(_nsmap, &_nsmapsize, sizeof(*_nsmap), (vector_free_elem)ns_dbt_free); VECTOR_FREE(_nsmod, &_nsmodsize, sizeof(*_nsmod), (vector_free_elem)ns_mod_free); ! if (__isthreaded) ! (void)_pthread_rwlock_unlock(&nss_lock); } *************** *** 571,580 **** int serrno, i, result, srclistsize; serrno = errno; ! result = _pthread_rwlock_rdlock(&nss_lock); ! if (result != 0) { ! result = NS_UNAVAIL; ! goto fin; } result = nss_configure(); if (result != 0) { --- 582,593 ---- int serrno, i, result, srclistsize; serrno = errno; ! if (__isthreaded) { ! result = _pthread_rwlock_rdlock(&nss_lock); ! if (result != 0) { ! result = NS_UNAVAIL; ! goto fin; ! } } result = nss_configure(); if (result != 0) { *************** *** 604,610 **** break; } } ! (void)_pthread_rwlock_unlock(&nss_lock); fin: errno = serrno; return (result); --- 617,624 ---- break; } } ! if (__isthreaded) ! (void)_pthread_rwlock_unlock(&nss_lock); fin: errno = serrno; return (result); Index: net/nss_compat.c =================================================================== RCS file: /home/ncvs/src/lib/libc/net/nss_compat.c,v retrieving revision 1.2 diff -c -r1.2 nss_compat.c *** net/nss_compat.c 9 Jan 2004 13:43:49 -0000 1.2 --- net/nss_compat.c 30 Mar 2004 02:16:03 -0000 *************** *** 41,46 **** --- 41,47 ---- #include #include #include "un-namespace.h" + #include "libc_private.h" struct group; *************** *** 60,66 **** #define SET_TERMINATOR(x, y) \ do { \ ! if (_pthread_main_np()) \ _term_main_##x = (y); \ else { \ (void)_pthread_once(&_term_once_##x, _term_create_##x); \ --- 61,67 ---- #define SET_TERMINATOR(x, y) \ do { \ ! if (!__isthreaded || _pthread_main_np()) \ _term_main_##x = (y); \ else { \ (void)_pthread_once(&_term_once_##x, _term_create_##x); \ *************** *** 69,75 **** } while (0) #define CHECK_TERMINATOR(x) \ ! (_pthread_main_np() ? \ (_term_main_##x) : \ ((void)_pthread_once(&_term_once_##x, _term_create_##x), \ _pthread_getspecific(_term_key_##x))) --- 70,76 ---- } while (0) #define CHECK_TERMINATOR(x) \ ! (!__isthreaded || _pthread_main_np() ? \ (_term_main_##x) : \ ((void)_pthread_once(&_term_once_##x, _term_create_##x), \ _pthread_getspecific(_term_key_##x)))