summaryrefslogtreecommitdiffstats
path: root/mod_glusterfs/apache/1.3/src
diff options
context:
space:
mode:
Diffstat (limited to 'mod_glusterfs/apache/1.3/src')
-rw-r--r--mod_glusterfs/apache/1.3/src/Makefile.am30
-rw-r--r--mod_glusterfs/apache/1.3/src/README.txt107
-rw-r--r--mod_glusterfs/apache/1.3/src/mod_glusterfs.c514
3 files changed, 651 insertions, 0 deletions
diff --git a/mod_glusterfs/apache/1.3/src/Makefile.am b/mod_glusterfs/apache/1.3/src/Makefile.am
new file mode 100644
index 00000000..6bb3075f
--- /dev/null
+++ b/mod_glusterfs/apache/1.3/src/Makefile.am
@@ -0,0 +1,30 @@
+mod_glusterfs_PROGRAMS = mod_glusterfs.so
+mod_glusterfsdir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/apache/1.3
+
+mod_glusterfs_so_SOURCES = mod_glusterfs.c
+
+all: mod_glusterfs.so
+
+mod_glusterfs.so: $(top_srcdir)/mod_glusterfs/apache/1.3/src/mod_glusterfs.c $(top_builddir)/libglusterfsclient/src/libglusterfsclient.la
+ ln -sf $(top_srcdir)/mod_glusterfs/apache/1.3/src/mod_glusterfs.c $(top_builddir)/mod_glusterfs/apache/1.3/src/mod_glusterfs-build.c
+ $(APXS) -c -Wc,-g3 -Wc,-O0 -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 -D_GNU_SOURCE -I$(top_srcdir)/libglusterfsclient/src -Wl,-rpath,$(libdir) -Wl,-rpath,$(top_builddir)/libglusterfsclient/src/.libs/ $(top_builddir)/libglusterfsclient/src/.libs/libglusterfsclient.so mod_glusterfs-build.c -o $(top_builddir)/mod_glusterfs/apache/1.3/src/mod_glusterfs.so
+
+$(top_builddir)/libglusterfsclient/src/libglusterfsclient.la:
+ $(MAKE) -C $(top_builddir)/libglusterfsclient/src/ all
+
+install-data-local:
+ @echo ""
+ @echo ""
+ @echo "**********************************************************************************"
+ @echo "* TO INSTALL MODGLUSTERFS, PLEASE USE, "
+ @echo "* $(APXS) -n glusterfs -ia $(mod_glusterfsdir)/mod_glusterfs.so "
+ @echo "**********************************************************************************"
+ @echo ""
+ @echo ""
+
+#install:
+# cp -fv mod_glusterfs.so $(HTTPD_LIBEXECDIR)
+# cp -fv httpd.conf $(HTTPD_CONF_DIR)
+
+clean:
+ -rm -fv *.so *.o mod_glusterfs-build.c
diff --git a/mod_glusterfs/apache/1.3/src/README.txt b/mod_glusterfs/apache/1.3/src/README.txt
new file mode 100644
index 00000000..378a51d7
--- /dev/null
+++ b/mod_glusterfs/apache/1.3/src/README.txt
@@ -0,0 +1,107 @@
+What is mod_glusterfs?
+======================
+* mod_glusterfs is a module for apache written for efficient serving of files from glusterfs.
+ mod_glusterfs interfaces with glusterfs using apis provided by libglusterfsclient.
+
+* this README speaks about installation of apache-1.3.x, where x is any minor version.
+
+Prerequisites for mod_glusterfs
+===============================
+Though mod_glusterfs has been written as a module, with an intent of making no changes to the way apache has
+been built, currently following points have to be taken care of:
+
+* module "so" has to be enabled, for apache to support modules.
+* since glusterfs is compiled with _FILE_OFFSET_BITS=64 and __USE_FILE_OFFSET64 flags, mod_glusterfs and apache
+ in turn have to be compiled with the above two flags.
+
+ $ tar xzvf apache-1.3.9.tar.gz
+ $ cd apache-1.3.9/
+ $ # add -D_FILE_OFFSET_BITS=64 -D__USE_FILE_OFFSET64 to EXTRA_CFLAGS in src/Configuration.
+ $ ./configure --prefix=/usr --enable-module=so
+ $ cd src
+ $ ./Configure
+ $ cd ../
+ $ make install
+ $ httpd -l | grep -i mod_so
+ mod_so.c
+
+* if multiple apache installations are present, make sure to pass --with-apxs=/path/to/apxs/of/proper/version to configure script while building glusterfs.
+
+Build/Install mod_glusterfs
+===========================
+* mod_glusterfs is provided with glusterfs--mainline--3.0 and all releases from the same branch.
+
+* building glusterfs also builds mod_glusterfs. But 'make install' of glusterfs installs mod_glusterfs.so to
+ glusterfs install directory instead of the apache modules directory.
+
+* 'make install' of glusterfs will print a message similar to the one given below, which is self explanatory.
+ Make sure to use apxs of proper apache version in case of multiple apache installations. This will copy
+ mod_glusterfs.so to modules directory of proper apache version and modify the appropriate httpd.conf to enable
+ mod_glusterfs.
+
+**********************************************************************************************
+* TO INSTALL MODGLUSTERFS, PLEASE USE,
+* apxs -n mod_glusterfs -ia /usr/lib/glusterfs/1.4.0pre2/apache-1.3/mod_glusterfs.so
+**********************************************************************************************
+
+Configuration
+=============
+* Following configuration has to be added to httpd.conf.
+
+ <Location "/glusterfs">
+ GlusterfsLogfile "/var/log/glusterfs/glusterfs.log"
+ GlusterfsLoglevel "warning"
+ GlusterfsVolumeSpecfile "/etc/glusterfs/glusterfs-client.spec"
+ GlusterfsCacheTimeout "600"
+ GlusterfsXattrFileSize "65536"
+ SetHandler "glusterfs-handler"
+ </Location>
+
+* GlusterfsVolumeSpecfile (COMPULSORY)
+ Path to the the glusterfs volume specification file.
+
+* GlusterfsLogfile (COMPULSORY)
+ Path to the glusterfs logfile.
+
+* GlusterfsLoglevel (OPTIONAL, default = warning)
+ Severity of messages that are to be logged. Allowed values are critical, error, warning, debug, none
+ in the decreasing order of severity.
+
+* GlusterfsCacheTimeOut (OPTIONAL, default = 0)
+ Timeout values for glusterfs stat and lookup cache.
+
+* GlusterfsXattrFileSize (OPTIONAL, default = 0)
+ Files with sizes upto and including this value are fetched through the extended attribute interface of
+ glusterfs rather than the usual open-read-close set of operations. For files of small sizes, it is recommended
+ to use extended attribute interface.
+
+* With the above configuration all the requests to httpd of the form www.example.org/glusterfs/path/to/file are
+ served from glusterfs.
+
+Miscellaneous points
+====================
+* httpd by default runs with username "nobody" and group "nogroup". Permissions of logfile and specfile have to
+ be set suitably.
+
+* Since mod_glusterfs runs with permissions of nobody.nogroup, glusterfs has to use only login based
+ authentication. See docs/authentication.txt for more details.
+
+* To copy the data served by httpd into glusterfs mountpoint, glusterfs can be started with the
+ volume-specification file provided to mod_glusterfs. Any tool like cp can then be used.
+
+* To run in gdb, apache has to be compiled with -lpthread, since libglusterfsclient is multithreaded.
+ If not on Linux gdb runs into errors like:
+ "Error while reading shared library symbols:
+ Cannot find new threads: generic error"
+
+* when used with ib-verbs transport, ib_verbs initialization fails.
+ reason for this is that apache runs as non-privileged user and the amount of memory that can be
+ locked by default is not sufficient for ib-verbs. to fix this, as root run,
+
+ # ulimit -l unlimited
+
+ and then start apache.
+
+TODO
+====
+* directory listing for the directories accessed through mod_glusterfs.
diff --git a/mod_glusterfs/apache/1.3/src/mod_glusterfs.c b/mod_glusterfs/apache/1.3/src/mod_glusterfs.c
new file mode 100644
index 00000000..e13d7762
--- /dev/null
+++ b/mod_glusterfs/apache/1.3/src/mod_glusterfs.c
@@ -0,0 +1,514 @@
+/*
+ Copyright (c) 2008 Z RESEARCH, Inc. <http://www.zresearch.com>
+ This file is part of GlusterFS.
+
+ GlusterFS 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.
+
+ GlusterFS 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, see
+ <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CORE_PRIVATE
+#define CORE_PRIVATE
+#endif
+
+#include <httpd.h>
+#include <http_config.h>
+#include <http_core.h>
+#include <http_request.h>
+#include <http_protocol.h>
+#include <http_log.h>
+#include <http_main.h>
+#include <util_script.h>
+#include <libglusterfsclient.h>
+#include <sys/uio.h>
+#include <pthread.h>
+
+#define GLUSTERFS_INVALID_LOGLEVEL "mod_glusterfs: Unrecognized log-level \"%s\", possible values are \"DEBUG|WARNING|ERROR|CRITICAL|NONE\"\n"
+
+#define GLUSTERFS_HANDLER "glusterfs-handler"
+#define GLUSTERFS_CHUNK_SIZE 131072
+
+module MODULE_VAR_EXPORT glusterfs_module;
+
+/*TODO: verify error returns to server core */
+
+typedef struct glusterfs_dir_config {
+ char *logfile;
+ char *loglevel;
+ char *specfile;
+ char *mount_dir;
+ char *buf;
+ size_t xattr_file_size;
+ uint32_t cache_timeout;
+ libglusterfs_handle_t handle;
+} glusterfs_dir_config_t;
+
+typedef struct glusterfs_async_local {
+ int op_ret;
+ int op_errno;
+ char async_read_complete;
+ off_t length;
+ off_t read_bytes;
+ glusterfs_read_buf_t *buf;
+ request_rec *request;
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+}glusterfs_async_local_t;
+
+#define GLUSTERFS_CMD_PERMS ACCESS_CONF
+
+static glusterfs_dir_config_t *
+mod_glusterfs_dconfig(request_rec *r)
+{
+ glusterfs_dir_config_t *dir_config = NULL;
+ if (r->per_dir_config != NULL) {
+ dir_config = ap_get_module_config (r->per_dir_config, &glusterfs_module);
+ }
+
+ return dir_config;
+}
+
+static
+const char *add_xattr_file_size(cmd_parms *cmd, void *dummy, char *arg)
+{
+ glusterfs_dir_config_t *dir_config = dummy;
+ dir_config->xattr_file_size = atoi (arg);
+ return NULL;
+}
+
+static
+const char *set_cache_timeout(cmd_parms *cmd, void *dummy, char *arg)
+{
+ glusterfs_dir_config_t *dir_config = dummy;
+ dir_config->cache_timeout = atoi (arg);
+ return NULL;
+}
+
+static
+const char *set_loglevel(cmd_parms *cmd, void *dummy, char *arg)
+{
+ glusterfs_dir_config_t *dir_config = dummy;
+ char *error = NULL;
+ if (strncasecmp (arg, "DEBUG", strlen ("DEBUG"))
+ && strncasecmp (arg, "WARNING", strlen ("WARNING"))
+ && strncasecmp (arg, "CRITICAL", strlen ("CRITICAL"))
+ && strncasecmp (arg, "NONE", strlen ("NONE"))
+ && strncasecmp (arg, "ERROR", strlen ("ERROR")))
+ error = GLUSTERFS_INVALID_LOGLEVEL;
+ else
+ dir_config->loglevel = arg;
+
+ return error;
+}
+
+static
+const char *add_logfile(cmd_parms *cmd, void *dummy, char *arg)
+{
+ glusterfs_dir_config_t *dir_config = dummy;
+ dir_config->logfile = arg;
+
+ return NULL;
+}
+
+static
+const char *add_specfile(cmd_parms *cmd, void *dummy, char *arg)
+{
+ glusterfs_dir_config_t *dir_config = dummy;
+
+ dir_config->specfile = arg;
+
+ return NULL;
+}
+
+static void *
+mod_glusterfs_create_dir_config(pool *p, char *dirspec)
+{
+ glusterfs_dir_config_t *dir_config = NULL;
+
+ dir_config = (glusterfs_dir_config_t *) ap_pcalloc(p, sizeof(*dir_config));
+
+ dir_config->mount_dir = dirspec;
+ dir_config->logfile = dir_config->specfile = (char *)0;
+ dir_config->loglevel = "warning";
+ dir_config->handle = (libglusterfs_handle_t) 0;
+ dir_config->cache_timeout = 0;
+ dir_config->buf = NULL;
+
+ return (void *) dir_config;
+}
+
+static void
+mod_glusterfs_child_init(server_rec *s, pool *p)
+{
+ void **urls = NULL;
+ int n, i;
+ core_server_config *mod_core_config = ap_get_module_config (s->module_config,
+ &core_module);
+ glusterfs_dir_config_t *dir_config = NULL;
+ glusterfs_init_ctx_t ctx;
+
+ n = mod_core_config->sec_url->nelts;
+ urls = (void **)mod_core_config->sec_url->elts;
+ for (i = 0; i < n; i++) {
+ dir_config = ap_get_module_config (urls[i], &glusterfs_module);
+
+ if (dir_config) {
+ memset (&ctx, 0, sizeof (ctx));
+
+ ctx.logfile = dir_config->logfile;
+ ctx.loglevel = dir_config->loglevel;
+ ctx.lookup_timeout = ctx.stat_timeout = dir_config->cache_timeout;
+ ctx.specfile = dir_config->specfile;
+
+ dir_config->handle = glusterfs_init (&ctx);
+ }
+ dir_config = NULL;
+ }
+}
+
+static void
+mod_glusterfs_child_exit(server_rec *s, pool *p)
+{
+ void **urls = NULL;
+ int n, i;
+ core_server_config *mod_core_config = ap_get_module_config (s->module_config,
+ &core_module);
+ glusterfs_dir_config_t *dir_config = NULL;
+
+ n = mod_core_config->sec_url->nelts;
+ urls = (void **)mod_core_config->sec_url->elts;
+ for (i = 0; i < n; i++) {
+ dir_config = ap_get_module_config (urls[i], &glusterfs_module);
+ if (dir_config && dir_config->handle) {
+ glusterfs_fini (dir_config->handle);
+ dir_config->handle = 0;
+ }
+ dir_config = NULL;
+ }
+}
+
+static int mod_glusterfs_fixup(request_rec *r)
+{
+ glusterfs_dir_config_t *dir_config = NULL;
+ int access_status;
+ int ret;
+ char *path = NULL;
+
+ dir_config = mod_glusterfs_dconfig(r);
+
+ if (dir_config && dir_config->mount_dir && !(strncmp (ap_pstrcat (r->pool, dir_config->mount_dir, "/", NULL), r->uri, strlen (dir_config->mount_dir) + 1) && !r->handler))
+ r->handler = ap_pstrdup (r->pool, GLUSTERFS_HANDLER);
+
+ if (!r->handler || (r->handler && strcmp (r->handler, GLUSTERFS_HANDLER)))
+ return DECLINED;
+
+ if (dir_config->mount_dir)
+ path = r->uri + strlen (dir_config->mount_dir);
+
+ memset (&r->finfo, 0, sizeof (r->finfo));
+
+ dir_config->buf = calloc (1, dir_config->xattr_file_size);
+ if (!dir_config->buf) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ ret = glusterfs_lookup (dir_config->handle, path, dir_config->buf,
+ dir_config->xattr_file_size, &r->finfo);
+
+ if (ret == -1 || r->finfo.st_size > dir_config->xattr_file_size || S_ISDIR (r->finfo.st_mode)) {
+ free (dir_config->buf);
+ dir_config->buf = NULL;
+
+ if (ret == -1) {
+ int error = HTTP_NOT_FOUND;
+ char *emsg = NULL;
+ if (r->path_info == NULL) {
+ emsg = ap_pstrcat(r->pool, strerror (errno), r->filename, NULL);
+ }
+ else {
+ emsg = ap_pstrcat(r->pool, strerror (errno), r->filename, r->path_info, NULL);
+ }
+ ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, r, "%s", emsg);
+ if (errno != ENOENT) {
+ error = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ return error;
+ }
+ }
+
+ if (r->uri && strlen (r->uri) && r->uri[strlen(r->uri) - 1] == '/')
+ r->handler = NULL;
+
+ r->filename = ap_pstrcat (r->pool, r->filename, r->path_info, NULL);
+
+ if ((access_status = ap_find_types(r)) != 0) {
+ return DECLINED;
+ }
+
+ return OK;
+}
+
+
+int
+mod_glusterfs_readv_async_cbk (glusterfs_read_buf_t *buf,
+ void *cbk_data)
+{
+ glusterfs_async_local_t *local = cbk_data;
+
+ pthread_mutex_lock (&local->lock);
+ {
+ local->async_read_complete = 1;
+ local->buf = buf;
+ pthread_cond_signal (&local->cond);
+ }
+ pthread_mutex_unlock (&local->lock);
+
+ return 0;
+}
+
+/* use read_async just to avoid memcpy of read buffer in libglusterfsclient */
+static int
+mod_glusterfs_read_async (request_rec *r, int fd, off_t offset, off_t length)
+{
+ glusterfs_async_local_t local;
+ off_t end;
+ int nbytes;
+ int complete;
+ pthread_cond_init (&local.cond, NULL);
+ pthread_mutex_init (&local.lock, NULL);
+
+ memset (&local, 0, sizeof (local));
+ local.request = r;
+
+ if (length > 0)
+ end = offset + length;
+
+ do {
+ glusterfs_read_buf_t *buf;
+ int i;
+ if (length > 0) {
+ nbytes = end - offset;
+ if (nbytes > GLUSTERFS_CHUNK_SIZE)
+ nbytes = GLUSTERFS_CHUNK_SIZE;
+ } else
+ nbytes = GLUSTERFS_CHUNK_SIZE;
+
+ glusterfs_read_async(fd,
+ nbytes,
+ offset,
+ mod_glusterfs_readv_async_cbk,
+ (void *)&local);
+
+ pthread_mutex_lock (&local.lock);
+ {
+ while (!local.async_read_complete) {
+ pthread_cond_wait (&local.cond, &local.lock);
+ }
+
+ local.op_ret = local.buf->op_ret;
+ local.op_errno = local.buf->op_errno;
+
+ local.async_read_complete = 0;
+ buf = local.buf;
+
+ if (length < 0)
+ complete = (local.buf->op_ret <= 0);
+ else {
+ local.read_bytes += local.buf->op_ret;
+ complete = ((local.read_bytes == length) || (local.buf->op_ret < 0));
+ }
+ }
+ pthread_mutex_unlock (&local.lock);
+
+ for (i = 0; i < buf->count; i++) {
+ if (ap_rwrite (buf->vector[i].iov_base, buf->vector[i].iov_len, r) < 0) {
+ local.op_ret = -1;
+ complete = 1;
+ break;
+ }
+ }
+
+ glusterfs_free (buf);
+
+ offset += nbytes;
+ } while (!complete);
+
+ return (local.op_ret < 0 ? SERVER_ERROR : OK);
+}
+
+/* TODO: to read blocks of size "length" from offset "offset" */
+/*
+ static int
+ mod_glusterfs_read_sync (request_rec *r, int fd, off_t offset, off_t length)
+ {
+ int error = OK;
+ off_t read_bytes;
+ char buf [GLUSTERFS_CHUNK_SIZE];
+
+ while ((read_bytes = glusterfs_read (fd, buf, GLUSTERFS_CHUNK_SIZE)) && read_bytes != -1) {
+ ap_rwrite (buf, read_bytes, r);
+ }
+ if (read_bytes) {
+ error = SERVER_ERROR;
+ }
+ return error;
+ }
+*/
+
+static int
+mod_glusterfs_handler(request_rec *r)
+{
+ glusterfs_dir_config_t *dir_config;
+ char *path = NULL;
+ int error = OK;
+ int rangestatus = 0;
+ int errstatus = OK;
+ int fd;
+
+ if (!r->handler || (r->handler && strcmp (r->handler, GLUSTERFS_HANDLER)))
+ return DECLINED;
+
+ if (r->uri[0] == '\0' || r->uri[strlen(r->uri) - 1] == '/') {
+ return DECLINED;
+ }
+
+ dir_config = mod_glusterfs_dconfig (r);
+
+ if (r->method_number != M_GET) {
+ return METHOD_NOT_ALLOWED;
+ }
+
+ if (!dir_config->handle) {
+ ap_log_rerror (APLOG_MARK, APLOG_ERR, r,
+ "glusterfs initialization failed\n");
+ return FORBIDDEN;
+ }
+
+ ap_update_mtime(r, r->finfo.st_mtime);
+ ap_set_last_modified(r);
+ ap_set_etag(r);
+ ap_table_setn(r->headers_out, "Accept-Ranges", "bytes");
+ if (((errstatus = ap_meets_conditions(r)) != OK)
+ || (errstatus = ap_set_content_length(r, r->finfo.st_size))) {
+ return errstatus;
+ }
+ rangestatus = ap_set_byterange(r);
+ ap_send_http_header(r);
+
+ if (r->finfo.st_size <= dir_config->xattr_file_size && dir_config->buf) {
+ if (!r->header_only) {
+ error = OK;
+ ap_log_rerror (APLOG_MARK, APLOG_NOTICE, r,
+ "fetching data from glusterfs through xattr interface\n");
+
+ if (!rangestatus) {
+ if (ap_rwrite (dir_config->buf, r->finfo.st_size, r) < 0) {
+ error = HTTP_INTERNAL_SERVER_ERROR;
+ }
+ } else {
+ long offset, length;
+ while (ap_each_byterange (r, &offset, &length)) {
+ if (ap_rwrite (dir_config->buf + offset, length, r) < 0) {
+ error = HTTP_INTERNAL_SERVER_ERROR;
+ break;
+ }
+ }
+ }
+ }
+
+ free (dir_config->buf);
+ dir_config->buf = NULL;
+
+ return error;
+ }
+
+ path = r->uri + strlen (dir_config->mount_dir);
+ fd = glusterfs_open (dir_config->handle, path , O_RDONLY, 0);
+
+ if (fd == 0) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "file permissions deny server access: %s", r->filename);
+ return FORBIDDEN;
+ }
+
+ if (!r->header_only) {
+ if (!rangestatus) {
+ mod_glusterfs_read_async (r, fd, 0, -1);
+ } else {
+ long offset, length;
+ while (ap_each_byterange(r, &offset, &length)) {
+ mod_glusterfs_read_async (r, fd, offset, length);
+ }
+ }
+ }
+
+ glusterfs_close (fd);
+ return error;
+}
+
+static const command_rec mod_glusterfs_cmds[] =
+{
+ {"GlusterfsLogfile", add_logfile, NULL,
+ GLUSTERFS_CMD_PERMS, TAKE1,
+ "Glusterfs Logfile"},
+ {"GlusterfsLoglevel", set_loglevel, NULL,
+ GLUSTERFS_CMD_PERMS, TAKE1,
+ "Glusterfs Loglevel:anyone of none, critical, error, warning, debug"},
+ {"GlusterfsCacheTimeout", set_cache_timeout, NULL,
+ GLUSTERFS_CMD_PERMS, TAKE1,
+ "Timeout value in seconds for caching lookups and stats"},
+ {"GlusterfsVolumeSpecfile", add_specfile, NULL,
+ GLUSTERFS_CMD_PERMS, TAKE1,
+ "Glusterfs Specfile required to access contents of this directory"},
+ {"GlusterfsXattrFileSize", add_xattr_file_size, NULL,
+ GLUSTERFS_CMD_PERMS, TAKE1,
+ "Maximum size of the file to be fetched using xattr interface of glusterfs"},
+ {NULL}
+};
+
+static const handler_rec mod_glusterfs_handlers[] =
+{
+ {GLUSTERFS_HANDLER, mod_glusterfs_handler},
+ {NULL}
+};
+
+module glusterfs_module =
+{
+ STANDARD_MODULE_STUFF,
+ NULL,
+ mod_glusterfs_create_dir_config, /* per-directory config creator */
+ NULL,
+ NULL, /* server config creator */
+ NULL, /* server config merger */
+ mod_glusterfs_cmds, /* command table */
+ mod_glusterfs_handlers, /* [7] list of handlers */
+ NULL, /* [2] filename-to-URI translation */
+ NULL, /* [5] check/validate user_id */
+ NULL, /* [6] check user_id is valid *here* */
+ NULL, /* [4] check access by host address */
+ NULL, /* [7] MIME type checker/setter */
+ mod_glusterfs_fixup, /* [8] fixups */
+ NULL, /* [10] logger */
+#if MODULE_MAGIC_NUMBER >= 19970103
+ NULL, /* [3] header parser */
+#endif
+#if MODULE_MAGIC_NUMBER >= 19970719
+ mod_glusterfs_child_init, /* process initializer */
+#endif
+#if MODULE_MAGIC_NUMBER >= 19970728
+ mod_glusterfs_child_exit, /* process exit/cleanup */
+#endif
+#if MODULE_MAGIC_NUMBER >= 19970902
+ NULL /* [1] post read_request handling */
+#endif
+};