Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > media > main-testing-src > by-pkgid > 097a12bbe051ea2436c51f094f5d588b > files > 48

glibc-2.8-1.20080520.5.3mnb2.src.rpm

 2008-06-12  Ulrich Drepper  <drepper@redhat.com>

	* nscd/grpcache.c (cache_addgr): Correctly compute size of
	fixed-size portion of the record.
	* nscd/servicescache.c (cache_addserv): Likewise.
	* nscd/pwdcache.c (cache_addpw): Likewise.
	* nscd/initgrcache.c (addinitgroupsX): Likewise.

 2008-06-11  Ulrich Drepper  <drepper@redhat.com>

	* nscd/mem.c (gc): Initialize obstack earlier so that if we jump
	out we don't use uninitialized memory.

	* nscd/hstcache.c (cache_addhst): Send correct number of bytes to
	the client.

 2008-06-03  Jakub Jelinek  <jakub@redhat.com>

	* nscd/nscd_getserv_r.c (__nscd_getservbyport_r): Pass cp
	instead of portstr to nscd_getserv_r.  Patch by
	Roman Kagan <rkagan@mail.ru>.

 2008-05-18  Ulrich Drepper  <drepper@redhat.com>

	* nscd/cache.c (cache_add): Take additional parameter specifying
	whether this is in response of a cache refill.  Check alignment
	of package data.  Revamp waking of pruning thread.
	(prune_cache): Small optimization.
	* nscd/nscd.h: Adjust cache_add prototypes.
	* nscd/aicache.c: Adjust cache_add calls.
	* nscd/grpcache.c: Likewise.
	* nscd/hstcache.c: Likewise.
	* nscd/initgrcache.c: Likewise.
	* nscd/pwdcache.c: Likewise.
	* nscd/servicescache.c: Likewise.
	* nscd/connections.c (restart): Really disable cache use before
	exec attempt.  If it fails, reenable cache.
	(nscd_run_prune): Initialize wakeup_time.  After wakeup, set wakeup
	time to max to be able to notice concurrent cache additions.  Unlock
	prune_lock while performing gc.  Afterwards compute wakeup time with
	current wakeup_time value in mind.

 2008-05-17  Ulrich Drepper  <drepper@redhat.com>

	* nscd/mem.c (gc): Avoid stack overflow when allocating move list.

	* nscd/mem.c (gc): Correctly determine highest used array element
	in mark.

	* nscd/mem.c (markrange): Add assert to check entries are all
	aligned.  Small cleanup in bitmap use.

	* nscd/nscd.h (mem_in_flight): Replace blockaddr field with
	blockoff of type nscd_ssize_t.
	* nscd/mem.c (gc): Simplify markrange call for on-flight blocks.
	(mempoll_alloc): Record block offset and not address.

	* nscd/mem.c (gc): Fix test for stack overuse.

 2008-05-10  Ulrich Drepper  <drepper@redhat.com>

	* nscd/cache.c (cache_add): Before returning with failure and this
	is the first use of the record, mark it as unusable.
	* nscd/aicache.c: Don't touch the dataset after cache_add returns
	reporting a failure.
	* nscd/grpcache.c: Likewise
	* nscd/hstcache.c: Likewise.
	* nscd/initgrcache.c: Likewise.
	* nscd/pwdcache.c: Likewise.
	* nscd/servicecache.c: Likewise.

 2008-04-22  Jakub Jelinek  <jakub@redhat.com>

	* nscd/Makefile (nscd-cflags): Set back to -fpie.
	* nscd/nscd.h (mem_in_flight): Add attribute_tls_model_ie.
	* nscd/connections.c (mem_in_flight): Likewise.

	* nscd/nscd.h (dbs): Make hidden.

 2008-04-15  Ulrich Drepper  <drepper@redhat.com>

	[BZ #5381]
	* nscd/nscd.h: Define enum in_flight, mem_in_flight, and
	mem_in_flight_list variables.  Add new parameter to mempool_alloc
	prototype.
	* nscd/mem.c (mempool_alloc): Take additional parameter.  Initialize
	appropriate mem_in_flight element.
	(gc): Take allocations which have not yet been committed to the
	database into account.
	* nscd/cache.c (cache_add): Add new parameter to mempool_alloc call.
	Reset mem_in_flight before returning.
	* nscd/connections.c (nscd_run_worker): Initialize mem_in_flight and
	cue it up in mem_in_flight_list.
	* nscd/aicache.c: Adjust mempool_alloc call.
	* nscd/grpcache.c: Likewise.
	* nscd/hstcache.c: Likewise.
	* nscd/initgrcache.c: Likewise.
	* nscd/pwdcache.c: Likewise.
	* nscd/servicescache.c: Likewise.
	* nscd/Makefile (nscd-flags): Until ld is fixed, use -fpic instead
	of -fpie.

	* nscd/connections.c (handle_request): Provide better error message
	in case SELinux forbids the service.

===================================================================
RCS file: /cvs/glibc/libc/nscd/Makefile,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- libc/nscd/Makefile	2007/10/30 00:45:48	1.54
+++ libc/nscd/Makefile	2008/04/19 16:40:58	1.55
@@ -1,4 +1,4 @@
-# Copyright (C) 1998,2000,2002,2003,2004,2005,2006,2007
+# Copyright (C) 1998,2000,2002,2003,2004,2005,2006,2007,2008
 #	Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
@@ -90,7 +90,8 @@
 
 nscd-cflags = -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2
 ifeq (yesyes,$(have-fpie)$(build-shared))
-nscd-cflags += -fpie
+#nscd-cflags += -fpie
+nscd-cflags += -fpic
 endif
 ifeq (yes,$(have-ssp))
 nscd-cflags += -fstack-protector
===================================================================
RCS file: /cvs/glibc/libc/nscd/nscd.h,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- libc/nscd/nscd.h	2008/03/04 01:53:25	1.33
+++ libc/nscd/nscd.h	2008/04/19 16:41:20	1.34
@@ -181,6 +181,31 @@
 extern gid_t old_gid;
 
 
+/* Memory allocation in flight.  Each thread can have a limited number
+   of allocation in flight.  No need to create dynamic data
+   structures.  We use fixed indices.  */
+enum in_flight
+  {
+    IDX_result_data = 0,
+    /* Keep the IDX_record_data entry last at all times.  */
+    IDX_record_data = 1,
+    IDX_last
+  };
+extern __thread struct mem_in_flight
+{
+  struct
+  {
+    int dbidx;
+    nscd_ssize_t blocklen;
+    void *blockaddr;
+  } block[IDX_last];
+
+  struct mem_in_flight *next;
+} mem_in_flight;
+/* Global list of the mem_in_flight variables of all the threads.  */
+extern struct mem_in_flight *mem_in_flight_list;
+
+
 /* Prototypes for global functions.  */
 
 /* nscd.c */
@@ -271,7 +296,8 @@
 			     struct datahead *dh);
 
 /* mem.c */
-extern void *mempool_alloc (struct database_dyn *db, size_t len);
+extern void *mempool_alloc (struct database_dyn *db, size_t len,
+			    enum in_flight idx);
 extern void gc (struct database_dyn *db);
 
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- libc/nscd/mem.c	2007/11/25 21:07:14	1.12
+++ libc/nscd/mem.c	2008/04/19 16:41:32	1.13
@@ -1,5 +1,5 @@
 /* Cache memory handling.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -197,6 +197,31 @@
     }
   assert (cnt == db->head->nentries);
 
+  /* Go through the list of in-flight memory blocks.  */
+  struct mem_in_flight *mrunp = mem_in_flight_list;
+  while (mrunp != NULL)
+    {
+      /* NB: There can be no race between this test and another thread
+        setting the field to the index we are looking for because
+        this would require the other thread to also have the memlock
+        for the database.
+
+	NB2: we do not have to look at latter blocks (higher indices) if
+	earlier blocks are not in flight.  They are always allocated in
+	sequence.  */
+      for (enum in_flight idx = IDX_result_data;
+	   idx < IDX_last && mrunp->block[idx].dbidx == db - dbs; ++idx)
+	{
+	 assert ((char *) mrunp->block[idx].blockaddr > db->data);
+	 assert ((char *) mrunp->block[idx].blockaddr
+		 + mrunp->block[0].blocklen <= db->data + db->memsize);
+	 markrange (mark, (char *) mrunp->block[idx].blockaddr -  db->data,
+		    mrunp->block[idx].blocklen);
+	}
+
+      mrunp = mrunp->next;
+    }
+
   /* Sort the entries by the addresses of the referenced data.  All
      the entries pointing to the same DATAHEAD object will have the
      same key.  Stability of the sorting is unimportant.  */
