[SCM] Samba Shared Repository - branch master updated

Simo Sorce idra at samba.org
Sun Aug 14 20:14:02 MDT 2011


The branch, master has been updated
       via  2e5fc83 s3-prefork: Do not use mmap/mremap/munmap directly
       via  039ddef util: add function to extend anonymous shared memory
       via  a171938 replace: Check if we have mremap() available
      from  88ecf1a Use public pytalloc header file.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 2e5fc8335022df44a015817d4628a48e9195e311
Author: Simo Sorce <idra at samba.org>
Date:   Sun Aug 14 18:11:18 2011 -0400

    s3-prefork: Do not use mmap/mremap/munmap directly
    
    Use the wrappers in util.h as they deal with trying to do the best they can on
    platfroms that do not support mmap extensions.
    
    Autobuild-User: Simo Sorce <idra at samba.org>
    Autobuild-Date: Mon Aug 15 04:13:51 CEST 2011 on sn-devel-104

commit 039ddef20900322760093a04881007dbb0897b50
Author: Simo Sorce <idra at samba.org>
Date:   Sun Aug 14 18:10:53 2011 -0400

    util: add function to extend anonymous shared memory

commit a171938408adde0d787b9ff40a4cebeee66d747a
Author: Simo Sorce <idra at samba.org>
Date:   Sun Aug 14 18:05:27 2011 -0400

    replace: Check if we have mremap() available

-----------------------------------------------------------------------

Summary of changes:
 lib/replace/libreplace.m4        |    7 ++++
 lib/replace/test/shared_mremap.c |   48 ++++++++++++++++++++++++++++
 lib/util/util.c                  |   64 ++++++++++++++++++++++++++++++++++++++
 lib/util/util.h                  |    1 +
 source3/lib/server_prefork.c     |   20 ++++++-----
 5 files changed, 131 insertions(+), 9 deletions(-)
 create mode 100644 lib/replace/test/shared_mremap.c


Changeset truncated at 500 lines:

diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4
index 808d5d1..d644e50 100644
--- a/lib/replace/libreplace.m4
+++ b/lib/replace/libreplace.m4
@@ -98,6 +98,13 @@ if test x"$libreplace_cv_HAVE_MMAP" = x"yes"; then
     AC_DEFINE(HAVE_MMAP,1,[Whether mmap works])
 fi
 
+AC_CACHE_CHECK([for working mremap],libreplace_cv_HAVE_MREMAP,[
+AC_TRY_RUN([#include "$libreplacedir/test/shared_mremap.c"],
+           libreplace_cv_HAVE_MREMAP=yes,libreplace_cv_HAVE_MREMAP=no,libreplace_cv_HAVE_MREMAP=cross)])
+if test x"$libreplace_cv_HAVE_MREMAP" = x"yes"; then
+    AC_DEFINE(HAVE_MREMAP,1,[Whether mremap works])
+fi
+
 
 AC_CHECK_HEADERS(sys/syslog.h syslog.h)
 AC_CHECK_HEADERS(sys/time.h time.h)
diff --git a/lib/replace/test/shared_mremap.c b/lib/replace/test/shared_mremap.c
new file mode 100644
index 0000000..05032ad
--- /dev/null
+++ b/lib/replace/test/shared_mremap.c
@@ -0,0 +1,48 @@
+/* this tests whether we can use mremap */
+
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define DATA "conftest.mmap"
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED (int *)-1
+#endif
+
+main()
+{
+	int *buf;
+	int fd;
+	int err = 1;
+
+	fd = open(DATA, O_RDWR|O_CREAT|O_TRUNC, 0666);
+	if (fd == -1) {
+		exit(1);
+	}
+
+	buf = (int *)mmap(NULL, 0x1000, PROT_READ | PROT_WRITE,
+			  MAP_FILE | MAP_SHARED, fd, 0);
+	if (buf == MAP_FAILED) {
+		goto done;
+	}
+
+	buf = mremap(buf, 0x1000, 0x2000, MREMAP_MAYMOVE);
+	if (buf == MAP_FAILED) {
+		goto done;
+	}
+
+	err = 0;
+done:
+	close(fd);
+	unlink(DATA);
+	exit(err);
+}
diff --git a/lib/util/util.c b/lib/util/util.c
index 2d1d830..b700f37 100644
--- a/lib/util/util.c
+++ b/lib/util/util.c
@@ -1073,6 +1073,70 @@ void *anonymous_shared_allocate(size_t orig_bufsz)
 	return ptr;
 }
 
