summaryrefslogtreecommitdiffstats
path: root/booster
diff options
context:
space:
mode:
authorVikas Gorur <vikas@zresearch.com>2009-02-18 17:36:07 +0530
committerVikas Gorur <vikas@zresearch.com>2009-02-18 17:36:07 +0530
commit77adf4cd648dce41f89469dd185deec6b6b53a0b (patch)
tree02e155a5753b398ee572b45793f889b538efab6b /booster
parentf3b2e6580e5663292ee113c741343c8a43ee133f (diff)
Added all files
Diffstat (limited to 'booster')
-rw-r--r--booster/Makefile.am1
-rw-r--r--booster/src/Makefile.am17
-rw-r--r--booster/src/booster.c920
3 files changed, 938 insertions, 0 deletions
diff --git a/booster/Makefile.am b/booster/Makefile.am
new file mode 100644
index 00000000000..e1c45f3051c
--- /dev/null
+++ b/booster/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=src \ No newline at end of file
diff --git a/booster/src/Makefile.am b/booster/src/Makefile.am
new file mode 100644
index 00000000000..9b6e77f957d
--- /dev/null
+++ b/booster/src/Makefile.am
@@ -0,0 +1,17 @@
+xlatordir = $(libdir)/glusterfs/$(PACKAGE_VERSION)/xlator/performance
+
+ldpreload_PROGRAMS = glusterfs-booster.so
+ldpreloaddir = $(libdir)/glusterfs/
+glusterfs_booster_so_SOURCES = booster.c
+glusterfs_booster_so_CFLAGS = -I$(top_srcdir)/libglusterfsclient/src/ -D_GNU_SOURCE -D$(GF_HOST_OS) -fPIC -Wall \
+ -pthread $(GF_BOOSTER_CFLAGS)
+glusterfs_booster_so_CPPFLAGS = -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE \
+ -I$(top_srcdir)/libglusterfsclient/src \
+ -I$(top_srcdir)/libglusterfs/src -DDATADIR=\"$(localstatedir)\" \
+ -DCONFDIR=\"$(sysconfdir)/glusterfs\"
+glusterfs_booster_so_LDFLAGS = -shared -nostartfiles
+glusterfs_booster_so_LDADD = -L$(top_builddir)/libglusterfs/src -lglusterfs \
+ -L$(top_builddir)/libglusterfsclient/src -lglusterfsclient
+
+CLEANFILES =
+
diff --git a/booster/src/booster.c b/booster/src/booster.c
new file mode 100644
index 00000000000..cf5f7883cb9
--- /dev/null
+++ b/booster/src/booster.c
@@ -0,0 +1,920 @@
+/*
+ Copyright (c) 2007, 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 _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <libglusterfsclient.h>
+#include <list.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/xattr.h>
+#include <string.h>
+#include <assert.h>
+
+#ifndef GF_UNIT_KB
+#define GF_UNIT_KB 1024
+#endif
+
+#ifndef UNIX_PATH_MAX
+#define UNIX_PATH_MAX 108
+#endif
+
+struct _inode;
+struct _dict;
+struct _fd {
+ pid_t pid;
+ struct list_head inode_list;
+ struct _inode *inode;
+ struct _dict *ctx;
+ int32_t refcount;
+};
+
+typedef struct _fdtable fdtable_t;
+typedef struct _fd fd_t;
+
+
+inline void
+gf_fd_put (struct _fdtable *fdtable, int64_t fd);
+
+struct _fd *
+gf_fd_fdptr_get (struct _fdtable *fdtable, int64_t fd);
+
+struct _fdtable *
+gf_fd_fdtable_alloc (void);
+
+void
+gf_fd_fdtable_destroy (struct _fdtable *);
+
+int32_t
+gf_fd_unused_get (struct _fdtable *fdtable, struct _fd *fdptr);
+
+int32_t
+gf_fd_unused_get2 (struct _fdtable *fdtable, struct _fd *fdptr, int64_t fd);
+
+void
+fd_unref (struct _fd *fd);
+
+fd_t *
+fd_ref (struct _fd *fd);
+
+pid_t
+getpid (void);
+
+ssize_t
+write (int fd, const void *buf, size_t count);
+
+/* open, open64, creat */
+static int (*real_open) (const char *pathname, int flags, ...);
+static int (*real_open64) (const char *pathname, int flags, ...);
+static int (*real_creat) (const char *pathname, mode_t mode);
+
+/* read, readv, pread, pread64 */
+static ssize_t (*real_read) (int fd, void *buf, size_t count);
+static ssize_t (*real_readv) (int fd, const struct iovec *vector, int count);
+static ssize_t (*real_pread) (int fd, void *buf, size_t count, unsigned long offset);
+static ssize_t (*real_pread64) (int fd, void *buf, size_t count, uint64_t offset);
+
+/* write, writev, pwrite, pwrite64 */
+static ssize_t (*real_write) (int fd, const void *buf, size_t count);
+static ssize_t (*real_writev) (int fd, const struct iovec *vector, int count);
+static ssize_t (*real_pwrite) (int fd, const void *buf, size_t count, unsigned long offset);
+static ssize_t (*real_pwrite64) (int fd, const void *buf, size_t count, uint64_t offset);
+
+/* lseek, llseek, lseek64 */
+static off_t (*real_lseek) (int fildes, unsigned long offset, int whence);
+static off_t (*real_lseek64) (int fildes, uint64_t offset, int whence);
+
+/* close */
+static int (*real_close) (int fd);
+
+/* dup dup2 */
+static int (*real_dup) (int fd);
+static int (*real_dup2) (int oldfd, int newfd);
+
+static pid_t (*real_fork) (void);
+
+#define RESOLVE(sym) do { \
+ if (!real_##sym) \
+ real_##sym = dlsym (RTLD_NEXT, #sym); \
+ } while (0)
+
+/*TODO: set proper value */
+#define MOUNT_HASH_SIZE 256
+
+struct booster_mount {
+ dev_t st_dev;
+ libglusterfs_handle_t handle;
+ struct list_head device_list;
+};
+typedef struct booster_mount booster_mount_t;
+
+struct booster_mount_table {
+ pthread_mutex_t lock;
+ struct list_head *mounts;
+ int32_t hash_size;
+};
+typedef struct booster_mount_table booster_mount_table_t;
+
+static fdtable_t *booster_glfs_fdtable = NULL;
+static booster_mount_table_t *booster_mount_table = NULL;
+
+static int32_t
+booster_put_handle (booster_mount_table_t *table,
+ dev_t st_dev,
+ libglusterfs_handle_t handle)
+{
+ int32_t hash = 0;
+ booster_mount_t *mount = NULL, *tmp = NULL;
+ int32_t ret = 0;
+
+ mount = calloc (1, sizeof (*mount));
+ if (!mount) {
+ return -1;
+ }
+
+ // ERR_ABORT (mount);
+ INIT_LIST_HEAD (&mount->device_list);
+ mount->st_dev = st_dev;
+ mount->handle = handle;
+
+ hash = st_dev % table->hash_size;
+
+ pthread_mutex_lock (&table->lock);
+ {
+ list_for_each_entry (tmp, &table->mounts[hash], device_list) {
+ if (tmp->st_dev == st_dev) {
+ ret = -1;
+ errno = EEXIST;
+ goto unlock;
+ }
+ }
+
+ list_add (&mount->device_list, &table->mounts[hash]);
+ }
+unlock:
+ pthread_mutex_unlock (&table->lock);
+
+ return ret;
+}
+
+
+static inline long
+booster_get_glfs_fd (fdtable_t *fdtable, int fd)
+{
+ fd_t *glfs_fd = NULL;
+
+ glfs_fd = gf_fd_fdptr_get (fdtable, fd);
+ return (long) glfs_fd;
+}
+
+
+static inline void
+booster_put_glfs_fd (long glfs_fd)
+{
+ fd_unref ((fd_t *)glfs_fd);
+}
+
+
+static inline int32_t
+booster_get_unused_fd (fdtable_t *fdtable, long glfs_fd, int fd)
+{
+ int32_t ret = -1;
+ ret = gf_fd_unused_get2 (fdtable, (fd_t *)glfs_fd, fd);
+ return ret;
+}
+
+
+static inline void
+booster_put_fd (fdtable_t *fdtable, int fd)
+{
+ gf_fd_put (fdtable, fd);
+}
+
+
+static libglusterfs_handle_t
+booster_get_handle (booster_mount_table_t *table, dev_t st_dev)
+{
+ int32_t hash = 0;
+ booster_mount_t *mount = NULL;
+ libglusterfs_handle_t handle = NULL;
+
+ hash = st_dev % table->hash_size;
+
+ pthread_mutex_lock (&table->lock);
+ {
+ list_for_each_entry (mount, &table->mounts[hash], device_list) {
+ if (mount->st_dev == st_dev) {
+ handle = mount->handle;
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock (&table->lock);
+
+ return handle;
+}
+
+
+void
+do_open (int fd, int flags, mode_t mode)
+{
+ char *specfile = NULL;
+ libglusterfs_handle_t handle;
+ int32_t file_size;
+ struct stat st = {0,};
+ int32_t ret = -1;
+
+ ret = fstat (fd, &st);
+ if (ret == -1) {
+ return;
+ }
+
+ if (!booster_mount_table) {
+ return;
+ }
+
+ handle = booster_get_handle (booster_mount_table, st.st_dev);
+ if (!handle) {
+ FILE *specfp = NULL;
+
+ glusterfs_init_ctx_t ctx = {
+ .loglevel = "critical",
+ .lookup_timeout = 600,
+ .stat_timeout = 600,
+ };
+
+ file_size = fgetxattr (fd, "user.glusterfs-booster-volfile", NULL, 0);
+ if (file_size == -1) {
+ return;
+ }
+
+ specfile = calloc (1, file_size);
+ if (!specfile) {
+ fprintf (stderr, "cannot allocate memory: %s\n", strerror (errno));
+ return;
+ }
+
+ ret = fgetxattr (fd, "user.glusterfs-booster-volfile", specfile, file_size);
+ if (ret == -1) {
+ free (specfile);
+ return ;
+ }
+
+ specfp = tmpfile ();
+ if (!specfp) {
+ free (specfile);
+ return;
+ }
+
+ ret = fwrite (specfile, file_size, 1, specfp);
+ if (ret != 1) {
+ fclose (specfp);
+ free (specfile);
+ }
+
+ fseek (specfp, 0L, SEEK_SET);
+
+ ctx.logfile = getenv ("GLFS_BOOSTER_LOGFILE");
+ ctx.specfp = specfp;
+
+ handle = glusterfs_init (&ctx);
+
+ free (specfile);
+ fclose (specfp);
+
+ if (!handle) {
+ return;
+ }
+
+ ret = booster_put_handle (booster_mount_table, st.st_dev, handle);
+ if (ret == -1) {
+ glusterfs_fini (handle);
+ if (errno != EEXIST) {
+ return;
+ }
+ }
+ }
+
+ if (handle) {
+ long glfs_fd;
+ char path [UNIX_PATH_MAX];
+ ret = fgetxattr (fd, "user.glusterfs-booster-path", path, UNIX_PATH_MAX);
+ if (ret == -1) {
+ return;
+ }
+
+ glfs_fd = glusterfs_open (handle, path, flags, mode);
+ if (glfs_fd) {
+ ret = booster_get_unused_fd (booster_glfs_fdtable, glfs_fd, fd);
+ if (ret == -1) {
+ glusterfs_close (glfs_fd);
+ return;
+ }
+ }
+ }
+
+ return;
+}
+
+#ifndef __USE_FILE_OFFSET64
+int
+open (const char *pathname, int flags, ...)
+{
+ int ret;
+ mode_t mode = 0;
+ va_list ap;
+
+ if (flags & O_CREAT) {
+ va_start (ap, flags);
+ mode = va_arg (ap, mode_t);
+ va_end (ap);
+
+ ret = real_open (pathname, flags, mode);
+ } else {
+ ret = real_open (pathname, flags);
+ }
+
+ if (ret != -1) {
+ flags &= ~ O_CREAT;
+ do_open (ret, flags, mode);
+ }
+
+ return ret;
+}
+#endif
+
+#if defined (__USE_LARGEFILE64) || !defined (__USE_FILE_OFFSET64)
+int
+open64 (const char *pathname, int flags, ...)
+{
+ int ret;
+ mode_t mode = 0;
+ va_list ap;
+
+ if (flags & O_CREAT) {
+ va_start (ap, flags);
+ mode = va_arg (ap, mode_t);
+ va_end (ap);
+
+ ret = real_open64 (pathname, flags, mode);
+ } else {
+ ret = real_open64 (pathname, flags);
+ }
+
+ if (ret != -1) {
+ flags &= ~O_CREAT;
+ do_open (ret, flags, mode);
+ }
+
+ return ret;
+}
+#endif
+
+int
+creat (const char *pathname, mode_t mode)
+{
+ int ret;
+
+ ret = real_creat (pathname, mode);
+
+ if (ret != -1) {
+ do_open (ret, O_WRONLY | O_TRUNC, mode);
+ }
+
+ return ret;
+}
+
+
+/* pread */
+
+ssize_t
+pread (int fd, void *buf, size_t count, unsigned long offset)
+{
+ ssize_t ret;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+ if (!glfs_fd) {
+ ret = real_pread (fd, buf, count, offset);
+ } else {
+ ret = glusterfs_pread (glfs_fd, buf, count, offset);
+ if (ret == -1) {
+ ret = real_pread (fd, buf, count, offset);
+ }
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+
+ssize_t
+pread64 (int fd, void *buf, size_t count, uint64_t offset)
+{
+ ssize_t ret;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+ if (!glfs_fd) {
+ ret = real_pread (fd, buf, count, offset);
+ } else {
+ ret = glusterfs_pread (glfs_fd, buf, count, offset);
+ if (ret == -1) {
+ ret = real_pread (fd, buf, count, offset);
+ }
+ }
+
+ return ret;
+}
+
+
+ssize_t
+read (int fd, void *buf, size_t count)
+{
+ int ret;
+ long glfs_fd;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+ if (!glfs_fd) {
+ ret = real_read (fd, buf, count);
+ } else {
+ uint64_t offset = 0;
+ offset = real_lseek64 (fd, 0L, SEEK_CUR);
+ if ((int64_t)offset != -1) {
+ ret = glusterfs_lseek (glfs_fd, offset, SEEK_SET);
+ if (ret != -1) {
+ ret = glusterfs_read (glfs_fd, buf, count);
+ }
+ } else {
+ ret = -1;
+ }
+
+ if (ret == -1) {
+ ret = real_read (fd, buf, count);
+ }
+
+ if (ret > 0 && ((int64_t) offset) >= 0) {
+ real_lseek64 (fd, ret + offset, SEEK_SET);
+ }
+
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+
+ssize_t
+readv (int fd, const struct iovec *vector, int count)
+{
+ int ret;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+ if (!glfs_fd) {
+ ret = real_readv (fd, vector, count);
+ } else {
+ uint64_t offset = 0;
+ offset = real_lseek64 (fd, 0L, SEEK_CUR);
+ if ((int64_t)offset != -1) {
+ ret = glusterfs_lseek (glfs_fd, offset, SEEK_SET);
+ if (ret != -1) {
+ ret = glusterfs_readv (glfs_fd, vector, count);
+ }
+ } else {
+ ret = -1;
+ }
+
+ ret = glusterfs_readv (glfs_fd, vector, count);
+ if (ret > 0) {
+ real_lseek64 (fd, offset + ret, SEEK_SET);
+ }
+
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+
+ssize_t
+write (int fd, const void *buf, size_t count)
+{
+ int ret;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+
+ if (!glfs_fd) {
+ ret = real_write (fd, buf, count);
+ } else {
+ uint64_t offset = 0;
+ offset = real_lseek64 (fd, 0L, SEEK_CUR);
+ if (((int64_t) offset) != -1) {
+ ret = glusterfs_lseek (glfs_fd, offset, SEEK_SET);
+ if (ret != -1) {
+ ret = glusterfs_write (glfs_fd, buf, count);
+ }
+ } else {
+ ret = -1;
+ }
+
+ if (ret == -1) {
+ ret = real_write (fd, buf, count);
+ }
+
+ if (ret > 0 && ((int64_t) offset) >= 0) {
+ real_lseek64 (fd, offset + ret, SEEK_SET);
+ }
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+ssize_t
+writev (int fd, const struct iovec *vector, int count)
+{
+ int ret = 0;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+
+ if (!glfs_fd) {
+ ret = real_writev (fd, vector, count);
+ } else {
+ uint64_t offset = 0;
+ offset = real_lseek64 (fd, 0L, SEEK_CUR);
+
+ if (((int64_t) offset) != -1) {
+ ret = glusterfs_lseek (glfs_fd, offset, SEEK_SET);
+ if (ret != -1) {
+ ret = glusterfs_writev (glfs_fd, vector, count);
+ }
+ } else {
+ ret = -1;
+ }
+
+/* ret = glusterfs_writev (glfs_fd, vector, count); */
+ if (ret == -1) {
+ ret = real_writev (fd, vector, count);
+ }
+
+ if (ret > 0 && ((int64_t)offset) >= 0) {
+ real_lseek64 (fd, offset + ret, SEEK_SET);
+ }
+
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+
+ssize_t
+pwrite (int fd, const void *buf, size_t count, unsigned long offset)
+{
+ int ret;
+ long glfs_fd = 0;
+
+ assert (real_pwrite != NULL);
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+
+ if (!glfs_fd) {
+ ret = real_pwrite (fd, buf, count, offset);
+ } else {
+ ret = glusterfs_pwrite (glfs_fd, buf, count, offset);
+ if (ret == -1) {
+ ret = real_pwrite (fd, buf, count, offset);
+ }
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+
+ssize_t
+pwrite64 (int fd, const void *buf, size_t count, uint64_t offset)
+{
+ int ret;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+
+ if (!glfs_fd) {
+ ret = real_pwrite64 (fd, buf, count, offset);
+ } else {
+ ret = glusterfs_pwrite (glfs_fd, buf, count, offset);
+ if (ret == -1) {
+ ret = real_pwrite64 (fd, buf, count, offset);
+ }
+ }
+
+ return ret;
+}
+
+
+int
+close (int fd)
+{
+ int ret = -1;
+ long glfs_fd = 0;
+/* struct stat st = {0,}; */
+
+/* ret = fstat (fd, &st);
+ if (ret != -1) {
+ libglusterfs_handle_t handle = 0;
+ handle = booster_get_handle (booster_mount_table, st.st_dev);
+ if (handle) { */
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, fd);
+
+ if (glfs_fd) {
+ booster_put_fd (booster_glfs_fdtable, fd);
+ ret = glusterfs_close (glfs_fd);
+ booster_put_glfs_fd (glfs_fd);
+ }
+/*}
+ }*/
+
+ ret = real_close (fd);
+
+ return ret;
+}
+
+#ifndef _LSEEK_DECLARED
+#define _LSEEK_DECLARED
+off_t
+lseek (int filedes, unsigned long offset, int whence)
+{
+ int ret;
+ long glfs_fd = 0;
+
+ ret = real_lseek (filedes, offset, whence);
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, filedes);
+ if (glfs_fd) {
+ ret = glusterfs_lseek (glfs_fd, offset, whence);
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+#endif
+
+off_t
+lseek64 (int filedes, uint64_t offset, int whence)
+{
+ int ret;
+ long glfs_fd = 0;
+
+ ret = real_lseek64 (filedes, offset, whence);
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, filedes);
+ if (glfs_fd) {
+ ret = glusterfs_lseek (glfs_fd, offset, whence);
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return ret;
+}
+
+int
+dup (int oldfd)
+{
+ int ret = -1, new_fd = -1;
+ long glfs_fd = 0;
+
+ glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, oldfd);
+ new_fd = real_dup (oldfd);
+
+ if (new_fd >=0 && glfs_fd) {
+ ret = booster_get_unused_fd (booster_glfs_fdtable, glfs_fd, new_fd);
+ fd_ref ((fd_t *)glfs_fd);
+ if (ret == -1) {
+ real_close (new_fd);
+ }
+ }
+
+ if (glfs_fd) {
+ booster_put_glfs_fd (glfs_fd);
+ }
+
+ return new_fd;
+}
+
+
+int
+dup2 (int oldfd, int newfd)
+{
+ int ret = -1;
+ long old_glfs_fd = 0, new_glfs_fd = 0;
+
+ if (oldfd == newfd) {
+ return newfd;
+ }
+
+ old_glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, oldfd);
+ new_glfs_fd = booster_get_glfs_fd (booster_glfs_fdtable, newfd);
+
+ ret = real_dup2 (oldfd, newfd);
+ if (ret >= 0) {
+ if (new_glfs_fd) {
+ glusterfs_close (new_glfs_fd);
+ booster_put_glfs_fd (new_glfs_fd);
+ booster_put_fd (booster_glfs_fdtable, newfd);
+ new_glfs_fd = 0;
+ }
+
+ if (old_glfs_fd) {
+ ret = booster_get_unused_fd (booster_glfs_fdtable, old_glfs_fd, newfd);
+ fd_ref ((fd_t *)old_glfs_fd);
+ if (ret == -1) {
+ real_close (newfd);
+ }
+ }
+ }
+
+ if (old_glfs_fd) {
+ booster_put_glfs_fd (old_glfs_fd);
+ }
+
+ if (new_glfs_fd) {
+ booster_put_glfs_fd (new_glfs_fd);
+ }
+
+ return ret;
+}
+
+
+#define MOUNT_TABLE_HASH_SIZE 256
+
+
+static int
+booster_init (void)
+{
+ int i = 0;
+ booster_glfs_fdtable = gf_fd_fdtable_alloc ();
+ if (!booster_glfs_fdtable) {
+ fprintf (stderr, "cannot allocate fdtable: %s\n", strerror (errno));
+ goto err;
+ }
+
+ booster_mount_table = calloc (1, sizeof (*booster_mount_table));
+ if (!booster_mount_table) {
+ fprintf (stderr, "cannot allocate memory: %s\n", strerror (errno));
+ goto err;
+ }
+
+ pthread_mutex_init (&booster_mount_table->lock, NULL);
+ booster_mount_table->hash_size = MOUNT_TABLE_HASH_SIZE;
+ booster_mount_table->mounts = calloc (booster_mount_table->hash_size, sizeof (*booster_mount_table->mounts));
+ if (!booster_mount_table->mounts) {
+ fprintf (stderr, "cannot allocate memory: %s\n", strerror (errno));
+ goto err;
+ }
+
+ for (i = 0; i < booster_mount_table->hash_size; i++)
+ {
+ INIT_LIST_HEAD (&booster_mount_table->mounts[i]);
+ }
+
+ return 0;
+
+err:
+ if (booster_glfs_fdtable) {
+ gf_fd_fdtable_destroy (booster_glfs_fdtable);
+ booster_glfs_fdtable = NULL;
+ }
+
+ if (booster_mount_table) {
+ if (booster_mount_table->mounts) {
+ free (booster_mount_table->mounts);
+ }
+
+ free (booster_mount_table);
+ booster_mount_table = NULL;
+ }
+ return -1;
+}
+
+
+static void
+booster_cleanup (void)
+{
+ int i;
+ booster_mount_t *mount = NULL, *tmp = NULL;
+
+ /* gf_fd_fdtable_destroy (booster_glfs_fdtable);*/
+ /*for (i=0; i < booster_glfs_fdtable->max_fds; i++) {
+ if (booster_glfs_fdtable->fds[i]) {
+ fd_t *fd = booster_glfs_fdtable->fds[i];
+ free (fd);
+ }
+ }*/
+
+ free (booster_glfs_fdtable);
+ booster_glfs_fdtable = NULL;
+
+ pthread_mutex_lock (&booster_mount_table->lock);
+ {
+ for (i = 0; i < booster_mount_table->hash_size; i++)
+ {
+ list_for_each_entry_safe (mount, tmp,
+ &booster_mount_table->mounts[i], device_list) {
+ list_del (&mount->device_list);
+ glusterfs_fini (mount->handle);
+ free (mount);
+ }
+ }
+ free (booster_mount_table->mounts);
+ }
+ pthread_mutex_unlock (&booster_mount_table->lock);
+
+ glusterfs_reset ();
+ free (booster_mount_table);
+ booster_mount_table = NULL;
+}
+
+
+
+pid_t
+fork (void)
+{
+ pid_t pid = 0;
+ char child = 0;
+
+ glusterfs_log_lock ();
+ {
+ pid = real_fork ();
+ }
+ glusterfs_log_unlock ();
+
+ child = (pid == 0);
+ if (child) {
+ booster_cleanup ();
+ booster_init ();
+ }
+
+ return pid;
+}
+
+
+void
+_init (void)
+{
+ booster_init ();
+
+ RESOLVE (open);
+ RESOLVE (open64);
+ RESOLVE (creat);
+
+ RESOLVE (read);
+ RESOLVE (readv);
+ RESOLVE (pread);
+ RESOLVE (pread64);
+
+ RESOLVE (write);
+ RESOLVE (writev);
+ RESOLVE (pwrite);
+ RESOLVE (pwrite64);
+
+ RESOLVE (lseek);
+ RESOLVE (lseek64);
+
+ RESOLVE (close);
+
+ RESOLVE (dup);
+ RESOLVE (dup2);
+
+ RESOLVE (fork);
+}
+