@@ -503,7 +528,7 @@
 
 
 void *
-mempool_alloc (struct database_dyn *db, size_t len)
+mempool_alloc (struct database_dyn *db, size_t len, enum in_flight idx)
 {
   /* Make sure LEN is a multiple of our maximum alignment so we can
      keep track of used memory is multiples of this alignment value.  */
@@ -567,6 +592,12 @@
       db->head->first_free += len;
 
       db->last_alloc_failed = false;
+
+      /* Remember that we have allocated this memory.  */
+      assert (idx >= 0 && idx < IDX_last);
+      mem_in_flight.block[idx].dbidx = db - dbs;
+      mem_in_flight.block[idx].blocklen = len;
+      mem_in_flight.block[idx].blockaddr = res;
     }
 
   pthread_mutex_unlock (&db->memlock);
===================================================================
RCS file: /cvs/glibc/libc/nscd/cache.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- libc/nscd/cache.c	2007/11/25 21:47:35	1.35
+++ libc/nscd/cache.c	2008/04/19 16:41:46	1.36
@@ -1,4 +1,4 @@
-/* Copyright (c) 1998, 1999, 2003-2006, 2007 Free Software Foundation, Inc.
+/* Copyright (c) 1998, 1999, 2003-2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -155,11 +155,16 @@
   unsigned long int hash = __nis_hash (key, len) % table->head->module;
   struct hashentry *newp;
 
-  newp = mempool_alloc (table, sizeof (struct hashentry));
+  newp = mempool_alloc (table, sizeof (struct hashentry), IDX_record_data);
   /* If we cannot allocate memory, just do not do anything.  */
   if (newp == NULL)
     {
       ++table->head->addfailed;
+
+      /* Mark the in-flight memory as unused.  */
+      for (enum in_flight idx = 0; idx < IDX_record_data; ++idx)
+	mem_in_flight.block[idx].dbidx = -1;
+
       return -1;
     }
 
@@ -215,6 +220,10 @@
     else
       next_wakeup = table->wakeup_time;
 
+  /* Mark the in-flight memory as unused.  */
+  for (enum in_flight idx = 0; idx < IDX_last; ++idx)
+    mem_in_flight.block[idx].dbidx = -1;
+
   return 0;
 }
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/connections.c,v
retrieving revision 1.109
retrieving revision 1.110
diff -u -r1.109 -r1.110
--- libc/nscd/connections.c	2008/03/04 01:53:50	1.109
+++ libc/nscd/connections.c	2008/04/19 16:42:02	1.110
@@ -225,6 +225,11 @@
 /* Number of times clients had to wait.  */
 unsigned long int client_queued;
 
+/* Data structure for recording in-flight memory allocation.  */
+__thread struct mem_in_flight mem_in_flight;
+/* Global list of the mem_in_flight variables of all the threads.  */
+struct mem_in_flight *mem_in_flight_list;
+
 
 ssize_t
 writeall (int fd, const void *buf, size_t len)
@@ -964,7 +969,7 @@
 
 /* Handle new request.  */
 static void
-handle_request (int fd, request_header *req, void *key, uid_t uid)
+handle_request (int fd, request_header *req, void *key, uid_t uid, pid_t pid)
 {
   if (__builtin_expect (req->version, NSCD_VERSION) != NSCD_VERSION)
     {
@@ -979,7 +984,31 @@
   if (selinux_enabled && nscd_request_avc_has_perm (fd, req->type) != 0)
     {
       if (debug_level > 0)
-	dbg_log (_("request not handled due to missing permission"));
+	{
+#ifdef SO_PEERCRED
+# ifdef PATH_MAX
+	  char buf[PATH_MAX];
+# else
+	  char buf[4096];
+# endif
+
+	  snprintf (buf, sizeof (buf), "/proc/%ld/exe", (long int) pid);
+	  ssize_t n = readlink (buf, buf, sizeof (buf) - 1);
+
+	  if (n <= 0)
+	    dbg_log (_("\
+request from %ld not handled due to missing permission"), (long int) pid);
+	  else
+	    {
+	      buf[n] = '\0';
+	      dbg_log (_("\
+request from '%s' [%ld] not handled due to missing permission"),
+		       buf, (long int) pid);
+	    }
+#else
+	  dbg_log (_("request not handled due to missing permission"));
+#endif
+	}
       return;
     }
 
@@ -1426,6 +1455,16 @@
 {
   char buf[256];
 
+  /* Initialize the memory-in-flight list.  */
+  for (enum in_flight idx = 0; idx < IDX_last; ++idx)
+    mem_in_flight.block[idx].dbidx = -1;
+  /* And queue this threads structure.  */
+  do
+    mem_in_flight.next = mem_in_flight_list;
+  while (atomic_compare_and_exchange_bool_acq (&mem_in_flight_list,
+					       &mem_in_flight,
+					       mem_in_flight.next) != 0);
+
   /* Initial locking.  */
   pthread_mutex_lock (&readylist_lock);
 
@@ -1491,6 +1530,8 @@
 	  if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &caller, &optlen) == 0)
 	    pid = caller.pid;
 	}
+#else
+      const pid_t pid = 0;
 #endif
 
       /* It should not be possible to crash the nscd with a silly
@@ -1531,7 +1572,7 @@
 	    }
 
 	  /* Phew, we got all the data, now process it.  */
-	  handle_request (fd, &req, keybuf, uid);
+	  handle_request (fd, &req, keybuf, uid, pid);
 	}
 
     close_and_out:
===================================================================
RCS file: /cvs/glibc/libc/nscd/servicescache.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- libc/nscd/servicescache.c	2007/11/25 21:26:37	1.5
+++ libc/nscd/servicescache.c	2008/04/19 16:42:32	1.6
@@ -1,5 +1,5 @@
 /* Cache handling for services lookup.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@drepper.com>, 2007.
 
@@ -103,7 +103,8 @@
 	  written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
 					      MSG_NOSIGNAL));
 
-	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
+	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+				   IDX_result_data);
 	  /* If we cannot permanently store the result, so be it.  */
 	  if (dataset != NULL)
 	    {
@@ -190,7 +191,8 @@
       if (he == NULL)
 	{
 	  dataset = (struct dataset *) mempool_alloc (db,
-						      total + req->key_len);
+						      total + req->key_len,
+						      IDX_result_data);
 	  if (dataset == NULL)
 	    ++db->head->addfailed;
 	}
@@ -261,7 +263,8 @@
 	      /* We have to create a new record.  Just allocate
 		 appropriate memory and copy it.  */
 	      struct dataset *newp
