diff options
Diffstat (limited to 'nscd')
-rw-r--r-- | nscd/connections.c | 69 | ||||
-rw-r--r-- | nscd/nscd.c | 4 | ||||
-rw-r--r-- | nscd/nscd.h | 1 | ||||
-rw-r--r-- | nscd/nscd_getai.c | 16 | ||||
-rw-r--r-- | nscd/nscd_gethst_r.c | 15 |
5 files changed, 80 insertions, 25 deletions
diff --git a/nscd/connections.c b/nscd/connections.c index e3a67386d0..dd934c1106 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -109,6 +109,7 @@ struct database_dyn dbs[lastdb] = [pwddb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -129,6 +130,7 @@ struct database_dyn dbs[lastdb] = [grpdb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -149,6 +151,7 @@ struct database_dyn dbs[lastdb] = [hstdb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -169,6 +172,7 @@ struct database_dyn dbs[lastdb] = [servdb] = { .lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP, .prune_lock = PTHREAD_MUTEX_INITIALIZER, + .prune_run_lock = PTHREAD_MUTEX_INITIALIZER, .enabled = 0, .check_file = 1, .persistent = 0, @@ -238,8 +242,9 @@ static int resolv_conf_descr = -1; /* Negative if SOCK_CLOEXEC is not supported, positive if it is, zero before be know the result. */ static int have_sock_cloexec; -/* The paccept syscall was introduced at the same time as SOCK_CLOEXEC. */ -# define have_paccept -1 // XXX For the time being there is no such call +#endif +#ifndef __ASSUME_ACCEPT4 +static int have_accept4; #endif /* Number of times clients had to wait. */ @@ -975,9 +980,9 @@ invalidate_cache (char *key, int fd) if (dbs[number].enabled) { - pthread_mutex_lock (&dbs[number].prune_lock); + pthread_mutex_lock (&dbs[number].prune_run_lock); prune_cache (&dbs[number], LONG_MAX, fd); - pthread_mutex_unlock (&dbs[number].prune_lock); + pthread_mutex_unlock (&dbs[number].prune_run_lock); } else { @@ -1492,6 +1497,7 @@ nscd_run_prune (void *p) dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number; pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock; + pthread_mutex_t *prune_run_lock = &dbs[my_number].prune_run_lock; pthread_cond_t *prune_cond = &dbs[my_number].prune_cond; pthread_mutex_lock (prune_lock); @@ -1525,7 +1531,12 @@ nscd_run_prune (void *p) pthread_mutex_unlock (prune_lock); + /* We use a separate lock for running the prune function (instead + of keeping prune_lock locked) because this enables concurrent + invocations of cache_add which might modify the timeout value. */ + pthread_mutex_lock (prune_run_lock); next_wait = prune_cache (&dbs[my_number], prune_now, -1); + pthread_mutex_unlock (prune_run_lock); next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL); /* If clients cannot determine for sure whether nscd is running @@ -1609,8 +1620,8 @@ nscd_run_worker (void *p) /* We are done with the list. */ pthread_mutex_unlock (&readylist_lock); -#ifndef __ASSUME_SOCK_CLOEXEC - if (have_sock_cloexec < 0) +#ifndef __ASSUME_ACCEPT4 + if (have_accept4 < 0) { /* We do not want to block on a short read or so. */ int fl = fcntl (fd, F_GETFL); @@ -1819,22 +1830,20 @@ main_loop_poll (void) /* We have a new incoming connection. Accept the connection. */ int fd; -#ifndef __ASSUME_PACCEPT +#ifndef __ASSUME_ACCEPT4 fd = -1; - if (have_paccept >= 0) + if (have_accept4 >= 0) #endif { -#if 0 - fd = TEMP_FAILURE_RETRY (paccept (sock, NULL, NULL, NULL, + fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL, SOCK_NONBLOCK)); -#ifndef __ASSUME_PACCEPT - if (have_paccept == 0) - have_paccept = fd != -1 || errno != ENOSYS ? 1 : -1; -#endif +#ifndef __ASSUME_ACCEPT4 + if (have_accept4 == 0) + have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1; #endif } -#ifndef __ASSUME_PACCEPT - if (have_paccept < 0) +#ifndef __ASSUME_ACCEPT4 + if (have_accept4 < 0) fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL)); #endif @@ -2000,7 +2009,7 @@ main_loop_epoll (int efd) /* We cannot use epoll. */ return; -#ifdef HAVE_INOTIFY +# ifdef HAVE_INOTIFY if (inotify_fd != -1) { ev.events = EPOLLRDNORM; @@ -2010,7 +2019,7 @@ main_loop_epoll (int efd) return; nused = 2; } -#endif +# endif while (1) { @@ -2025,8 +2034,26 @@ main_loop_epoll (int efd) if (revs[cnt].data.fd == sock) { /* A new connection. */ - int fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL)); + int fd; + +# ifndef __ASSUME_ACCEPT4 + fd = -1; + if (have_accept4 >= 0) +# endif + { + fd = TEMP_FAILURE_RETRY (accept4 (sock, NULL, NULL, + SOCK_NONBLOCK)); +# ifndef __ASSUME_ACCEPT4 + if (have_accept4 == 0) + have_accept4 = fd != -1 || errno != ENOSYS ? 1 : -1; +# endif + } +# ifndef __ASSUME_ACCEPT4 + if (have_accept4 < 0) + fd = TEMP_FAILURE_RETRY (accept (sock, NULL, NULL)); +# endif + /* Use the descriptor if we have not reached the limit. */ if (fd >= 0) { /* Try to add the new descriptor. */ @@ -2048,7 +2075,7 @@ main_loop_epoll (int efd) } } } -#ifdef HAVE_INOTIFY +# ifdef HAVE_INOTIFY else if (revs[cnt].data.fd == inotify_fd) { bool to_clear[lastdb] = { false, }; @@ -2104,7 +2131,7 @@ main_loop_epoll (int efd) pthread_cond_signal (&dbs[dbcnt].prune_cond); } } -#endif +# endif else { /* Remove the descriptor from the epoll descriptor. */ diff --git a/nscd/nscd.c b/nscd/nscd.c index aa1490936c..08bf1f1260 100644 --- a/nscd/nscd.c +++ b/nscd/nscd.c @@ -1,4 +1,4 @@ -/* Copyright (c) 1998-2006, 2007, 2008 Free Software Foundation, Inc. +/* Copyright (c) 1998-2008, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998. @@ -407,7 +407,7 @@ print_version (FILE *stream, struct argp_state *state) Copyright (C) %s Free Software Foundation, Inc.\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ -"), "2008"); +"), "2009"); fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk and Ulrich Drepper"); } diff --git a/nscd/nscd.h b/nscd/nscd.h index 5c77dd3c41..2d77bab989 100644 --- a/nscd/nscd.h +++ b/nscd/nscd.h @@ -69,6 +69,7 @@ struct database_dyn pthread_rwlock_t lock; pthread_cond_t prune_cond; pthread_mutex_t prune_lock; + pthread_mutex_t prune_run_lock; time_t wakeup_time; int enabled; diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c index 56f963776e..674a5e7514 100644 --- a/nscd/nscd_getai.c +++ b/nscd/nscd_getai.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. @@ -36,10 +36,24 @@ extern int __nss_not_use_nscd_hosts; /* We use the mapping from nscd_gethst. */ libc_locked_map_ptr (extern, __hst_map_handle) attribute_hidden; +/* Defined in nscd_gethst_r.c. */ +extern int __nss_have_localdomain attribute_hidden; + int __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop) { + if (__builtin_expect (__nss_have_localdomain >= 0, 0)) + { + if (__nss_have_localdomain == 0) + __nss_have_localdomain = getenv ("LOCALDOMAIN") != NULL ? 1 : -1; + if (__nss_have_localdomain > 0) + { + __nss_not_use_nscd_hosts = 1; + return -1; + } + } + size_t keylen = strlen (key) + 1; int gc_cycle; int nretries = 0; diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c index a211404756..aea8288594 100644 --- a/nscd/nscd_gethst_r.c +++ b/nscd/nscd_gethst_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2005, 2006, 2007 Free Software Foundation, Inc. +/* Copyright (C) 1998-2005, 2006, 2007, 2008 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998. @@ -97,12 +97,25 @@ libc_freeres_fn (hst_map_free) } +int __nss_have_localdomain attribute_hidden; + static int internal_function nscd_gethst_r (const char *key, size_t keylen, request_type type, struct hostent *resultbuf, char *buffer, size_t buflen, struct hostent **result, int *h_errnop) { + if (__builtin_expect (__nss_have_localdomain >= 0, 0)) + { + if (__nss_have_localdomain == 0) + __nss_have_localdomain = getenv ("LOCALDOMAIN") != NULL ? 1 : -1; + if (__nss_have_localdomain > 0) + { + __nss_not_use_nscd_hosts = 1; + return -1; + } + } + int gc_cycle; int nretries = 0; |