Eliminate conf_lock and instead rely on the NSS write lock to protect
NSS configuration state. As a side effect, this fixes a race condition which can occur if multiple threads call nsdispatch(3) concurrently before nsswitch.conf has been parsed. Previously, the thread holding conf_lock could cause other threads to return from nss_configure() before nsswitch.conf had been parsed, forcing them to fall back to the default sources for their NSS methods. Reviewed by: jhb Differential Revision: https://reviews.freebsd.org/D994 MFC after: 1 month Sponsored by: EMC / Isilon Storage Division
This commit is contained in:
parent
53e1ffbbce
commit
f53b045631
@ -329,7 +329,6 @@ _nsdbtdump(const ns_dbt *dbt)
|
||||
static int
|
||||
nss_configure(void)
|
||||
{
|
||||
static pthread_mutex_t conf_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static time_t confmod;
|
||||
struct stat statbuf;
|
||||
int result, isthreaded;
|
||||
@ -353,13 +352,14 @@ nss_configure(void)
|
||||
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;
|
||||
return (result);
|
||||
if (stat(path, &statbuf) != 0)
|
||||
goto fin;
|
||||
if (statbuf.st_mtime <= confmod)
|
||||
goto fin;
|
||||
}
|
||||
_nsyyin = fopen(path, "re");
|
||||
if (_nsyyin == NULL)
|
||||
@ -390,9 +390,6 @@ fin:
|
||||
if (result == 0)
|
||||
result = _pthread_rwlock_rdlock(&nss_lock);
|
||||
}
|
||||
fin2:
|
||||
if (isthreaded)
|
||||
(void)_pthread_mutex_unlock(&conf_lock);
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user