-		= (struct dataset *) mempool_alloc (db, total + req->key_len);
+		= (struct dataset *) mempool_alloc (db, total + req->key_len,
+						    IDX_result_data);
 	      if (newp != NULL)
 		{
 		  /* Adjust pointers into the memory block.  */
===================================================================
RCS file: /cvs/glibc/libc/nscd/pwdcache.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- libc/nscd/pwdcache.c	2007/11/25 21:27:50	1.48
+++ libc/nscd/pwdcache.c	2008/04/19 16:42:32	1.49
@@ -1,5 +1,5 @@
 /* Cache handling for passwd lookup.
-   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.
 
@@ -120,7 +120,8 @@
 	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
 						MSG_NOSIGNAL));
 
-	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
+	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+				   IDX_result_data);
 	  /* If we cannot permanently store the result, so be it.  */
 	  if (dataset != NULL)
 	    {
@@ -199,7 +200,8 @@
 
       if (he == NULL)
 	{
-	  dataset = (struct dataset *) mempool_alloc (db, total + n);
+	  dataset = (struct dataset *) mempool_alloc (db, total + n,
+						      IDX_result_data);
 	  if (dataset == NULL)
 	    ++db->head->addfailed;
 	}
@@ -270,7 +272,8 @@
 	      /* We have to create a new record.  Just allocate
 		 appropriate memory and copy it.  */
 	      struct dataset *newp
-		= (struct dataset *) mempool_alloc (db, total + n);
+		= (struct dataset *) mempool_alloc (db, total + n,
+						    IDX_result_data);
 	      if (newp != NULL)
 		{
 		  /* Adjust pointer into the memory block.  */
===================================================================
RCS file: /cvs/glibc/libc/nscd/initgrcache.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- libc/nscd/initgrcache.c	2007/11/25 21:29:04	1.12
+++ libc/nscd/initgrcache.c	2008/04/19 16:42:32	1.13
@@ -1,5 +1,5 @@
 /* Cache handling for host lookup.
-   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
 
@@ -197,7 +197,8 @@
 	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
 						MSG_NOSIGNAL));
 
-	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
+	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+				   IDX_result_data);
 	  /* If we cannot permanently store the result, so be it.  */
 	  if (dataset != NULL)
 	    {
@@ -259,7 +260,8 @@
       if (he == NULL)
 	{
 	  dataset = (struct dataset *) mempool_alloc (db,
-						      total + req->key_len);
+						      total + req->key_len,
+						      IDX_result_data);
 	  if (dataset == NULL)
 	    ++db->head->addfailed;
 	}
@@ -329,7 +331,8 @@
 	      /* We have to create a new record.  Just allocate
 		 appropriate memory and copy it.  */
 	      struct dataset *newp
-		= (struct dataset *) mempool_alloc (db, total + req->key_len);
+		= (struct dataset *) mempool_alloc (db, total + req->key_len,
+						    IDX_result_data);
 	      if (newp != NULL)
 		{
 		  /* Adjust pointer into the memory block.  */
===================================================================
RCS file: /cvs/glibc/libc/nscd/hstcache.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -r1.46 -r1.47
--- libc/nscd/hstcache.c	2007/11/25 21:24:14	1.46
+++ libc/nscd/hstcache.c	2008/04/19 16:42:32	1.47
@@ -1,5 +1,5 @@
 /* Cache handling for host lookup.
-   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.
 
@@ -121,7 +121,8 @@
 	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
 						MSG_NOSIGNAL));
 
-	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
+	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+				   IDX_result_data);
 	  /* If we cannot permanently store the result, so be it.  */
 	  if (dataset != NULL)
 	    {
@@ -226,7 +227,8 @@
       if (he == NULL && h_addr_list_cnt == 1)
 	{
 	  dataset = (struct dataset *) mempool_alloc (db,
-						      total + req->key_len);
+						      total + req->key_len,
+						      IDX_result_data);
 	  if (dataset == NULL)
 	    ++db->head->addfailed;
 	}
@@ -312,7 +314,8 @@
 		     appropriate memory and copy it.  */
 		  struct dataset *newp
 		    = (struct dataset *) mempool_alloc (db,
-							total + req->key_len);
+							total + req->key_len,
+							IDX_result_data);
 		  if (newp != NULL)
 		    {
 		      /* Adjust pointers into the memory block.  */
===================================================================
RCS file: /cvs/glibc/libc/nscd/grpcache.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- libc/nscd/grpcache.c	2007/11/25 21:25:22	1.50
+++ libc/nscd/grpcache.c	2008/04/19 16:42:32	1.51
@@ -1,5 +1,5 @@
 /* Cache handling for group lookup.
-   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.
 
@@ -113,7 +113,8 @@
 	  written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
 					      MSG_NOSIGNAL));
 
-	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
+	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+				   IDX_result_data);
 	  /* If we cannot permanently store the result, so be it.  */
 	  if (dataset != NULL)
 	    {
@@ -204,7 +205,8 @@
 
       if (he == NULL)
 	{
-	  dataset = (struct dataset *) mempool_alloc (db, total + n);
+	  dataset = (struct dataset *) mempool_alloc (db, total + n,
+						      IDX_result_data);
 	  if (dataset == NULL)
 	    ++db->head->addfailed;
 	}
@@ -274,7 +276,8 @@
 	      /* We have to create a new record.  Just allocate
 		 appropriate memory and copy it.  */
 	      struct dataset *newp
-		= (struct dataset *) mempool_alloc (db, total + n);
+		= (struct dataset *) mempool_alloc (db, total + n,
+						    IDX_result_data);
 	      if (newp != NULL)
 		{
 		  /* Adjust pointers into the memory block.  */
===================================================================
RCS file: /cvs/glibc/libc/nscd/aicache.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- libc/nscd/aicache.c	2007/11/25 12:56:35	1.17
+++ libc/nscd/aicache.c	2008/04/19 16:42:32	1.18
@@ -1,5 +1,5 @@
 /* Cache handling for host lookup.
-   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.
 
@@ -262,7 +262,8 @@
 		{
 		  dataset = (struct dataset *) mempool_alloc (db,
 							      total
-							      + req->key_len);
+							      + req->key_len,
+							      IDX_result_data);
 		  if (dataset == NULL)
 		    ++db->head->addfailed;
 		}
@@ -338,7 +339,8 @@
 		      struct dataset *newp
 			= (struct dataset *) mempool_alloc (db,
 							    total
-							    + req->key_len);
+							    + req->key_len,
+							    IDX_result_data);
 		      if (__builtin_expect (newp != NULL, 1))
 			{
 			  /* Adjust pointer into the memory block.  */
@@ -424,7 +426,8 @@
       if (fd != -1)
 	TEMP_FAILURE_RETRY (send (fd, &notfound, total, MSG_NOSIGNAL));
 
-      dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
+      dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+			       IDX_result_data);
       /* If we cannot permanently store the result, so be it.  */
       if (dataset != NULL)
 	{
===================================================================
RCS file: /cvs/glibc/libc/nscd/Makefile,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- libc/nscd/Makefile	2008/04/19 16:40:58	1.55
+++ libc/nscd/Makefile	2008/04/22 15:53:11	1.56
@@ -90,8 +90,7 @@
 
 nscd-cflags = -DIS_IN_nscd=1 -D_FORTIFY_SOURCE=2
 ifeq (yesyes,$(have-fpie)$(build-shared))
-#nscd-cflags += -fpie
-nscd-cflags += -fpic
+nscd-cflags += -fpie
 endif
 ifeq (yes,$(have-ssp))
 nscd-cflags += -fstack-protector
===================================================================
RCS file: /cvs/glibc/libc/nscd/nscd.h,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- libc/nscd/nscd.h	2008/04/19 16:41:20	1.34
+++ libc/nscd/nscd.h	2008/04/22 15:53:29	1.35
@@ -130,7 +130,7 @@
 
 
 /* Global variables.  */
-extern struct database_dyn dbs[lastdb];
+extern struct database_dyn dbs[lastdb] attribute_hidden;
 extern const char *const dbnames[lastdb];
 extern const char *const serv2str[LASTREQ];
 
@@ -201,7 +201,7 @@
   } block[IDX_last];
 
   struct mem_in_flight *next;
-} mem_in_flight;
+} mem_in_flight attribute_tls_model_ie;
 /* Global list of the mem_in_flight variables of all the threads.  */
 extern struct mem_in_flight *mem_in_flight_list;
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/connections.c,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -r1.110 -r1.111
--- libc/nscd/connections.c	2008/04/19 16:42:02	1.110
+++ libc/nscd/connections.c	2008/04/22 15:53:45	1.111
@@ -226,7 +226,7 @@
 unsigned long int client_queued;
 
 /* Data structure for recording in-flight memory allocation.  */
-__thread struct mem_in_flight mem_in_flight;
+__thread struct mem_in_flight mem_in_flight attribute_tls_model_ie;
 /* Global list of the mem_in_flight variables of all the threads.  */
 struct mem_in_flight *mem_in_flight_list;
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/cache.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- libc/nscd/cache.c	2008/04/19 16:41:46	1.36
+++ libc/nscd/cache.c	2008/05/11 03:02:25	1.37
@@ -161,6 +161,11 @@
     {
       ++table->head->addfailed;
 
+      /* If necessary mark the entry as unusable so that lookups will
+	 not use it.  */
+      if (first)
+	packet->usable = false;
+
       /* Mark the in-flight memory as unused.  */
       for (enum in_flight idx = 0; idx < IDX_record_data; ++idx)
 	mem_in_flight.block[idx].dbidx = -1;
===================================================================
RCS file: /cvs/glibc/libc/nscd/servicescache.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- libc/nscd/servicescache.c	2008/04/19 16:42:32	1.6
+++ libc/nscd/servicescache.c	2008/05/11 03:02:54	1.7
@@ -136,10 +136,8 @@
 	      /* Now get the lock to safely insert the records.  */
 	      pthread_rwlock_rdlock (&db->lock);
 
-	      if (cache_add (req->type, &dataset->strdata, req->key_len,
-			     &dataset->head, true, db, owner) < 0)
-		/* Ensure the data can be recovered.  */
-		dataset->head.usable = false;
+	      (void) cache_add (req->type, &dataset->strdata, req->key_len,
+				&dataset->head, true, db, owner);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -332,11 +330,8 @@
 	  /* Now get the lock to safely insert the records.  */
 	  pthread_rwlock_rdlock (&db->lock);
 
-	  if (cache_add (req->type, key_copy, req->key_len,
-			 &dataset->head, true, db, owner) < 0)
-	    /* Could not allocate memory.  Make sure the
-	       data gets discarded.  */
-	    dataset->head.usable = false;
+	  (void) cache_add (req->type, key_copy, req->key_len,
+			    &dataset->head, true, db, owner);
 
 	  pthread_rwlock_unlock (&db->lock);
 	}
===================================================================
RCS file: /cvs/glibc/libc/nscd/pwdcache.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- libc/nscd/pwdcache.c	2008/04/19 16:42:32	1.49
+++ libc/nscd/pwdcache.c	2008/05/11 03:02:54	1.50
@@ -153,11 +153,8 @@
 	      /* Now get the lock to safely insert the records.  */
 	      pthread_rwlock_rdlock (&db->lock);
 
-	      if (cache_add (req->type, key_copy, req->key_len,
-			     &dataset->head, true, db, owner) < 0)
-		/* Ensure the data can be recovered.  */
-		dataset->head.usable = false;
-
+	      (void) cache_add (req->type, key_copy, req->key_len,
+				&dataset->head, true, db, owner);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -352,12 +349,7 @@
 	    {
 	      if (cache_add (GETPWBYUID, cp, key_offset, &dataset->head, true,
 			     db, owner) < 0)
-		{
-		  /* Could not allocate memory.  Make sure the data gets
-		     discarded.  */
-		  dataset->head.usable = false;
-		  goto out;
-		}
+		goto out;
 
 	      first = false;
 	    }
@@ -366,12 +358,7 @@
 	    {
 	      if (cache_add (GETPWBYNAME, key_copy, key_len + 1,
 			     &dataset->head, true, db, owner) < 0)
-		{
-		  /* Could not allocate memory.  Make sure the data gets
-		     discarded.  */
-		  dataset->head.usable = false;
-		  goto out;
-		}
+		goto out;
 
 	      first = false;
 	    }
@@ -384,12 +371,8 @@
 	    {
 	      if (req->type == GETPWBYNAME && db->propagate)
 		(void) cache_add (GETPWBYUID, cp, key_offset, &dataset->head,
-				  req->type != GETPWBYNAME, db, owner);
+				  false, db, owner);
 	    }
-	  else if (first)
-	    /* Could not allocate memory.  Make sure the data gets
-	       discarded.  */
-	    dataset->head.usable = false;
 
 	out:
 	  pthread_rwlock_unlock (&db->lock);
===================================================================
RCS file: /cvs/glibc/libc/nscd/initgrcache.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- libc/nscd/initgrcache.c	2008/04/19 16:42:32	1.13
+++ libc/nscd/initgrcache.c	2008/05/11 03:02:54	1.14
@@ -230,10 +230,8 @@
 	      /* Now get the lock to safely insert the records.  */
 	      pthread_rwlock_rdlock (&db->lock);
 
-	      if (cache_add (req->type, key_copy, req->key_len,
-			     &dataset->head, true, db, uid) < 0)
-		/* Ensure the data can be recovered.  */
-		dataset->head.usable = false;
+	      (void) cache_add (req->type, key_copy, req->key_len,
+				&dataset->head, true, db, uid);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -399,11 +397,8 @@
 	  /* Now get the lock to safely insert the records.  */
 	  pthread_rwlock_rdlock (&db->lock);
 
-	  if (cache_add (INITGROUPS, cp, req->key_len, &dataset->head, true,
-			 db, uid) < 0)
-	    /* Could not allocate memory.  Make sure the data gets
-	       discarded.  */
-	    dataset->head.usable = false;
+	  (void) cache_add (INITGROUPS, cp, req->key_len, &dataset->head, true,
+			    db, uid);
 
 	  pthread_rwlock_unlock (&db->lock);
 	}
===================================================================
RCS file: /cvs/glibc/libc/nscd/hstcache.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -r1.47 -r1.48
--- libc/nscd/hstcache.c	2008/04/19 16:42:32	1.47
+++ libc/nscd/hstcache.c	2008/05/11 03:02:54	1.48
@@ -155,10 +155,8 @@
 	      /* Now get the lock to safely insert the records.  */
 	      pthread_rwlock_rdlock (&db->lock);
 
-	      if (cache_add (req->type, &dataset->strdata, req->key_len,
-			     &dataset->head, true, db, owner) < 0)
-		/* Ensure the data can be recovered.  */
-		dataset->head.usable = false;
+	      (void) cache_add (req->type, &dataset->strdata, req->key_len,
+				&dataset->head, true, db, owner);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -409,11 +407,8 @@
 		  || req->type == GETHOSTBYADDR
 		  || req->type == GETHOSTBYADDRv6);
 
