diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | nscd/connections.c | 55 | ||||
-rw-r--r-- | nscd/grpcache.c | 11 |
3 files changed, 50 insertions, 25 deletions
@@ -1,3 +1,12 @@ +2004-08-25 Ulrich Drepper <drepper@redhat.com> + + * nscd/connections.c: Make socket nonblocking so that threads + don't get stuck on accept. Fix locking. + + * nscd/grpcache.c (cache_addgr): Use cope of original key in hash + entry with alternative key. + * nscd/pwdcache.c (cache_addpw): Likewise. + 2004-08-25 Richard Sandiford <rsandifo@redhat.com> * sysdeps/mips/dl-machine.h (_dl_start_user): Don't set diff --git a/nscd/connections.c b/nscd/connections.c index f8efcc26ee..0018ed9ec7 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -22,6 +22,7 @@ #include <atomic.h> #include <error.h> #include <errno.h> +#include <fcntl.h> #include <grp.h> #include <pthread.h> #include <pwd.h> @@ -207,6 +208,12 @@ nscd_init (void) exit (1); } + /* We don't wait for data otherwise races between threads can get + them stuck on accept. */ + int fl = fcntl (sock, F_GETFL); + if (fl != -1) + fcntl (sock, F_SETFL, fl | O_NONBLOCK); + /* Set permissions for the socket. */ chmod (_PATH_NSCDSOCKET, 0666); @@ -451,32 +458,37 @@ nscd_run (void *p) while (1) { int nr; + time_t now = 0; /* One more thread available. */ atomic_increment (&nready); no_conn: - if (run_prune) - do - { - time_t now = time (NULL); - int timeout = now < next_prune ? 1000 * (next_prune - now) : 0; + do + { + int timeout = -1; + if (run_prune) + { + now = time (NULL); + timeout = now < next_prune ? 1000 * (next_prune - now) : 0; + } - nr = poll (&conn, 1, timeout); + nr = poll (&conn, 1, timeout); - if (nr == 0) - { - /* The `poll' call timed out. It's time to clean up the - cache. */ - atomic_decrement (&nready); - assert (my_number < lastdb); - prune_cache (&dbs[my_number], time(NULL)); - now = time (NULL); - next_prune = now + CACHE_PRUNE_INTERVAL; - goto try_get; - } - } - while ((conn.revents & POLLRDNORM) == 0); + if (nr == 0) + { + /* The `poll' call timed out. It's time to clean up the + cache. */ + atomic_decrement (&nready); + assert (my_number < lastdb); + prune_cache (&dbs[my_number], time(NULL)); + now = time (NULL); + next_prune = now + CACHE_PRUNE_INTERVAL; + atomic_increment (&nready); + goto try_get; + } + } + while ((conn.revents & POLLRDNORM) == 0); got_data:; /* We have a new incoming connection. Accept the connection. */ @@ -490,8 +502,9 @@ nscd_run (void *p) if (__builtin_expect (fd, 0) < 0) { - dbg_log (_("while accepting connection: %s"), - strerror_r (errno, buf, sizeof (buf))); + if (errno != EAGAIN && errno != EWOULDBLOCK) + dbg_log (_("while accepting connection: %s"), + strerror_r (errno, buf, sizeof (buf))); goto no_conn; } diff --git a/nscd/grpcache.c b/nscd/grpcache.c index 2ad6251762..8f5238fe75 100644 --- a/nscd/grpcache.c +++ b/nscd/grpcache.c @@ -140,7 +140,7 @@ cache_addgr (struct database *db, int fd, request_header *req, void *key, total = (sizeof (struct groupdata) + gr_mem_cnt * sizeof (uint32_t) + gr_name_len + gr_passwd_len + gr_mem_len_total); - data = (struct groupdata *) malloc (total + n); + data = (struct groupdata *) malloc (total + n + req->key_len); if (data == NULL) /* There is no reason to go on. */ error (EXIT_FAILURE, errno, _("while allocating cache entry")); @@ -163,9 +163,12 @@ cache_addgr (struct database *db, int fd, request_header *req, void *key, for (cnt = 0; cnt < gr_mem_cnt; ++cnt) cp = mempcpy (cp, grp->gr_mem[cnt], gr_mem_len[cnt]); - /* Finally the stringified GID value. */ + /* Next the stringified GID value. */ memcpy (cp, buf, n); + /* Copy of the key in case it differs. */ + char *key_copy = memcpy (cp + n, key, req->key_len); + /* Write the result. */ written = TEMP_FAILURE_RETRY (write (fd, &data->resp, total)); @@ -180,8 +183,8 @@ cache_addgr (struct database *db, int fd, request_header *req, void *key, total, data, 0, t, db, owner); /* If the key is different from the name add a separate entry. */ - if (type == GETGRBYNAME && strcmp (key, gr_name) != 0) - cache_add (GETGRBYNAME, key, strlen (key) + 1, data, + if (type == GETGRBYNAME && strcmp (key_copy, gr_name) != 0) + cache_add (GETGRBYNAME, key_copy, req->key_len, data, total, data, 0, t, db, owner); cache_add (GETGRBYGID, cp, n, data, total, data, 1, t, db, owner); |