+void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove)
+{
+#ifdef HAVE_MREMAP
+	void *buf;
+	size_t pagesz = getpagesize();
+	size_t pagecnt;
+	size_t bufsz;
+	struct anonymous_shared_header *hdr;
+	int flags = 0;
+
+	if (ptr == NULL) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	hdr = (struct anonymous_shared_header *)ptr;
+	hdr--;
+	if (hdr->u.length > (new_size + sizeof(*hdr))) {
+		errno = EINVAL;
+		return NULL;
+	}
+
+	bufsz = new_size + sizeof(*hdr);
+
+	/* round up to full pages */
+	pagecnt = bufsz / pagesz;
+	if (bufsz % pagesz) {
+		pagecnt += 1;
+	}
+	bufsz = pagesz * pagecnt;
+
+	if (new_size >= bufsz) {
+		/* integer wrap */
+		errno = ENOSPC;
+		return NULL;
+	}
+
+	if (bufsz <= hdr->u.length) {
+		return ptr;
+	}
+
+	if (maymove) {
+		flags = MREMAP_MAYMOVE;
+	}
+
+	buf = mremap(hdr, hdr->u.length, bufsz, flags);
+
+	if (buf == MAP_FAILED) {
+		errno = ENOSPC;
+		return NULL;
+	}
+
+	hdr = (struct anonymous_shared_header *)buf;
+	hdr->u.length = bufsz;
+
+	ptr = (void *)(&hdr[1]);
+
+	return ptr;
+#else
+	errno = ENOSPC;
+	return NULL;
+#endif
+}
+
 void anonymous_shared_free(void *ptr)
 {
 	struct anonymous_shared_header *hdr;
diff --git a/lib/util/util.h b/lib/util/util.h
index 7f0de26..0102fea 100644
--- a/lib/util/util.h
+++ b/lib/util/util.h
@@ -852,6 +852,7 @@ bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
  * Allocate anonymous shared memory of the given size
  */
 void *anonymous_shared_allocate(size_t bufsz);
+void *anonymous_shared_resize(void *ptr, size_t new_size, bool maymove);
 void anonymous_shared_free(void *ptr);
 
 /*
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c
index 501fbc1..5206c36 100644
--- a/source3/lib/server_prefork.c
+++ b/source3/lib/server_prefork.c
@@ -50,7 +50,7 @@ static bool prefork_setup_sigchld_handler(struct tevent_context *ev_ctx,
 
 static int prefork_pool_destructor(struct prefork_pool *pfp)
 {
-	munmap(pfp->pool, pfp->pool_size * sizeof(struct pf_worker_data));
+	anonymous_shared_free(pfp->pool);
 	return 0;
 }
 
@@ -97,9 +97,8 @@ bool prefork_create_pool(TALLOC_CTX *mem_ctx,
 	pfp->pool_size = max_children;
 	data_size = sizeof(struct pf_worker_data) * max_children;
 
-	pfp->pool = mmap(NULL, data_size, PROT_READ|PROT_WRITE,
-			 MAP_SHARED|MAP_ANONYMOUS, -1, 0);
-	if (pfp->pool == MAP_FAILED) {
+	pfp->pool = anonymous_shared_allocate(data_size);
+	if (pfp->pool == NULL) {
 		DEBUG(1, ("Failed to mmap memory for prefork pool!\n"));
 		talloc_free(pfp);
 		return false;
@@ -153,9 +152,10 @@ bool prefork_create_pool(TALLOC_CTX *mem_ctx,
  */
 int prefork_expand_pool(struct prefork_pool *pfp, int new_max)
 {
-	struct pf_worker_data *pool;
+	struct prefork_pool *pool;
 	size_t old_size;
 	size_t new_size;
+	int ret;
 
 	if (new_max <= pfp->pool_size) {
 		return EINVAL;
@@ -164,10 +164,12 @@ int prefork_expand_pool(struct prefork_pool *pfp, int new_max)
 	old_size = sizeof(struct pf_worker_data) * pfp->pool_size;
 	new_size = sizeof(struct pf_worker_data) * new_max;
 
-	pool = mremap(pfp->pool, old_size, new_size, 0);
-	if (pool == MAP_FAILED) {
-		DEBUG(3, ("Failed to mremap memory for prefork pool!\n"));
-		return ENOSPC;
+	pool = anonymous_shared_resize(&pfp->pool, new_size, false);
+	if (pool == NULL) {
+		ret = errno;
+		DEBUG(3, ("Failed to mremap memory (%d: %s)!\n",
+			  ret, strerror(ret)));
+		return ret;
 	}
 
 	memset(&pool[pfp->pool_size], 0, new_size - old_size);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list