-	  if (cache_add (req->type, key_copy, req->key_len,
-			 &dataset->head, true, db, owner) < 0)
-	    /* Could not allocate memory.  Make sure the
-	       data gets discarded.  */
-	    dataset->head.usable = false;
+	  (void) cache_add (req->type, key_copy, req->key_len,
+			    &dataset->head, true, db, owner);
 
 	  pthread_rwlock_unlock (&db->lock);
 	}
===================================================================
RCS file: /cvs/glibc/libc/nscd/grpcache.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- libc/nscd/grpcache.c	2008/04/19 16:42:32	1.51
+++ libc/nscd/grpcache.c	2008/05/11 03:02:54	1.52
@@ -146,10 +146,8 @@
 	      /* Now get the lock to safely insert the records.  */
 	      pthread_rwlock_rdlock (&db->lock);
 
-	      if (cache_add (req->type, &dataset->strdata, req->key_len,
-			     &dataset->head, true, db, owner) < 0)
-		/* Ensure the data can be recovered.  */
-		dataset->head.usable = false;
+	      (void) cache_add (req->type, &dataset->strdata, req->key_len,
+				&dataset->head, true, db, owner);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -356,12 +354,7 @@
 	    {
 	      if (cache_add (GETGRBYGID, cp, key_offset, &dataset->head, true,
 			     db, owner) < 0)
-		{
-		  /* Could not allocate memory.  Make sure the data gets
-		     discarded.  */
-		  dataset->head.usable = false;
-		  goto out;
-		}
+		goto out;
 
 	      first = false;
 	    }
@@ -370,12 +363,7 @@
 	    {
 	      if (cache_add (GETGRBYNAME, key_copy, key_len + 1,
 			     &dataset->head, true, db, owner) < 0)
-		{
-		  /* Could not allocate memory.  Make sure the data gets
-		     discarded.  */
-		  dataset->head.usable = false;
-		  goto out;
-		}
+		goto out;
 
 	      first = false;
 	    }
@@ -389,12 +377,8 @@
 	    {
 	      if (req->type == GETGRBYNAME && db->propagate)
 		(void) cache_add (GETGRBYGID, cp, key_offset, &dataset->head,
-				  req->type != GETGRBYNAME, db, owner);
+				  false, db, owner);
 	    }
-	  else if (first)
-	    /* Could not allocate memory.  Make sure the data gets
-	       discarded.  */
-	    dataset->head.usable = false;
 
 	out:
 	  pthread_rwlock_unlock (&db->lock);
