diff options
Diffstat (limited to 'booster/src/booster.c')
-rw-r--r-- | booster/src/booster.c | 166 |
1 files changed, 146 insertions, 20 deletions
diff --git a/booster/src/booster.c b/booster/src/booster.c index 903ad8e8f37..026e03ce31c 100644 --- a/booster/src/booster.c +++ b/booster/src/booster.c @@ -38,12 +38,14 @@ #include <assert.h> #include <errno.h> #include <ctype.h> +#include <logging.h> #ifndef GF_UNIT_KB #define GF_UNIT_KB 1024 #endif +extern int pipe (int filedes[2]); /* We define these flags so that we can remove fcntl.h from the include path. * fcntl.h has certain defines and other lines of code that redirect the * application's open and open64 calls to the syscalls defined by @@ -172,6 +174,18 @@ 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; +/* This is dup'ed every time VMP open/creat wants a new fd. + * This is needed so we occupy an entry in the process' file + * table. + */ +int process_piped_fd = -1; + +static int +booster_get_process_fd () +{ + return real_dup (process_piped_fd); +} + #define DEFAULT_BOOSTER_CONF "/etc/booster.conf" int @@ -459,27 +473,138 @@ do_open (int fd, int flags, mode_t mode) } int -open (const char *pathname, int flags, ...) +vmp_open (const char *pathname, int flags, ...) { - int ret; - mode_t mode = 0; - va_list ap; + mode_t mode = 0; + int fd = -1; + glusterfs_file_t fh = NULL; + va_list ap; + + if (flags & GF_O_CREAT) { + va_start (ap, flags); + mode = va_arg (ap, mode_t); + va_end (ap); + + fh = glusterfs_open (pathname, flags, mode); + } + else + fh = glusterfs_open (pathname, flags); + + if (!fh) + goto out; + + fd = booster_get_process_fd (); + if (fd == -1) + goto fh_close_out; + + if (booster_get_unused_fd (booster_glfs_fdtable, fh, fd) == -1) + goto realfd_close_out; + + return fd; + +realfd_close_out: + real_close (fd); + fd = -1; + +fh_close_out: + glusterfs_close (fh); + +out: + return fd; +} + +#define BOOSTER_USE_OPEN64 1 +#define BOOSTER_DONT_USE_OPEN64 0 + +int +booster_open (const char *pathname, int use64, int flags, ...) +{ + int ret = -1; + mode_t mode = 0; + va_list ap; + int (*my_open) (const char *pathname, int flags, ...); + + if (!pathname) { + errno = EINVAL; + goto out; + } + + /* First try opening through the virtual mount point. + * The difference lies in the fact that: + * 1. We depend on libglusterfsclient library to perform + * the translation from the path to handle. + * 2. We do not go to the file system for the fd, instead + * we use booster_get_process_fd (), which returns a dup'ed + * fd of a pipe created in booster_init. + */ + if (flags & GF_O_CREAT) { + va_start (ap, flags); + mode = va_arg (ap, mode_t); + va_end (ap); + ret = vmp_open (pathname, flags, mode); + } + else + ret = vmp_open (pathname, flags); + + /* We receive an ENODEV if the VMP does not exist. If we + * receive an error other than ENODEV, it means, there + * actually was an error performing vmp_open. This must + * be returned to the user. + */ + if (((ret < 0) && (errno != ENODEV)) || (ret > 0)) + goto out; + + if (use64) + my_open = real_open64; + else + my_open = real_open; + + /* It is possible the RESOLVE macro is not able + * to resolve the symbol of a function, in that case + * we dont want to seg-fault on calling a NULL functor. + */ + if (my_open == NULL) { + ret = -1; + errno = ENOSYS; + goto out; + } if (flags & GF_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); - } + ret = my_open (pathname, flags, mode); + } else + ret = my_open (pathname, flags); if (ret != -1) { flags &= ~ GF_O_CREAT; do_open (ret, flags, mode); } +out: + return ret; +} + +int +open (const char *pathname, int flags, ...) +{ + int ret = -1; + mode_t mode = 0; + va_list ap; + + if (flags & GF_O_CREAT) { + va_start (ap, flags); + mode = va_arg (ap, mode_t); + va_end (ap); + + ret = booster_open (pathname, BOOSTER_DONT_USE_OPEN64, + flags, mode); + } + else + ret = booster_open (pathname, BOOSTER_DONT_USE_OPEN64, flags); + return ret; } @@ -491,20 +616,15 @@ open64 (const char *pathname, int flags, ...) mode_t mode = 0; va_list ap; - if (flags & GF_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 (flags & GF_O_CREAT) { + va_start (ap, flags); + mode = va_arg (ap, mode_t); + va_end (ap); - if (ret != -1) { - flags &= ~GF_O_CREAT; - do_open (ret, flags, mode); + ret = booster_open (pathname, BOOSTER_USE_OPEN64, flags, mode); } + else + ret = booster_open (pathname, BOOSTER_USE_OPEN64, flags); return ret; } @@ -891,6 +1011,7 @@ booster_init (void) int i = 0; char *booster_conf_path = NULL; int ret = -1; + int pipefd[2]; booster_glfs_fdtable = gf_fd_fdtable_alloc (); if (!booster_glfs_fdtable) { @@ -921,6 +1042,11 @@ booster_init (void) INIT_LIST_HEAD (&booster_mount_table->mounts[i]); } + if (pipe (pipefd) == -1) + goto err; + + process_piped_fd = pipefd[0]; + real_close (pipefd[1]); /* libglusterfsclient based VMPs should be inited only * after the file tables are inited so that if the socket * calls use the fd based syscalls, the fd tables are |