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 <[email protected]>
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 <[email protected]>
    Autobuild-Date: Mon Aug 15 04:13:51 CEST 2011 on sn-devel-104

commit 039ddef20900322760093a04881007dbb0897b50
Author: Simo Sorce <[email protected]>
Date:   Sun Aug 14 18:10:53 2011 -0400

    util: add function to extend anonymous shared memory

commit a171938408adde0d787b9ff40a4cebeee66d747a
Author: Simo Sorce <[email protected]>
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

Reply via email to