===================================================================
RCS file: /cvs/glibc/libc/nscd/aicache.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- libc/nscd/aicache.c	2008/05/10 23:23:52	1.19
+++ libc/nscd/aicache.c	2008/05/11 03:02:54	1.20
@@ -556,10 +556,8 @@
       /* Now get the lock to safely insert the records.  */
       pthread_rwlock_rdlock (&db->lock);
 
-      if (cache_add (req->type, key_copy, req->key_len, &dataset->head, true,
-		     db, uid) < 0)
-	/* Ensure the data can be recovered.  */
-	dataset->head.usable = false;
+      (void) cache_add (req->type, key_copy, req->key_len, &dataset->head,
+			true, db, uid);
 
       pthread_rwlock_unlock (&db->lock);
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- libc/nscd/mem.c	2008/04/19 16:41:32	1.13
+++ libc/nscd/mem.c	2008/05/18 02:45:37	1.14
@@ -132,12 +132,12 @@
     stack_used = 0;
   size_t memory_needed = ((db->head->first_free / BLOCK_ALIGN + BITS - 1)
 			  / BITS) * sizeof (BITMAP_T);
-  if (memory_needed <= MAX_STACK_USE)
+  if (stack_used + memory_needed <= MAX_STACK_USE)
     {
       mark = (BITMAP_T *) alloca (memory_needed);
       mark_use_malloc = false;
       memset (mark, '\0', memory_needed);
-      stack_used = memory_needed;
+      stack_used += memory_needed;
     }
   else
     {
===================================================================
RCS file: /cvs/glibc/libc/nscd/nscd.h,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- libc/nscd/nscd.h	2008/04/22 15:53:29	1.35
+++ libc/nscd/nscd.h	2008/05/18 03:55:50	1.36
@@ -197,7 +197,7 @@
   {
     int dbidx;
     nscd_ssize_t blocklen;
-    void *blockaddr;
+    nscd_ssize_t blockoff;
   } block[IDX_last];
 
   struct mem_in_flight *next;
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- libc/nscd/mem.c	2008/05/18 02:45:37	1.14
+++ libc/nscd/mem.c	2008/05/18 03:57:06	1.15
@@ -212,11 +212,12 @@
       for (enum in_flight idx = IDX_result_data;
 	   idx < IDX_last && mrunp->block[idx].dbidx == db - dbs; ++idx)
 	{
-	 assert ((char *) mrunp->block[idx].blockaddr > db->data);
-	 assert ((char *) mrunp->block[idx].blockaddr
-		 + mrunp->block[0].blocklen <= db->data + db->memsize);
-	 markrange (mark, (char *) mrunp->block[idx].blockaddr -  db->data,
-		    mrunp->block[idx].blocklen);
+	  assert (mrunp->block[idx].blockoff >= 0);
+	  assert (mrunp->block[idx].blocklen < db->memsize);
+	  assert (mrunp->block[idx].blockoff
+		  + mrunp->block[0].blocklen <= db->memsize);
+	  markrange (mark, mrunp->block[idx].blockoff,
+		     mrunp->block[idx].blocklen);
 	}
 
       mrunp = mrunp->next;
@@ -589,15 +590,16 @@
     }
   else
     {
-      db->head->first_free += len;
-
-      db->last_alloc_failed = false;
-
       /* Remember that we have allocated this memory.  */
       assert (idx >= 0 && idx < IDX_last);
       mem_in_flight.block[idx].dbidx = db - dbs;
       mem_in_flight.block[idx].blocklen = len;
-      mem_in_flight.block[idx].blockaddr = res;
+      mem_in_flight.block[idx].blockoff = db->head->first_free;
+
+      db->head->first_free += len;
+
+      db->last_alloc_failed = false;
+
     }
 
   pthread_mutex_unlock (&db->memlock);
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- libc/nscd/mem.c	2008/05/18 03:57:06	1.15
+++ libc/nscd/mem.c	2008/05/18 04:16:23	1.16
@@ -79,6 +79,7 @@
 markrange (BITMAP_T *mark, ref_t start, size_t len)
 {
   /* Adjust parameters for block alignment.  */
+  assert ((start & BLOCK_ALIGN_M1) == 0);
   start /= BLOCK_ALIGN;
   len = (len + BLOCK_ALIGN_M1) / BLOCK_ALIGN;
 
@@ -93,7 +94,7 @@
 	  return;
 	}
 
-      mark[elem++] |= 0xff << (start % BITS);
+      mark[elem++] |= ALLBITS << (start % BITS);
       len -= BITS - (start % BITS);
     }
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- libc/nscd/mem.c	2008/05/18 04:16:23	1.16
+++ libc/nscd/mem.c	2008/05/18 04:25:36	1.17
@@ -131,8 +131,8 @@
   size_t stack_used = sizeof (bool) * db->head->module;
   if (__builtin_expect (stack_used > MAX_STACK_USE, 0))
     stack_used = 0;
-  size_t memory_needed = ((db->head->first_free / BLOCK_ALIGN + BITS - 1)
-			  / BITS) * sizeof (BITMAP_T);
+  size_t nmark = (db->head->first_free / BLOCK_ALIGN + BITS - 1) / BITS;
+  size_t memory_needed = nmark * sizeof (BITMAP_T);
   if (stack_used + memory_needed <= MAX_STACK_USE)
     {
       mark = (BITMAP_T *) alloca (memory_needed);
@@ -234,7 +234,7 @@
   qsort (he, cnt, sizeof (struct hashentry *), sort_he);
 
   /* Determine the highest used address.  */
-  size_t high = sizeof (mark);
+  size_t high = nmark;
   while (high > 0 && mark[high - 1] == 0)
     --high;
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- libc/nscd/mem.c	2008/05/18 04:25:36	1.17
+++ libc/nscd/mem.c	2008/05/18 06:28:54	1.18
@@ -24,6 +24,7 @@
 #include <inttypes.h>
 #include <libintl.h>
 #include <limits.h>
+#include <obstack.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -157,6 +158,7 @@
       he = alloca (db->head->nentries * sizeof (struct hashentry *));
       he_data = alloca (db->head->nentries * sizeof (struct hashentry *));
       he_use_malloc = false;
+      stack_used += memory_needed;
     }
   else
     {
@@ -305,6 +307,10 @@
     size_t size;
     struct moveinfo *next;
   } *moves = NULL;
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+  struct obstack ob;
+  obstack_init (&ob);
 
   while (byte < high)
     {
@@ -365,8 +371,14 @@
 	 displacement.  */
       ref_t disp = off_alloc - off_free;
 
-      struct moveinfo *new_move
-	= (struct moveinfo *) alloca (sizeof (*new_move));
+      struct moveinfo *new_move;
+      if (stack_used + sizeof (*new_move) <= MAX_STACK_USE)
+	{
+	  new_move = alloca (sizeof (*new_move));
+	  stack_used += sizeof (*new_move);
+	}
+      else
+	new_move = obstack_alloc (&ob, sizeof (*new_move));
       new_move->from = db->data + off_alloc;
       new_move->to = db->data + off_free;
       new_move->size = off_allocend - off_alloc;
@@ -526,6 +538,8 @@
     free (he);
   if (mark_use_malloc)
     free (mark);
+
+  obstack_free (&ob, NULL);
 }
 
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/cache.c,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -r1.37 -r1.38
--- libc/nscd/cache.c	2008/05/11 03:02:25	1.37
+++ libc/nscd/cache.c	2008/05/18 21:53:38	1.38
@@ -135,7 +135,7 @@
 int
 cache_add (int type, const void *key, size_t len, struct datahead *packet,
 	   bool first, struct database_dyn *table,
-	   uid_t owner)
+	   uid_t owner, bool prune_wakeup)
 {
   if (__builtin_expect (debug_level >= 2, 0))
     {
@@ -180,6 +180,7 @@
   assert (newp->key + newp->len <= table->head->first_free);
   newp->owner = owner;
   newp->packet = (char *) packet - table->data;
+  assert ((newp->packet & BLOCK_ALIGN_M1) == 0);
 
   /* Put the new entry in the first position.  */
   do
@@ -211,19 +212,27 @@
 	   (char *) &table->head->array[hash] - (char *) table->head
 	   + sizeof (ref_t), MS_ASYNC);
 
-  /* Perhaps the prune thread for the data is not running in a long
-     time.  Wake it if necessary.  */
-  time_t next_wakeup = table->wakeup_time;
-  while (next_wakeup + CACHE_PRUNE_INTERVAL > packet->timeout)
-    if (atomic_compare_and_exchange_bool_acq (&table->wakeup_time,
-					      packet->timeout,
-					      next_wakeup) == 0)
-      {
+  /* We do not have to worry about the pruning thread if we are
+     re-adding the data since this is done by the pruning thread.  We
+     also do not have to do anything in case this is not the first
+     time the data is entered since different data heads all have the
+     same timeout.  */
+  if (first && prune_wakeup)
+    {
+      /* Perhaps the prune thread for the table is not running in a long
+	 time.  Wake it if necessary.  */
+      pthread_mutex_lock (&table->prune_lock);
+      time_t next_wakeup = table->wakeup_time;
+      bool do_wakeup = false;
+      if (next_wakeup > packet->timeout + CACHE_PRUNE_INTERVAL)
+	{
+	  table->wakeup_time = packet->timeout;
+	  do_wakeup = true;
+	}
+      pthread_mutex_unlock (&table->prune_lock);
+      if (do_wakeup)
 	pthread_cond_signal (&table->prune_cond);
-	break;
-      }
-    else
-      next_wakeup = table->wakeup_time;
+    }
 
   /* Mark the in-flight memory as unused.  */
   for (enum in_flight idx = 0; idx < IDX_last; ++idx)
@@ -436,7 +445,8 @@
 	      ref_t *old = &table->head->array[first];
 	      ref_t run = table->head->array[first];
 
-	      while (run != ENDREF)
+	      assert (run != ENDREF);
+	      do
 		{
 		  struct hashentry *runp = (struct hashentry *) (data + run);
 		  struct datahead *dh
@@ -462,6 +472,7 @@
 		      run = runp->next;
 		    }
 		}
