[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