about summary refs log tree commit diff
path: root/nscd/connections.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2005-08-23 23:21:53 +0000
committerUlrich Drepper <drepper@redhat.com>2005-08-23 23:21:53 +0000
commit2c210d1eb88d4ab44bfce576b8fbac8e89a946f4 (patch)
treeba61cc9d2f2ee26f7edc7d92549499175274a374 /nscd/connections.c
parentfd4af66481e49b3dca42ecb0eadf75dbeea09bfc (diff)
downloadglibc-2c210d1eb88d4ab44bfce576b8fbac8e89a946f4.tar.gz
glibc-2c210d1eb88d4ab44bfce576b8fbac8e89a946f4.tar.xz
glibc-2c210d1eb88d4ab44bfce576b8fbac8e89a946f4.zip
* nscd/connection.c (DEFAULT_DATASIZE_PER_BUCKET): Move to nscd.h.
	(dbs): Initialize max_db_size fields.
	(nscd_init): When mapping the database, use max_db_size as the
	mapping size even if it is bigger than the file size.
	* nscd/mem.c (mempool_alloc): When resizing the file make sure the
	limit in max_db_size is not exceeded.  Don't use mremap, just
	posix_fallocate is enough (according to Linus).  Use posix_fallocate
	correctly.
	* nscd/nscd.conf: Add max-db-size parameters.
	* nscd/nscd.h (struct database_dyn): Add max_db_size field.
	Define DEFAULT_MAX_DB_SIZE and DEFAULT_DATASIZE_PER_BUCKET.
	Temporarily define TEMP_FAILURE_RETRY_VAL here.
	* nscd/nscd_conf.c (nscd_parse_file): Parse max-db-size parameter
	and add sanity checks for it.

	* nscd/aicache.c (addhstaiX): Use send with MSG_NOSIGNAL not write to
	send reply.
	* nscd/connection.c (writeall): Likewise.
	(handle_request): Likewise.
	* nscd/grpcache.c (cache_addgr): Likewise.
	* nscd/hstcache.c (cache_addhst): Likewise.
	* nscd/initgrcache.c (addinitgroupsX): Likewise.
	* nscd/nscd.c (parse_opt): Likewise.
	* nscd/nscd_stat.c (send_stats): Likewise.
	(receive_print_stats): Likewise.
	* nscd/pwdcache.c (cache_addpw): Likewise.
Diffstat (limited to 'nscd/connections.c')
-rw-r--r--nscd/connections.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/nscd/connections.c b/nscd/connections.c
index 0a0654d6b8..ce1348b069 100644
--- a/nscd/connections.c
+++ b/nscd/connections.c
@@ -48,10 +48,6 @@
 #include "selinux.h"
 
 
-/* Number of bytes of data we initially reserve for each hash table bucket.  */
-#define DEFAULT_DATASIZE_PER_BUCKET 1024
-
-
 /* Wrapper functions with error checking for standard functions.  */
 extern void *xmalloc (size_t n);
 extern void *xcalloc (size_t n, size_t s);
@@ -104,6 +100,7 @@ struct database_dyn dbs[lastdb] =
     .check_file = 1,
     .persistent = 0,
     .shared = 0,
+    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/passwd",
     .db_filename = _PATH_NSCD_PASSWD_DB,
     .disabled_iov = &pwd_iov_disabled,
@@ -119,6 +116,7 @@ struct database_dyn dbs[lastdb] =
     .check_file = 1,
     .persistent = 0,
     .shared = 0,
+    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/group",
     .db_filename = _PATH_NSCD_GROUP_DB,
     .disabled_iov = &grp_iov_disabled,
@@ -134,6 +132,7 @@ struct database_dyn dbs[lastdb] =
     .check_file = 1,
     .persistent = 0,
     .shared = 0,
+    .max_db_size = DEFAULT_MAX_DB_SIZE,
     .filename = "/etc/hosts",
     .db_filename = _PATH_NSCD_HOSTS_DB,
     .disabled_iov = &hst_iov_disabled,
@@ -188,7 +187,7 @@ writeall (int fd, const void *buf, size_t len)
   ssize_t ret;
   do
     {
-      ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
+      ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
       if (ret <= 0)
 	break;
       buf = (const char *) buf + ret;
@@ -473,8 +472,16 @@ nscd_init (void)
 			     _("file size does not match"));
 		    unlink (dbs[cnt].db_filename);
 		  }
-		else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
-				      MAP_SHARED, fd, 0)) == MAP_FAILED)
+		/* Note we map with the maximum size allowed for the
+		   database.  This is likely much larger than the
+		   actual file size.  This is OK on most OSes since
+		   extensions of the underlying file will
+		   automatically translate more pages available for
+		   memory access.  */
+		else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
+				      PROT_READ | PROT_WRITE,
+				      MAP_SHARED, fd, 0))
+			 == MAP_FAILED)
 		  goto fail_db;
 		else if (!verify_persistent_db (mem, &head, cnt))
 		  {
@@ -638,8 +645,10 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
 
 		if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
 		     != sizeof (head))
-		    || posix_fallocate (fd, 0, total) != 0
-		    || (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
+		    || (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
+			!= 0)
+		    || (mem = mmap (NULL, dbs[cnt].max_db_size,
+				    PROT_READ | PROT_WRITE,
 				    MAP_SHARED, fd, 0)) == MAP_FAILED)
 		  {
 		  write_fail:
@@ -901,8 +910,9 @@ cannot handle old request version %d; current version is %d"),
       if (!db->enabled)
 	{
 	  /* No, sent the prepared record.  */
-	  if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
-					 db->disabled_iov->iov_len))
+	  if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
+					db->disabled_iov->iov_len,
+					MSG_NOSIGNAL))
 	      != (ssize_t) db->disabled_iov->iov_len
 	      && __builtin_expect (debug_level, 0) > 0)
 	    {