+	      while (run != ENDREF);
 	    }
 
 	  ++first;
===================================================================
RCS file: /cvs/glibc/libc/nscd/nscd.h,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- libc/nscd/nscd.h	2008/05/18 03:55:50	1.36
+++ libc/nscd/nscd.h	2008/05/18 21:53:48	1.37
@@ -231,7 +231,8 @@
 				      uid_t owner);
 extern int cache_add (int type, const void *key, size_t len,
 		      struct datahead *packet, bool first,
-		      struct database_dyn *table, uid_t owner);
+		      struct database_dyn *table, uid_t owner,
+		      bool prune_wakeup);
 extern time_t prune_cache (struct database_dyn *table, time_t now, int fd);
 
 /* pwdcache.c */
===================================================================
RCS file: /cvs/glibc/libc/nscd/servicescache.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- libc/nscd/servicescache.c	2008/05/11 03:02:54	1.7
+++ libc/nscd/servicescache.c	2008/05/18 21:54:07	1.8
@@ -137,7 +137,7 @@
 	      pthread_rwlock_rdlock (&db->lock);
 
 	      (void) cache_add (req->type, &dataset->strdata, req->key_len,
-				&dataset->head, true, db, owner);
+				&dataset->head, true, db, owner, he == NULL);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -331,7 +331,7 @@
 	  pthread_rwlock_rdlock (&db->lock);
 
 	  (void) cache_add (req->type, key_copy, req->key_len,
-			    &dataset->head, true, db, owner);
+			    &dataset->head, true, db, owner, he == NULL);
 
 	  pthread_rwlock_unlock (&db->lock);
 	}
===================================================================
RCS file: /cvs/glibc/libc/nscd/pwdcache.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -r1.50 -r1.51
--- libc/nscd/pwdcache.c	2008/05/11 03:02:54	1.50
+++ libc/nscd/pwdcache.c	2008/05/18 21:54:07	1.51
@@ -154,7 +154,7 @@
 	      pthread_rwlock_rdlock (&db->lock);
 
 	      (void) cache_add (req->type, key_copy, req->key_len,
-				&dataset->head, true, db, owner);
+				&dataset->head, true, db, owner, he == NULL);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -348,7 +348,7 @@
 	  if (req->type == GETPWBYUID)
 	    {
 	      if (cache_add (GETPWBYUID, cp, key_offset, &dataset->head, true,
-			     db, owner) < 0)
+			     db, owner, he == NULL) < 0)
 		goto out;
 
 	      first = false;
@@ -357,7 +357,7 @@
 	  else if (strcmp (key_copy, dataset->strdata) != 0)
 	    {
 	      if (cache_add (GETPWBYNAME, key_copy, key_len + 1,
-			     &dataset->head, true, db, owner) < 0)
+			     &dataset->head, true, db, owner, he == NULL) < 0)
 		goto out;
 
 	      first = false;
@@ -367,11 +367,12 @@
 	  if ((req->type == GETPWBYNAME || db->propagate)
 	      && __builtin_expect (cache_add (GETPWBYNAME, dataset->strdata,
 					      pw_name_len, &dataset->head,
-					      first, db, owner) == 0, 1))
+					      first, db, owner, he == NULL)
+				   == 0, 1))
 	    {
 	      if (req->type == GETPWBYNAME && db->propagate)
 		(void) cache_add (GETPWBYUID, cp, key_offset, &dataset->head,
-				  false, db, owner);
+				  false, db, owner, false);
 	    }
 
 	out:
===================================================================
RCS file: /cvs/glibc/libc/nscd/initgrcache.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- libc/nscd/initgrcache.c	2008/05/11 03:02:54	1.14
+++ libc/nscd/initgrcache.c	2008/05/18 21:54:07	1.15
@@ -231,7 +231,7 @@
 	      pthread_rwlock_rdlock (&db->lock);
 
 	      (void) cache_add (req->type, key_copy, req->key_len,
-				&dataset->head, true, db, uid);
+				&dataset->head, true, db, uid, he == NULL);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -398,7 +398,7 @@
 	  pthread_rwlock_rdlock (&db->lock);
 
 	  (void) cache_add (INITGROUPS, cp, req->key_len, &dataset->head, true,
-			    db, uid);
+			    db, uid, he == NULL);
 
 	  pthread_rwlock_unlock (&db->lock);
 	}
===================================================================
RCS file: /cvs/glibc/libc/nscd/hstcache.c,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- libc/nscd/hstcache.c	2008/05/11 03:02:54	1.48
+++ libc/nscd/hstcache.c	2008/05/18 21:54:07	1.49
@@ -156,7 +156,7 @@
 	      pthread_rwlock_rdlock (&db->lock);
 
 	      (void) cache_add (req->type, &dataset->strdata, req->key_len,
-				&dataset->head, true, db, owner);
+				&dataset->head, true, db, owner, he == NULL);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -408,7 +408,7 @@
 		  || req->type == GETHOSTBYADDRv6);
 
 	  (void) cache_add (req->type, key_copy, req->key_len,
-			    &dataset->head, true, db, owner);
+			    &dataset->head, true, db, owner, he == NULL);
 
 	  pthread_rwlock_unlock (&db->lock);
 	}
===================================================================
RCS file: /cvs/glibc/libc/nscd/grpcache.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -u -r1.52 -r1.53
--- libc/nscd/grpcache.c	2008/05/11 03:02:54	1.52
+++ libc/nscd/grpcache.c	2008/05/18 21:54:07	1.53
@@ -147,7 +147,7 @@
 	      pthread_rwlock_rdlock (&db->lock);
 
 	      (void) cache_add (req->type, &dataset->strdata, req->key_len,
-				&dataset->head, true, db, owner);
+				&dataset->head, true, db, owner, he == NULL);
 
 	      pthread_rwlock_unlock (&db->lock);
 
@@ -353,7 +353,7 @@
 	  if (req->type == GETGRBYGID)
 	    {
 	      if (cache_add (GETGRBYGID, cp, key_offset, &dataset->head, true,
-			     db, owner) < 0)
+			     db, owner, he == NULL) < 0)
 		goto out;
 
 	      first = false;
@@ -362,7 +362,7 @@
 	  else if (strcmp (key_copy, gr_name) != 0)
 	    {
 	      if (cache_add (GETGRBYNAME, key_copy, key_len + 1,
-			     &dataset->head, true, db, owner) < 0)
+			     &dataset->head, true, db, owner, he == NULL) < 0)
 		goto out;
 
 	      first = false;
