[SCM] Samba Shared Repository - branch v3-6-test updated
Karolin Seeger
kseeger at samba.org
Sun Feb 12 13:05:51 MST 2012
The branch, v3-6-test has been updated
via 16f900c Allow vfs_aio_pthread to build as a static module.
via c738f0e Update man page to fix typo vfs_aio_fork -> vfs_aio_pthread, add aio read size, aio write size examples. (cherry picked from commit 12b614a9298974ba5daee7aa8d1aa47006de01e2)
via 0ba64e6 Add vfs_aio_pthread code.
via caa7cca Ensure we always free aio_ex on all error paths by moving the TALLOC_FREE call out of smbd_aio_complete_aio_ex() and into the caller.
via 00d59a0 Add man page for vfs_aio_pthread module. (cherry picked from commit d8c699190d2cc0ce64395c7b2b10bb25c98a2943)
via b306267 Change the signature of pthreadpool_finished_job() to return 0 on success, errno on fail and return the jobid in a separate variable.
from 5bfe963 s3:smb2_server: fix a logic error, we should sign non guest sessions
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test
- Log -----------------------------------------------------------------
commit 16f900cb94a69a47d627666751d374f097f092f4
Author: Christian Ambach <ambi at samba.org>
Date: Fri Jan 27 10:25:13 2012 -0800
Allow vfs_aio_pthread to build as a static module.
The last 6 patches address bug #8723 (Add pthread-based aio module to 3.6.3.).
commit c738f0ea9e1c2356eab1dac778ceb94f22036f0a
Author: Jeremy Allison <jra at samba.org>
Date: Wed Jan 25 17:17:48 2012 -0800
Update man page to fix typo vfs_aio_fork -> vfs_aio_pthread, add aio read size, aio write size examples. (cherry picked from commit 12b614a9298974ba5daee7aa8d1aa47006de01e2)
commit 0ba64e6bc78404b2f75af638c22b52007159d96b
Author: Jeremy Allison <jra at samba.org>
Date: Wed Jan 25 16:54:39 2012 -0800
Add vfs_aio_pthread code.
commit caa7ccae10f9be77cf28890aadff735ca83de93e
Author: Jeremy Allison <jra at samba.org>
Date: Wed Jan 25 16:27:54 2012 -0800
Ensure we always free aio_ex on all error paths by moving the TALLOC_FREE call out of smbd_aio_complete_aio_ex() and into the caller.
commit 00d59a043dc4008f25cdf44dc233d181114dfa2d
Author: Jeremy Allison <jra at samba.org>
Date: Wed Jan 25 14:11:12 2012 -0800
Add man page for vfs_aio_pthread module. (cherry picked from commit d8c699190d2cc0ce64395c7b2b10bb25c98a2943)
commit b30626720405c435ad48abf8e1445ee8f4b859a3
Author: Jeremy Allison <jra at samba.org>
Date: Wed Dec 21 20:38:32 2011 -0800
Change the signature of pthreadpool_finished_job() to return 0 on success, errno on fail and return the jobid in a separate variable.
I need this fix for my vfs_aio_pthread.c module.
Autobuild-User: Jeremy Allison <jra at samba.org>
Autobuild-Date: Thu Dec 22 12:12:33 CET 2011 on sn-devel-104
(cherry picked from commit 711c18c2301d1bea35cac1144080a94e6b89be27)
-----------------------------------------------------------------------
Summary of changes:
docs-xml/manpages-3/vfs_aio_pthread.8.xml | 120 ++++++
source3/Makefile.in | 5 +
source3/configure.in | 4 +
source3/lib/fncall.c | 3 +-
source3/lib/pthreadpool/pthreadpool.c | 9 +-
source3/lib/pthreadpool/pthreadpool.h | 5 +-
source3/lib/pthreadpool/tests.c | 18 +-
source3/modules/vfs_aio_fork.c | 1 +
source3/modules/vfs_aio_pthread.c | 625 +++++++++++++++++++++++++++++
source3/smbd/aio.c | 3 +-
10 files changed, 775 insertions(+), 18 deletions(-)
create mode 100644 docs-xml/manpages-3/vfs_aio_pthread.8.xml
create mode 100644 source3/modules/vfs_aio_pthread.c
Changeset truncated at 500 lines:
diff --git a/docs-xml/manpages-3/vfs_aio_pthread.8.xml b/docs-xml/manpages-3/vfs_aio_pthread.8.xml
new file mode 100644
index 0000000..3e41ee9
--- /dev/null
+++ b/docs-xml/manpages-3/vfs_aio_pthread.8.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc">
+<refentry id="vfs_aio_pthread.8">
+
+<refmeta>
+ <refentrytitle>vfs_aio_pthread</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="source">Samba</refmiscinfo>
+ <refmiscinfo class="manual">System Administration tools</refmiscinfo>
+ <refmiscinfo class="version">3.6</refmiscinfo>
+</refmeta>
+
+
+<refnamediv>
+ <refname>vfs_aio_pthread</refname>
+ <refpurpose>implement async I/O in Samba vfs using a pthread pool</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv>
+ <cmdsynopsis>
+ <command>vfs objects = aio_pthread</command>
+ </cmdsynopsis>
+</refsynopsisdiv>
+
+<refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This VFS module is part of the
+ <citerefentry><refentrytitle>samba</refentrytitle>
+ <manvolnum>7</manvolnum></citerefentry> suite.</para>
+
+ <para>The <command>aio_pthread</command> VFS module enables asynchronous
+ I/O for Samba on platforms which have the pthreads API available,
+ without using the Posix AIO interface. Posix AIO can suffer from severe
+ limitations. For example, on some Linux versions the
+ real-time signals that it uses are broken under heavy load.
+ Other systems only allow AIO when special kernel modules are
+ loaded or only allow a certain system-wide amount of async
+ requests being scheduled. Systems based on glibc (most Linux
+ systems) only allow a single outstanding request per file
+ descriptor which essentially makes Posix AIO useless on systems
+ using the glibc implementation.</para>
+
+ <para>To work around all these limitations, the aio_pthread module
+ was written. It uses a pthread pool instead of the
+ internal Posix AIO interface to allow read and write calls
+ to be process asynchronously. A pthread pool is created
+ which expands dynamically by creating new threads as work is
+ given to it to a maximum of 100 threads per smbd process.
+ To change this limit see the "aio num threads" parameter
+ below. New threads are not created if idle threads are
+ available when a new read or write request is received,
+ the new work is given to an existing idle thread. Threads
+ terminate themselves if idle for one second.
+ </para>
+
+ <para>
+ Note that the smb.conf parameters <command>aio read size</command>
+ and <command>aio write size</command> must also be set appropriately
+ for this module to be active.
+ </para>
+
+ <para>This module MUST be listed last in any module stack as
+ the Samba VFS pread/pwrite interface is not thread-safe. This
+ module makes direct pread and pwrite system calls and does
+ NOT call the Samba VFS pread and pwrite interfaces.</para>
+
+</refsect1>
+
+
+<refsect1>
+ <title>EXAMPLES</title>
+
+ <para>Straight forward use:</para>
+
+<programlisting>
+ <smbconfsection name="[cooldata]"/>
+ <smbconfoption name="path">/data/ice</smbconfoption>
+ <smbconfoption name="aio read size">1024</smbconfoption>
+ <smbconfoption name="aio write size">1024</smbconfoption>
+ <smbconfoption name="vfs objects">aio_pthread</smbconfoption>
+</programlisting>
+
+</refsect1>
+
+<refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>aio_pthread:aio num threads = INTEGER</term>
+ <listitem>
+ <para>Limit the maximum number of threads per smbd that
+ will be created in the thread pool to service IO requests.
+ </para>
+ <para>By default this is set to 100.</para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+</refsect1>
+<refsect1>
+ <title>VERSION</title>
+
+ <para>This man page is correct for version 3.6.3 of the Samba suite.
+ </para>
+</refsect1>
+
+<refsect1>
+ <title>AUTHOR</title>
+
+ <para>The original Samba software and related utilities
+ were created by Andrew Tridgell. Samba is now developed
+ by the Samba Team as an Open Source project similar
+ to the way the Linux kernel is developed.</para>
+
+</refsect1>
+
+</refentry>
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 7e98db7..007c82d 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -829,6 +829,7 @@ VFS_READAHEAD_OBJ = modules/vfs_readahead.o
VFS_TSMSM_OBJ = modules/vfs_tsmsm.o
VFS_FILEID_OBJ = modules/vfs_fileid.o
VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o
+VFS_AIO_PTHREAD_OBJ = modules/vfs_aio_pthread.o
VFS_PREOPEN_OBJ = modules/vfs_preopen.o
VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
@@ -3029,6 +3030,10 @@ bin/aio_fork. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AIO_FORK_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_AIO_FORK_OBJ)
+bin/aio_pthread. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_AIO_PTHREAD_OBJ) lib/pthreadpool/pthreadpool.o
+ @echo "Building plugin $@"
+ @$(SHLD_MODULE) $(VFS_AIO_PTHREAD_OBJ) lib/pthreadpool/pthreadpool.o -lpthread
+
bin/preopen. at SHLIBEXT@: $(BINARY_PREREQS) $(VFS_PREOPEN_OBJ)
@echo "Building plugin $@"
@$(SHLD_MODULE) $(VFS_PREOPEN_OBJ)
diff --git a/source3/configure.in b/source3/configure.in
index 398a4f8..d8d3a1f 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -6674,6 +6674,9 @@ if test x"$enable_pthreadpool" = x"yes" -a x"$samba_cv_HAVE_PTHREAD" = x"yes"; t
AC_SUBST(PTHREADPOOL_OBJ, "lib/pthreadpool/pthreadpool.o")
PTHREADPOOLTEST="bin/pthreadpooltest\$(EXEEXT)"
AC_SUBST(PTHREADPOOLTEST)
+ if test x"$samba_cv_HAVE_AIO" = x"yes"; then
+ default_shared_modules="$default_shared_modules vfs_aio_pthread"
+ fi
fi
#################################################
@@ -6901,6 +6904,7 @@ SMB_MODULE(vfs_readahead, \$(VFS_READAHEAD_OBJ), "bin/readahead.$SHLIBEXT", VFS)
SMB_MODULE(vfs_tsmsm, \$(VFS_TSMSM_OBJ), "bin/tsmsm.$SHLIBEXT", VFS)
SMB_MODULE(vfs_fileid, \$(VFS_FILEID_OBJ), "bin/fileid.$SHLIBEXT", VFS)
SMB_MODULE(vfs_aio_fork, \$(VFS_AIO_FORK_OBJ), "bin/aio_fork.$SHLIBEXT", VFS)
+SMB_MODULE(vfs_aio_pthread, \$(VFS_AIO_PTHREAD_OBJ), "bin/aio_pthread.$SHLIBEXT", VFS)
SMB_MODULE(vfs_preopen, \$(VFS_PREOPEN_OBJ), "bin/preopen.$SHLIBEXT", VFS)
SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS)
SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS)
diff --git a/source3/lib/fncall.c b/source3/lib/fncall.c
index 4a013e9..13bf093 100644
--- a/source3/lib/fncall.c
+++ b/source3/lib/fncall.c
@@ -280,8 +280,7 @@ static void fncall_handler(struct tevent_context *ev, struct tevent_fd *fde,
int i, num_pending;
int job_id;
- job_id = pthreadpool_finished_job(ctx->pool);
- if (job_id <= 0) {
+ if (pthreadpool_finished_job(ctx->pool, &job_id) != 0) {
return;
}
diff --git a/source3/lib/pthreadpool/pthreadpool.c b/source3/lib/pthreadpool/pthreadpool.c
index 7538fb7..c2dd92a 100644
--- a/source3/lib/pthreadpool/pthreadpool.c
+++ b/source3/lib/pthreadpool/pthreadpool.c
@@ -284,16 +284,16 @@ static void pthreadpool_join_children(struct pthreadpool *pool)
* Fetch a finished job number from the signal pipe
*/
-int pthreadpool_finished_job(struct pthreadpool *pool)
+int pthreadpool_finished_job(struct pthreadpool *pool, int *jobid)
{
- int result;
+ int ret_jobid;
ssize_t nread;
nread = -1;
errno = EINTR;
while ((nread == -1) && (errno == EINTR)) {
- nread = read(pool->sig_pipe[0], &result, sizeof(int));
+ nread = read(pool->sig_pipe[0], &ret_jobid, sizeof(int));
}
if (nread == -1) {
return errno;
@@ -301,7 +301,8 @@ int pthreadpool_finished_job(struct pthreadpool *pool)
if (nread != sizeof(int)) {
return EINVAL;
}
- return result;
+ *jobid = ret_jobid;
+ return 0;
}
/*
diff --git a/source3/lib/pthreadpool/pthreadpool.h b/source3/lib/pthreadpool/pthreadpool.h
index 79704ea..0fde3c8 100644
--- a/source3/lib/pthreadpool/pthreadpool.h
+++ b/source3/lib/pthreadpool/pthreadpool.h
@@ -90,8 +90,9 @@ int pthreadpool_signal_fd(struct pthreadpool *pool);
* pthreadpool_signal_fd() is readable.
*
* @param[in] pool The pool to query for finished jobs
- * @return The job_id of the finished job
+ * @param[out] pjobid The job_id of the finished job
+ * @return success: 0, failure: errno
*/
-int pthreadpool_finished_job(struct pthreadpool *pool);
+int pthreadpool_finished_job(struct pthreadpool *pool, int *jobid);
#endif
diff --git a/source3/lib/pthreadpool/tests.c b/source3/lib/pthreadpool/tests.c
index 667ee01..95d37b6 100644
--- a/source3/lib/pthreadpool/tests.c
+++ b/source3/lib/pthreadpool/tests.c
@@ -68,12 +68,13 @@ static int test_jobs(int num_threads, int num_jobs)
}
for (i=0; i<num_jobs; i++) {
- ret = pthreadpool_finished_job(p);
- if ((ret < 0) || (ret >= num_jobs)) {
- fprintf(stderr, "invalid job number %d\n", ret);
+ int jobid = -1;
+ ret = pthreadpool_finished_job(p, &jobid);
+ if ((ret != 0) || (jobid >= num_jobs)) {
+ fprintf(stderr, "invalid job number %d\n", jobid);
return -1;
}
- finished[ret] += 1;
+ finished[jobid] += 1;
}
for (i=0; i<num_jobs; i++) {
@@ -275,18 +276,19 @@ static int test_threaded_addjob(int num_pools, int num_threads, int poolsize,
}
for (j=0; j<num_pools; j++) {
+ int jobid = -1;
if ((pfds[j].revents & (POLLIN|POLLHUP)) == 0) {
continue;
}
- ret = pthreadpool_finished_job(pools[j]);
- if ((ret < 0) || (ret >= num_jobs * num_threads)) {
+ ret = pthreadpool_finished_job(pools[j], &jobid);
+ if ((ret != 0) || (jobid >= num_jobs * num_threads)) {
fprintf(stderr, "invalid job number %d\n",
- ret);
+ jobid);
return -1;
}
- finished[ret] += 1;
+ finished[jobid] += 1;
received += 1;
}
}
diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index 41b5a89..7f6a021 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -434,6 +434,7 @@ static void handle_aio_completion(struct event_context *event_ctx,
aio_ex = (struct aio_extra *)child->aiocb->aio_sigevent.sigev_value.sival_ptr;
smbd_aio_complete_aio_ex(aio_ex);
+ TALLOC_FREE(aio_ex);
}
static int aio_child_destructor(struct aio_child *child)
diff --git a/source3/modules/vfs_aio_pthread.c b/source3/modules/vfs_aio_pthread.c
new file mode 100644
index 0000000..ceef822
--- /dev/null
+++ b/source3/modules/vfs_aio_pthread.c
@@ -0,0 +1,625 @@
+/*
+ * Simulate Posix AIO using pthreads.
+ *
+ * Based on the aio_fork work from Volker and Volker's pthreadpool library.
+ *
+ * Copyright (C) Volker Lendecke 2008
+ * Copyright (C) Jeremy Allison 2012
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "system/shmem.h"
+#include "smbd/smbd.h"
+#include "lib/pthreadpool/pthreadpool.h"
+
+struct aio_extra;
+static struct pthreadpool *pool;
+static int aio_pthread_jobid;
+
+struct aio_private_data {
+ struct aio_private_data *prev, *next;
+ int jobid;
+ SMB_STRUCT_AIOCB *aiocb;
+ ssize_t ret_size;
+ int ret_errno;
+ bool cancelled;
+ bool write_command;
+};
+
+/* List of outstanding requests we have. */
+static struct aio_private_data *pd_list;
+
+static void aio_pthread_handle_completion(struct event_context *event_ctx,
+ struct fd_event *event,
+ uint16 flags,
+ void *p);
+
+/************************************************************************
+ How many threads to initialize ?
+ 100 per process seems insane as a default until you realize that
+ (a) Threads terminate after 1 second when idle.
+ (b) Throttling is done in SMB2 via the crediting algorithm.
+ (c) SMB1 clients are limited to max_mux (50) outstanding requests and
+ Windows clients don't use this anyway.
+ Essentially we want this to be unlimited unless smb.conf says different.
+***********************************************************************/
+
+static int aio_get_num_threads(struct vfs_handle_struct *handle)
+{
+ return lp_parm_int(SNUM(handle->conn),
+ "aio_pthread", "aio num threads", 100);
+}
+
+/************************************************************************
+ Ensure thread pool is initialized.
+***********************************************************************/
+
+static bool init_aio_threadpool(struct vfs_handle_struct *handle)
+{
+ struct fd_event *sock_event = NULL;
+ int ret = 0;
+ int num_threads;
+
+ if (pool) {
+ return true;
+ }
+
+ num_threads = aio_get_num_threads(handle);
+ ret = pthreadpool_init(num_threads, &pool);
+ if (ret) {
+ errno = ret;
+ return false;
+ }
+ sock_event = tevent_add_fd(server_event_context(),
+ NULL,
+ pthreadpool_signal_fd(pool),
+ TEVENT_FD_READ,
+ aio_pthread_handle_completion,
+ NULL);
+ if (sock_event == NULL) {
+ pthreadpool_destroy(pool);
+ pool = NULL;
+ return false;
+ }
+
+ DEBUG(10,("init_aio_threadpool: initialized with up to %d threads\n",
+ num_threads));
+
+ return true;
+}
+
+
+/************************************************************************
+ Worker function - core of the pthread aio engine.
+ This is the function that actually does the IO.
+***********************************************************************/
+
+static void aio_worker(void *private_data)
+{
+ struct aio_private_data *pd =
+ (struct aio_private_data *)private_data;
+
+ if (pd->write_command) {
+ pd->ret_size = sys_pwrite(pd->aiocb->aio_fildes,
+ (const void *)pd->aiocb->aio_buf,
+ pd->aiocb->aio_nbytes,
+ pd->aiocb->aio_offset);
+ if (pd->ret_size == -1 && errno == ESPIPE) {
+ /* Maintain the fiction that pipes can
+ be seeked (sought?) on. */
+ pd->ret_size = sys_write(pd->aiocb->aio_fildes,
+ (const void *)pd->aiocb->aio_buf,
+ pd->aiocb->aio_nbytes);
+ }
+ } else {
+ pd->ret_size = sys_pread(pd->aiocb->aio_fildes,
+ (void *)pd->aiocb->aio_buf,
+ pd->aiocb->aio_nbytes,
+ pd->aiocb->aio_offset);
+ if (pd->ret_size == -1 && errno == ESPIPE) {
+ /* Maintain the fiction that pipes can
+ be seeked (sought?) on. */
+ pd->ret_size = sys_read(pd->aiocb->aio_fildes,
+ (void *)pd->aiocb->aio_buf,
+ pd->aiocb->aio_nbytes);
+ }
+ }
+ if (pd->ret_size == -1) {
+ pd->ret_errno = errno;
+ } else {
+ pd->ret_errno = 0;
+ }
+}
+
+/************************************************************************
+ Private data destructor.
+***********************************************************************/
+
+static int pd_destructor(struct aio_private_data *pd)
+{
+ DLIST_REMOVE(pd_list, pd);
+ return 0;
+}
+
+/************************************************************************
+ Create and initialize a private data struct.
+***********************************************************************/
+
+static struct aio_private_data *create_private_data(TALLOC_CTX *ctx,
+ SMB_STRUCT_AIOCB *aiocb)
+{
+ struct aio_private_data *pd = talloc_zero(ctx, struct aio_private_data);
+ if (!pd) {
+ return NULL;
+ }
+ pd->jobid = aio_pthread_jobid++;
+ pd->aiocb = aiocb;
+ pd->ret_size = -1;
+ pd->ret_errno = EINPROGRESS;
+ talloc_set_destructor(pd, pd_destructor);
+ DLIST_ADD_END(pd_list, pd, struct aio_private_data *);
+ return pd;
+}
+
+/************************************************************************
+ Spin off a threadpool (if needed) and initiate a pread call.
+***********************************************************************/
+
+static int aio_pthread_read(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ SMB_STRUCT_AIOCB *aiocb)
+{
+ struct aio_extra *aio_ex = (struct aio_extra *)aiocb->aio_sigevent.sigev_value.sival_ptr;
+ struct aio_private_data *pd = NULL;
+ int ret;
+
+ if (!init_aio_threadpool(handle)) {
+ return -1;
+ }
+
+ pd = create_private_data(aio_ex, aiocb);
+ if (pd == NULL) {
+ DEBUG(10, ("aio_pthread_read: Could not create private data.\n"));
+ return -1;
+ }
+
+ ret = pthreadpool_add_job(pool, pd->jobid, aio_worker, (void *)pd);
--
Samba Shared Repository
More information about the samba-cvs
mailing list