@@ -372,12 +372,13 @@
 	  if ((req->type == GETGRBYNAME || db->propagate)
 	      && __builtin_expect (cache_add (GETGRBYNAME, gr_name,
 					      gr_name_len,
-					      &dataset->head, first, db, owner)
+					      &dataset->head, first, db, owner,
+					      he == NULL)
 				   == 0, 1))
 	    {
 	      if (req->type == GETGRBYNAME && db->propagate)
 		(void) cache_add (GETGRBYGID, cp, key_offset, &dataset->head,
-				  false, db, owner);
+				  false, db, owner, false);
 	    }
 
 	out:
===================================================================
RCS file: /cvs/glibc/libc/nscd/aicache.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- libc/nscd/aicache.c	2008/05/17 22:51:08	1.21
+++ libc/nscd/aicache.c	2008/05/18 21:54:07	1.22
@@ -558,7 +558,7 @@
       pthread_rwlock_rdlock (&db->lock);
 
       (void) cache_add (req->type, key_copy, req->key_len, &dataset->head,
-			true, db, uid);
+			true, db, uid, he == NULL);
 
       pthread_rwlock_unlock (&db->lock);
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/connections.c,v
retrieving revision 1.111
retrieving revision 1.112
diff -u -r1.111 -r1.112
--- libc/nscd/connections.c	2008/04/22 15:53:45	1.111
+++ libc/nscd/connections.c	2008/05/18 21:54:26	1.112
@@ -1330,11 +1330,14 @@
     }
 
   /* Synchronize memory.  */
+  int32_t certainly[lastdb];
   for (int cnt = 0; cnt < lastdb; ++cnt)
     if (dbs[cnt].enabled)
       {
 	/* Make sure nobody keeps using the database.  */
 	dbs[cnt].head->timestamp = 0;
+	certainly[cnt] = dbs[cnt].head->nscd_certainly_running;
+	dbs[cnt].head->nscd_certainly_running = 0;
 
 	if (dbs[cnt].persistent)
 	  // XXX async OK?
@@ -1357,6 +1360,15 @@
     dbg_log (_("cannot change current working directory to \"/\": %s"),
 	     strerror (errno));
   paranoia = 0;
+
+  /* Reenable the databases.  */
+  time_t now = time (NULL);
+  for (int cnt = 0; cnt < lastdb; ++cnt)
+    if (dbs[cnt].enabled)
+      {
+	dbs[cnt].head->timestamp = now;
+	dbs[cnt].head->nscd_certainly_running = certainly[cnt];
+      }
 }
 
 
@@ -1394,42 +1406,68 @@
 
   int dont_need_update = setup_thread (&dbs[my_number]);
 
+  time_t now = time (NULL);
+
   /* We are running.  */
-  dbs[my_number].head->timestamp = time (NULL);
+  dbs[my_number].head->timestamp = now;
 
   struct timespec prune_ts;
-  if (clock_gettime (timeout_clock, &prune_ts) == -1)
+  if (__builtin_expect (clock_gettime (timeout_clock, &prune_ts) == -1, 0))
     /* Should never happen.  */
     abort ();
 
   /* Compute the initial timeout time.  Prevent all the timers to go
      off at the same time by adding a db-based value.  */
   prune_ts.tv_sec += CACHE_PRUNE_INTERVAL + my_number;
+  dbs[my_number].wakeup_time = now + CACHE_PRUNE_INTERVAL + my_number;
+
+  pthread_mutex_t *prune_lock = &dbs[my_number].prune_lock;
+  pthread_cond_t *prune_cond = &dbs[my_number].prune_cond;
 
-  pthread_mutex_lock (&dbs[my_number].prune_lock);
+  pthread_mutex_lock (prune_lock);
   while (1)
     {
       /* Wait, but not forever.  */
-      int e = pthread_cond_timedwait (&dbs[my_number].prune_cond,
-				      &dbs[my_number].prune_lock,
-				      &prune_ts);
-      assert (e == 0 || e == ETIMEDOUT);
+      int e = pthread_cond_timedwait (prune_cond, prune_lock, &prune_ts);
+      assert (__builtin_expect (e == 0 || e == ETIMEDOUT, 1));
 
       time_t next_wait;
-      time_t now = time (NULL);
+      now = time (NULL);
       if (e == ETIMEDOUT || now >= dbs[my_number].wakeup_time)
 	{
+	  /* We will determine the new timout values based on the
+	     cache content.  Should there be concurrent additions to
+	     the cache which are not accounted for in the cache
+	     pruning we want to know about it.  Therefore set the
+	     timeout to the maximum.  It will be descreased when adding
+	     new entries to the cache, if necessary.  */
+	  if (sizeof (time_t) == sizeof (long int))
+	    dbs[my_number].wakeup_time = LONG_MAX;
+	  else
+	    dbs[my_number].wakeup_time = INT_MAX;
+
+	  pthread_mutex_unlock (prune_lock);
+
 	  next_wait = prune_cache (&dbs[my_number], now, -1);
+
 	  next_wait = MAX (next_wait, CACHE_PRUNE_INTERVAL);
 	  /* If clients cannot determine for sure whether nscd is running
 	     we need to wake up occasionally to update the timestamp.
 	     Wait 90% of the update period.  */
 #define UPDATE_MAPPING_TIMEOUT (MAPPING_TIMEOUT * 9 / 10)
 	  if (__builtin_expect (! dont_need_update, 0))
-	    next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
+	    {
+	      next_wait = MIN (UPDATE_MAPPING_TIMEOUT, next_wait);
+	      dbs[my_number].head->timestamp = now;
+	    }
+
+	  pthread_mutex_lock (prune_lock);
 
 	  /* Make it known when we will wake up again.  */
-	  dbs[my_number].wakeup_time = now + next_wait;
+	  if (now + next_wait < dbs[my_number].wakeup_time)
+	    dbs[my_number].wakeup_time = now + next_wait;
+	  else
+	    next_wait = dbs[my_number].wakeup_time - now;
 	}
       else
 	/* The cache was just pruned.  Do not do it again now.  Just
===================================================================
RCS file: /cvs/glibc/libc/nscd/nscd_getserv_r.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- libc/nscd/nscd_getserv_r.c	2007/10/13 23:04:28	1.5
+++ libc/nscd/nscd_getserv_r.c	2008/06/03 10:22:52	1.6
@@ -53,7 +53,7 @@
   portstr[sizeof (portstr) - 1] = '\0';
   char *cp = _itoa_word (port, portstr + sizeof (portstr) - 1, 10, 0);
 
-  return nscd_getserv_r (portstr, portstr + sizeof (portstr) - cp, proto,
+  return nscd_getserv_r (cp, portstr + sizeof (portstr) - cp, proto,
 			 GETSERVBYPORT, result_buf, buf, buflen, result);
 }
 
===================================================================
RCS file: /cvs/glibc/libc/nscd/hstcache.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- libc/nscd/hstcache.c	2008/05/18 21:54:07	1.49
+++ libc/nscd/hstcache.c	2008/06/12 04:51:51	1.50
@@ -83,8 +83,7 @@
 	      struct hashentry *he, struct datahead *dh, int errval,
 	      int32_t ttl)
 {
-  ssize_t total;
-  ssize_t written;
+  bool all_written = true;
   time_t t = time (NULL);
 
   /* We allocate all data in one memory block: the iov vector,
@@ -108,18 +107,17 @@
 	  if (reload_count != UINT_MAX)
 	    /* Do not reset the value if we never not reload the record.  */
 	    dh->nreloads = reload_count - 1;
-
-	  written = total = 0;
 	}
       else
 	{
 	  /* We have no data.  This means we send the standard reply for this
 	     case.  */
-	  written = total = sizeof (notfound);
+	  ssize_t total = sizeof (notfound);
 
-	  if (fd != -1)
-	    written = TEMP_FAILURE_RETRY (send (fd, &notfound, total,
-						MSG_NOSIGNAL));
+	  if (fd != -1 &&
+	      TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+					MSG_NOSIGNAL)) != total)
+	    all_written = false;
 
 	  dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
 				   IDX_result_data);
@@ -181,6 +179,7 @@
       char *key_copy = NULL;
       char *cp;
       size_t cnt;
+      ssize_t total;
 
       /* Determine the number of aliases.  */
       h_aliases_cnt = 0;
@@ -208,7 +207,6 @@
 		+ h_name_len
 		+ h_aliases_cnt * sizeof (uint32_t)
 		+ h_addr_list_cnt * hst->h_length);
-      written = total;
 
       /* If we refill the cache, first assume the reconrd did not
 	 change.  Allocate memory on the cache since it is likely
@@ -260,6 +258,9 @@
       dataset->resp.h_addr_list_cnt = h_addr_list_cnt;
       dataset->resp.error = NETDB_SUCCESS;
 
+      /* Make sure there is no gap.  */
+      assert ((char *) (&dataset->resp.error + 1) == dataset->strdata);
+
       cp = dataset->strdata;
 
       cp = mempcpy (cp, hst->h_name, h_name_len);
@@ -286,6 +287,8 @@
 	 we explicitly add the name here.  */
       key_copy = memcpy (cp, key, req->key_len);
 
+      assert ((char *) &dataset->resp + dataset->head.recsize == cp);
+
       /* Now we can determine whether on refill we have to create a new
 	 record or not.  */
       if (he != NULL)
@@ -351,20 +354,27 @@
 		      <= (sizeof (struct database_pers_head)
 			  + db->head->module * sizeof (ref_t)
 			  + db->head->data_size));
-	      written = sendfileall (fd, db->wr_fd,
-				     (char *) &dataset->resp
-				     - (char *) db->head, total);
+	      ssize_t written = sendfileall (fd, db->wr_fd,
+					     (char *) &dataset->resp
+					     - (char *) db->head,
+					     dataset->head.recsize);
+	      if (written != dataset->head.recsize)
+		{
 # ifndef __ASSUME_SENDFILE
-	      if (written == -1 && errno == ENOSYS)
-		goto use_write;
+		  if (written == -1 && errno == ENOSYS)
+		    goto use_write;
 # endif
+		  all_written = false;
+		}
 	    }
 	  else
 # ifndef __ASSUME_SENDFILE
 	  use_write:
 # endif
 #endif
-	    written = writeall (fd, &dataset->resp, total);
+	    if (writeall (fd, &dataset->resp, dataset->head.recsize)
+		!= dataset->head.recsize)
+	      all_written = false;
 	}
 
       /* Add the record to the database.  But only if it has not been
@@ -414,7 +424,7 @@
 	}
     }
 
-  if (__builtin_expect (written != total, 0) && debug_level > 0)
+  if (__builtin_expect (!all_written, 0) && debug_level > 0)
     {
       char buf[256];
       dbg_log (_("short write in %s: %s"),  __FUNCTION__,
===================================================================
RCS file: /cvs/glibc/libc/nscd/mem.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- libc/nscd/mem.c	2008/05/18 06:28:54	1.18
+++ libc/nscd/mem.c	2008/06/12 04:52:27	1.19
@@ -235,6 +235,11 @@
   /* Sort the entries by their address.  */
   qsort (he, cnt, sizeof (struct hashentry *), sort_he);
 
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+  struct obstack ob;
+  obstack_init (&ob);
+
   /* Determine the highest used address.  */
   size_t high = nmark;
   while (high > 0 && mark[high - 1] == 0)
@@ -307,10 +312,6 @@
     size_t size;
     struct moveinfo *next;
   } *moves = NULL;
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-  struct obstack ob;
-  obstack_init (&ob);
 
   while (byte < high)
     {
===================================================================
RCS file: /cvs/glibc/libc/nscd/grpcache.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -r1.53 -r1.54
--- libc/nscd/grpcache.c	2008/05/18 21:54:07	1.53
+++ libc/nscd/grpcache.c	2008/06/12 16:03:36	1.54
@@ -190,7 +190,7 @@
 	  gr_mem_len_total += gr_mem_len[gr_mem_cnt];
 	}
 
-      written = total = (sizeof (struct dataset)
+      written = total = (offsetof (struct dataset, strdata)
 			 + gr_mem_cnt * sizeof (uint32_t)
 			 + gr_name_len + gr_passwd_len + gr_mem_len_total);
 
@@ -252,6 +252,9 @@
       char *key_copy = cp + key_offset;
       assert (key_copy == (char *) rawmemchr (cp, '\0') + 1);
 
+      assert (cp == dataset->strdata + total - offsetof (struct dataset,
+							 strdata));
+
       /* Now we can determine whether on refill we have to create a new
 	 record or not.  */
       if (he != NULL)
===================================================================
RCS file: /cvs/glibc/libc/nscd/initgrcache.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- libc/nscd/initgrcache.c	2008/05/18 21:54:07	1.15
+++ libc/nscd/initgrcache.c	2008/06/12 16:04:05	1.16
@@ -246,7 +246,8 @@
   else
     {
 
-      written = total = sizeof (struct dataset) + start * sizeof (int32_t);
+      written = total = (offsetof (struct dataset, strdata)
+			 + start * sizeof (int32_t));
 
       /* If we refill the cache, first assume the reconrd did not
 	 change.  Allocate memory on the cache since it is likely
@@ -307,6 +308,9 @@
       /* Finally the user name.  */
       memcpy (cp, key, req->key_len);
 
+      assert (cp == dataset->strdata + total - offsetof (struct dataset,
+							 strdata));
+
       /* Now we can determine whether on refill we have to create a new
 	 record or not.  */
       if (he != NULL)
===================================================================
RCS file: /cvs/glibc/libc/nscd/pwdcache.c,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -r1.51 -r1.52
--- libc/nscd/pwdcache.c	2008/05/18 21:54:07	1.51
+++ libc/nscd/pwdcache.c	2008/06/12 16:04:22	1.52
@@ -185,7 +185,8 @@
       n = snprintf (buf, buf_len, "%d%c%n%s", pwd->pw_uid, '\0',
 		    &key_offset, (char *) key) + 1;
 
-      written = total = (sizeof (struct dataset) + pw_name_len + pw_passwd_len
+      written = total = (offsetof (struct dataset, strdata)
+			 + pw_name_len + pw_passwd_len
 			 + pw_gecos_len + pw_dir_len + pw_shell_len);
 
       /* If we refill the cache, first assume the reconrd did not
@@ -247,16 +248,28 @@
       char *key_copy = cp + key_offset;
       assert (key_copy == (char *) rawmemchr (cp, '\0') + 1);
 
+      assert (cp == dataset->strdata + total - offsetof (struct dataset,
+							 strdata));
+
       /* Now we can determine whether on refill we have to create a new
 	 record or not.  */
       if (he != NULL)
 	{
 	  assert (fd == -1);
 
-	  if (total + n == dh->allocsize
-	      && total - offsetof (struct dataset, resp) == dh->recsize
+#if 0
+	  if (dataset->head.datasize == dh->allocsize
+	      && dataset->head.recsize == dh->recsize
 	      && memcmp (&dataset->resp, dh->data,
 			 dh->allocsize - offsetof (struct dataset, resp)) == 0)
+#else
+	  if (dataset->head.allocsize != dh->allocsize)
+	    goto nnn;
+	  if (dataset->head.recsize != dh->recsize)
+	    goto nnn;
+	  if(memcmp (&dataset->resp, dh->data,
+			 dh->allocsize - offsetof (struct dataset, resp)) == 0)
+#endif
 	    {
 	      /* The data has not changed.  We will just bump the
 		 timeout value.  Note that the new record has been
@@ -266,6 +279,7 @@
 	    }
 	  else
 	    {
+ nnn:;
 	      /* We have to create a new record.  Just allocate
 		 appropriate memory and copy it.  */
 	      struct dataset *newp
===================================================================
RCS file: /cvs/glibc/libc/nscd/servicescache.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- libc/nscd/servicescache.c	2008/05/18 21:54:07	1.8
+++ libc/nscd/servicescache.c	2008/06/12 16:04:37	1.9
@@ -173,7 +173,7 @@
 	  total += s_aliases_len[cnt];
 	}
 
-      total += (sizeof (struct dataset)
+      total += (offsetof (struct dataset, strdata)
 		+ s_name_len
 		+ s_proto_len
 		+ s_aliases_cnt * sizeof (uint32_t));