summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount/fuse')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c198
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h43
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c71
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in1
-rwxr-xr-xxlators/mount/fuse/utils/mount_glusterfs.in9
5 files changed, 207 insertions, 115 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 3df1135a2ed..0e22fe411ee 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -8,6 +8,8 @@
cases as published by the Free Software Foundation.
*/
+#include <config.h>
+
#include <sys/wait.h>
#include "fuse-bridge.h"
#include <glusterfs/glusterfs.h>
@@ -177,7 +179,7 @@ fusedump_gettime(struct fusedump_timespec *fts)
0,
};
- clock_gettime(CLOCK_REALTIME, &ts);
+ timespec_now_realtime(&ts);
fts->sec = ts.tv_sec;
fts->nsec = ts.tv_nsec;
@@ -225,14 +227,30 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
if (res == -1) {
const char *errdesc = NULL;
gf_loglevel_t loglevel = GF_LOG_ERROR;
+ gf_boolean_t errno_degraded = _gf_false;
+ gf_boolean_t errno_promoted = _gf_false;
+
+#define ACCOUNT_ERRNO(eno) \
+ do { \
+ if (errno_degraded) { \
+ pthread_mutex_lock(&priv->fusedev_errno_cnt_mutex); \
+ { \
+ if (!++priv->fusedev_errno_cnt[FUSEDEV_##eno]) \
+ errno_promoted = _gf_true; \
+ } \
+ pthread_mutex_unlock(&priv->fusedev_errno_cnt_mutex); \
+ } \
+ } while (0)
/* If caller masked the errno, then it
* does not indicate an error at the application
* level, so we degrade the log severity to DEBUG.
*/
if (errnomask && errno < ERRNOMASK_MAX &&
- GET_ERRNO_MASK(errnomask, errno))
+ GET_ERRNO_MASK(errnomask, errno)) {
loglevel = GF_LOG_DEBUG;
+ errno_degraded = _gf_true;
+ }
switch (errno) {
/* The listed errnos are FUSE status indicators,
@@ -242,33 +260,43 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
*/
case ENOENT:
errdesc = "ENOENT";
+ ACCOUNT_ERRNO(ENOENT);
break;
case ENOTDIR:
errdesc = "ENOTDIR";
+ ACCOUNT_ERRNO(ENOTDIR);
break;
case ENODEV:
errdesc = "ENODEV";
+ ACCOUNT_ERRNO(ENODEV);
break;
case EPERM:
errdesc = "EPERM";
+ ACCOUNT_ERRNO(EPERM);
break;
case ENOMEM:
errdesc = "ENOMEM";
+ ACCOUNT_ERRNO(ENOMEM);
break;
case ENOTCONN:
errdesc = "ENOTCONN";
+ ACCOUNT_ERRNO(ENOTCONN);
break;
case ECONNREFUSED:
errdesc = "ECONNREFUSED";
+ ACCOUNT_ERRNO(ECONNREFUSED);
break;
case EOVERFLOW:
errdesc = "EOVERFLOW";
+ ACCOUNT_ERRNO(EOVERFLOW);
break;
case EBUSY:
errdesc = "EBUSY";
+ ACCOUNT_ERRNO(EBUSY);
break;
case ENOTEMPTY:
errdesc = "ENOTEMPTY";
+ ACCOUNT_ERRNO(ENOTEMPTY);
break;
default:
errdesc = strerror(errno);
@@ -276,7 +304,13 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
gf_log_callingfn("glusterfs-fuse", loglevel,
"writing to fuse device failed: %s", errdesc);
+ if (errno_promoted)
+ gf_log("glusterfs-fuse", GF_LOG_WARNING,
+ "writing to fuse device yielded %s %d times", errdesc,
+ UINT8_MAX + 1);
return errno;
+
+#undef ACCOUNT_ERRNO
}
fouh = iov_out[0].iov_base;
@@ -373,7 +407,7 @@ send_fuse_data(xlator_t *this, fuse_in_header_t *finh, void *data, size_t size)
static int32_t
fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino)
{
-#if FUSE_KERNEL_MINOR_VERSION >= 11
+#if (FUSE_KERNEL_MINOR_VERSION >= 11 && defined(HAVE_FUSE_NOTIFICATIONS))
struct fuse_out_header *fouh = NULL;
struct fuse_notify_inval_entry_out *fnieo = NULL;
fuse_private_t *priv = NULL;
@@ -464,7 +498,7 @@ fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino)
static int32_t
fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino)
{
-#if FUSE_KERNEL_MINOR_VERSION >= 11
+#if (FUSE_KERNEL_MINOR_VERSION >= 11 && defined(HAVE_FUSE_NOTIFICATIONS))
struct fuse_out_header *fouh = NULL;
struct fuse_notify_inval_inode_out *fniio = NULL;
fuse_private_t *priv = NULL;
@@ -799,18 +833,22 @@ fuse_interrupt_finish_fop(call_frame_t *frame, xlator_t *this,
{
intstat_orig = fir->interrupt_state;
if (fir->interrupt_state == INTERRUPT_NONE) {
- fir->interrupt_state = INTERRUPT_SQUELCHED;
if (sync) {
- while (fir->interrupt_state == INTERRUPT_NONE) {
+ fir->interrupt_state = INTERRUPT_WAITING_HANDLER;
+ while (fir->interrupt_state != INTERRUPT_SQUELCHED) {
pthread_cond_wait(&fir->handler_cond,
&fir->handler_mutex);
}
- }
+ } else
+ fir->interrupt_state = INTERRUPT_SQUELCHED;
}
}
pthread_mutex_unlock(&fir->handler_mutex);
}
+ GF_ASSERT(intstat_orig == INTERRUPT_NONE ||
+ intstat_orig == INTERRUPT_HANDLED ||
+ intstat_orig == INTERRUPT_SQUELCHED);
gf_log("glusterfs-fuse", GF_LOG_DEBUG, "intstat_orig=%d", intstat_orig);
/*
@@ -860,19 +898,29 @@ fuse_interrupt_finish_interrupt(xlator_t *this, fuse_interrupt_record_t *fir,
};
fuse_interrupt_state_t intstat_orig = INTERRUPT_NONE;
+ GF_ASSERT(intstat == INTERRUPT_HANDLED || intstat == INTERRUPT_SQUELCHED);
+
pthread_mutex_lock(&fir->handler_mutex);
{
intstat_orig = fir->interrupt_state;
- if (fir->interrupt_state == INTERRUPT_NONE) {
- fir->interrupt_state = intstat;
- if (sync) {
+ switch (intstat_orig) {
+ case INTERRUPT_NONE:
+ fir->interrupt_state = intstat;
+ break;
+ case INTERRUPT_WAITING_HANDLER:
+ fir->interrupt_state = INTERRUPT_SQUELCHED;
pthread_cond_signal(&fir->handler_cond);
- }
+ break;
+ default:
+ break;
}
finh = fir->fuse_in_header;
}
pthread_mutex_unlock(&fir->handler_mutex);
+ GF_ASSERT(intstat_orig == INTERRUPT_NONE ||
+ (sync && intstat_orig == INTERRUPT_WAITING_HANDLER) ||
+ (!sync && intstat_orig == INTERRUPT_SQUELCHED));
gf_log("glusterfs-fuse", GF_LOG_DEBUG, "intstat_orig=%d", intstat_orig);
/*
@@ -2185,7 +2233,6 @@ fuse_mknod(xlator_t *this, fuse_in_header_t *finh, void *msg,
fuse_state_t *state = NULL;
#if FUSE_KERNEL_MINOR_VERSION >= 12
fuse_private_t *priv = NULL;
- int32_t ret = -1;
priv = this->private;
if (priv->proto_minor < 12)
@@ -2257,7 +2304,6 @@ fuse_mkdir(xlator_t *this, fuse_in_header_t *finh, void *msg,
char *name = (char *)(fmi + 1);
#if FUSE_KERNEL_MINOR_VERSION >= 12
fuse_private_t *priv = NULL;
- int32_t ret = -1;
#endif
fuse_state_t *state;
@@ -2783,7 +2829,6 @@ fuse_create(xlator_t *this, fuse_in_header_t *finh, void *msg,
#if FUSE_KERNEL_MINOR_VERSION >= 12
struct fuse_create_in *fci = msg;
fuse_private_t *priv = NULL;
- int32_t ret = -1;
#else
struct fuse_open_in *fci = msg;
#endif
@@ -3381,6 +3426,8 @@ fuse_release(xlator_t *this, fuse_in_header_t *finh, void *msg,
gf_log("glusterfs-fuse", GF_LOG_TRACE,
"finh->unique: %" PRIu64 ": RELEASE %p", finh->unique, state->fd);
+ fd_close(state->fd);
+
fuse_fd_ctx_destroy(this, state->fd);
fd_unref(fd);
@@ -4690,12 +4737,10 @@ fuse_setlk_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
fuse_state_t *state = NULL;
int ret = 0;
- ret = fuse_interrupt_finish_fop(frame, this, _gf_false, (void **)&state);
- if (state) {
- GF_FREE(state->name);
- dict_unref(state->xdata);
- GF_FREE(state);
- }
+ ret = fuse_interrupt_finish_fop(frame, this, _gf_true, (void **)&state);
+ GF_FREE(state->name);
+ dict_unref(state->xdata);
+ GF_FREE(state);
if (ret) {
return 0;
}
@@ -4751,28 +4796,12 @@ fuse_setlk_interrupt_handler_cbk(call_frame_t *frame, void *cookie,
int32_t op_errno, dict_t *dict, dict_t *xdata)
{
fuse_interrupt_state_t intstat = INTERRUPT_NONE;
- fuse_interrupt_record_t *fir;
- fuse_state_t *state = NULL;
- int ret = 0;
-
- ret = dict_get_bin(xdata, "fuse-interrupt-record", (void **)&fir);
- if (ret < 0) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR, "interrupt record not found");
-
- goto out;
- }
+ fuse_interrupt_record_t *fir = cookie;
intstat = op_ret >= 0 ? INTERRUPT_HANDLED : INTERRUPT_SQUELCHED;
- fuse_interrupt_finish_interrupt(this, fir, intstat, _gf_false,
- (void **)&state);
- if (state) {
- GF_FREE(state->name);
- dict_unref(state->xdata);
- GF_FREE(state);
- }
+ fuse_interrupt_finish_interrupt(this, fir, intstat, _gf_true, NULL);
-out:
STACK_DESTROY(frame->root);
return 0;
@@ -4810,9 +4839,10 @@ fuse_setlk_interrupt_handler(xlator_t *this, fuse_interrupt_record_t *fir)
frame->op = GF_FOP_GETXATTR;
state->name = xattr_name;
- STACK_WIND(frame, fuse_setlk_interrupt_handler_cbk, state->active_subvol,
- state->active_subvol->fops->fgetxattr, state->fd, xattr_name,
- state->xdata);
+ STACK_WIND_COOKIE(frame, fuse_setlk_interrupt_handler_cbk, fir,
+ state->active_subvol,
+ state->active_subvol->fops->fgetxattr, state->fd,
+ xattr_name, state->xdata);
return;
@@ -4835,15 +4865,9 @@ fuse_setlk_resume(fuse_state_t *state)
fir = fuse_interrupt_record_new(state->finh, fuse_setlk_interrupt_handler);
state_clone = gf_memdup(state, sizeof(*state));
if (state_clone) {
- /*
- * Calling this allocator with fir casted to (char *) seems like
- * an abuse of this API, but in fact the API is stupid to assume
- * a (char *) argument (in the funcion it's casted to (void *)
- * anyway).
- */
- state_clone->xdata = dict_for_key_value(
- "fuse-interrupt-record", (char *)fir, sizeof(*fir), _gf_true);
+ state_clone->xdata = dict_new();
}
+
if (!fir || !state_clone || !state_clone->xdata) {
if (fir) {
GF_FREE(fir);
@@ -4901,7 +4925,7 @@ fuse_setlk(xlator_t *this, fuse_in_header_t *finh, void *msg,
return;
}
-#if FUSE_KERNEL_MINOR_VERSION >= 11
+#if FUSE_KERNEL_MINOR_VERSION >= 11 && defined(HAVE_FUSE_NOTIFICATIONS)
static void *
notify_kernel_loop(void *data)
{
@@ -5148,6 +5172,7 @@ fuse_init(xlator_t *this, fuse_in_header_t *finh, void *msg,
priv->timed_response_fuse_thread_started = _gf_true;
/* Used for 'reverse invalidation of inode' */
+#ifdef HAVE_FUSE_NOTIFICATIONS
if (fini->minor >= 12) {
ret = gf_thread_create(&messenger, NULL, notify_kernel_loop, this,
"fusenoti");
@@ -5159,7 +5184,9 @@ fuse_init(xlator_t *this, fuse_in_header_t *finh, void *msg,
goto out;
}
priv->reverse_fuse_thread_started = _gf_true;
- } else {
+ } else
+#endif
+ {
/*
* FUSE minor < 12 does not implement invalidate notifications.
* This mechanism is required for fopen-keep-cache to operate
@@ -5586,6 +5613,7 @@ fuse_migrate_fd(xlator_t *this, fd_t *basefd, xlator_t *old_subvol,
char create_in_progress = 0;
fuse_fd_ctx_t *basefd_ctx = NULL;
fd_t *oldfd = NULL;
+ dict_t *xdata = NULL;
basefd_ctx = fuse_fd_ctx_get(this, basefd);
GF_VALIDATE_OR_GOTO("glusterfs-fuse", basefd_ctx, out);
@@ -5622,10 +5650,23 @@ fuse_migrate_fd(xlator_t *this, fd_t *basefd, xlator_t *old_subvol,
}
if (oldfd->inode->table->xl == old_subvol) {
- if (IA_ISDIR(oldfd->inode->ia_type))
+ if (IA_ISDIR(oldfd->inode->ia_type)) {
ret = syncop_fsyncdir(old_subvol, oldfd, 0, NULL, NULL);
- else
- ret = syncop_fsync(old_subvol, oldfd, 0, NULL, NULL, NULL, NULL);
+ } else {
+ xdata = dict_new();
+ if (!xdata || dict_set_int8(xdata, "last-fsync", 1)) {
+ gf_log("glusterfs-fuse", GF_LOG_WARNING,
+ "last-fsync set failed (%s) on fd (%p)"
+ "(basefd:%p basefd-inode.gfid:%s) "
+ "(old-subvolume:%s-%d new-subvolume:%s-%d)",
+ strerror(ENOMEM), oldfd, basefd,
+ uuid_utoa(basefd->inode->gfid), old_subvol->name,
+ old_subvol->graph->id, new_subvol->name,
+ new_subvol->graph->id);
+ }
+
+ ret = syncop_fsync(old_subvol, oldfd, 0, NULL, NULL, xdata, NULL);
+ }
if (ret < 0) {
gf_log("glusterfs-fuse", GF_LOG_WARNING,
@@ -5680,6 +5721,9 @@ out:
fd_unref(oldfd);
+ if (xdata)
+ dict_unref(xdata);
+
return ret;
}
@@ -5855,7 +5899,9 @@ fuse_graph_sync(xlator_t *this)
new_graph_id = priv->next_graph->id;
priv->next_graph = NULL;
need_first_lookup = 1;
- priv->handle_graph_switch = _gf_true;
+ if (old_subvol) {
+ priv->handle_graph_switch = _gf_true;
+ }
while (!priv->event_recvd) {
ret = pthread_cond_wait(&priv->sync_cond, &priv->sync_mutex);
@@ -5891,13 +5937,6 @@ unlock:
if (winds_on_old_subvol == 0) {
xlator_notify(old_subvol, GF_EVENT_PARENT_DOWN, old_subvol, NULL);
}
- } else {
- pthread_mutex_lock(&priv->sync_mutex);
- {
- priv->handle_graph_switch = _gf_false;
- pthread_cond_broadcast(&priv->migrate_cond);
- }
- pthread_mutex_unlock(&priv->sync_mutex);
}
return 0;
@@ -6284,14 +6323,12 @@ out:
int
dump_history_fuse(circular_buffer_t *cb, void *data)
{
- char timestr[256] = {
+ char timestr[GF_TIMESTR_SIZE] = {
0,
};
- gf_time_fmt(timestr, sizeof timestr, cb->tv.tv_sec, gf_timefmt_F_HMS);
+ gf_time_fmt_tv(timestr, sizeof timestr, &cb->tv, gf_timefmt_F_HMS);
- snprintf(timestr + strlen(timestr), 256 - strlen(timestr),
- ".%" GF_PRI_SUSECONDS, cb->tv.tv_usec);
gf_proc_dump_write("TIME", "%s", timestr);
gf_proc_dump_write("message", "%s\n", (char *)cb->data);
@@ -6374,6 +6411,7 @@ notify(xlator_t *this, int32_t event, void *data, ...)
fuse_private_t *private = NULL;
gf_boolean_t start_thread = _gf_false;
glusterfs_graph_t *graph = NULL;
+ struct pollfd pfd = {0};
private
= this->private;
@@ -6441,6 +6479,32 @@ notify(xlator_t *this, int32_t event, void *data, ...)
/* Authentication failure is an error and glusterfs should stop */
gf_log(this->name, GF_LOG_ERROR,
"Server authenication failed. Shutting down.");
+ pthread_mutex_lock(&private->sync_mutex);
+ {
+ /*Wait for mount to finish*/
+ if (!private->mount_finished) {
+ pfd.fd = private->status_pipe[0];
+ pfd.events = POLLIN | POLLHUP | POLLERR;
+ if (poll(&pfd, 1, -1) < 0) {
+ gf_log(this->name, GF_LOG_ERROR, "poll error %s",
+ strerror(errno));
+ goto auth_fail_unlock;
+ }
+ if (pfd.revents & POLLIN) {
+ if (fuse_get_mount_status(this) != 0) {
+ goto auth_fail_unlock;
+ }
+ private
+ ->mount_finished = _gf_true;
+ } else if (pfd.revents) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "mount pipe closed without status");
+ goto auth_fail_unlock;
+ }
+ }
+ }
+ auth_fail_unlock:
+ pthread_mutex_unlock(&private->sync_mutex);
fini(this);
break;
}
@@ -6644,6 +6708,8 @@ init(xlator_t *this_xl)
INIT_LIST_HEAD(&priv->interrupt_list);
pthread_mutex_init(&priv->interrupt_mutex, NULL);
+ pthread_mutex_init(&priv->fusedev_errno_cnt_mutex, NULL);
+
/* get options from option dictionary */
ret = dict_get_str(options, ZR_MOUNTPOINT_OPT, &value_string);
if (ret == -1 || value_string == NULL) {
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index f4c6ad8f2fb..4cb94c23cad 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -78,6 +78,20 @@ typedef struct fuse_in_header fuse_in_header_t;
typedef void(fuse_handler_t)(xlator_t *this, fuse_in_header_t *finh, void *msg,
struct iobuf *iobuf);
+enum fusedev_errno {
+ FUSEDEV_ENOENT,
+ FUSEDEV_ENOTDIR,
+ FUSEDEV_ENODEV,
+ FUSEDEV_EPERM,
+ FUSEDEV_ENOMEM,
+ FUSEDEV_ENOTCONN,
+ FUSEDEV_ECONNREFUSED,
+ FUSEDEV_EOVERFLOW,
+ FUSEDEV_EBUSY,
+ FUSEDEV_ENOTEMPTY,
+ FUSEDEV_EMAXPLUS
+};
+
struct fuse_private {
int fd;
uint32_t proto_minor;
@@ -193,6 +207,10 @@ struct fuse_private {
uint32_t lru_limit;
uint32_t invalidate_limit;
uint32_t fuse_dev_eperm_ratelimit_ns;
+
+ /* counters for fusdev errnos */
+ uint8_t fusedev_errno_cnt[FUSEDEV_EMAXPLUS];
+ pthread_mutex_t fusedev_errno_cnt_mutex;
};
typedef struct fuse_private fuse_private_t;
@@ -226,6 +244,7 @@ enum fuse_interrupt_state {
INTERRUPT_NONE,
INTERRUPT_SQUELCHED,
INTERRUPT_HANDLED,
+ INTERRUPT_WAITING_HANDLER,
};
typedef enum fuse_interrupt_state fuse_interrupt_state_t;
struct fuse_interrupt_record;
@@ -341,30 +360,6 @@ typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
return; \
} \
state->umask = fci->umask; \
- \
- /* TODO: remove this after 3.4.0 release. keeping it for the \
- sake of backward compatibility with old (3.3.[01]) \
- releases till then. */ \
- ret = dict_set_int16(state->xdata, "umask", fci->umask); \
- if (ret < 0) { \
- gf_log("glusterfs-fuse", GF_LOG_WARNING, \
- "%s Failed adding umask" \
- " to request", \
- op); \
- send_fuse_err(this, finh, ENOMEM); \
- free_fuse_state(state); \
- return; \
- } \
- ret = dict_set_int16(state->xdata, "mode", fci->mode); \
- if (ret < 0) { \
- gf_log("glusterfs-fuse", GF_LOG_WARNING, \
- "%s Failed adding mode " \
- "to request", \
- op); \
- send_fuse_err(this, finh, ENOMEM); \
- free_fuse_state(state); \
- return; \
- } \
} \
} while (0)
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index fd11f2ba652..a2b0ad11fe4 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -139,8 +139,6 @@ get_fuse_state(xlator_t *this, fuse_in_header_t *finh)
return state;
}
-#define FUSE_MAX_AUX_GROUPS \
- 32 /* We can get only up to 32 aux groups from /proc */
void
frame_fill_groups(call_frame_t *frame)
{
@@ -150,8 +148,6 @@ frame_fill_groups(call_frame_t *frame)
char filename[32];
char line[4096];
char *ptr = NULL;
- FILE *fp = NULL;
- int idx = 0;
long int id = 0;
char *saveptr = NULL;
char *endptr = NULL;
@@ -191,45 +187,72 @@ frame_fill_groups(call_frame_t *frame)
call_stack_set_groups(frame->root, ngroups, &mygroups);
} else {
+ FILE *fp = NULL;
+
ret = snprintf(filename, sizeof filename, "/proc/%d/status",
frame->root->pid);
- if (ret >= sizeof filename)
+ if (ret >= sizeof filename) {
+ gf_log(this->name, GF_LOG_ERROR, "procfs path exceeds buffer size");
goto out;
+ }
fp = fopen(filename, "r");
- if (!fp)
+ if (!fp) {
+ gf_log(this->name, GF_LOG_ERROR, "failed to open %s: %s", filename,
+ strerror(errno));
goto out;
+ }
- if (call_stack_alloc_groups(frame->root, ngroups) != 0)
- goto out;
+ for (;;) {
+ gf_boolean_t found_groups = _gf_false;
+ int idx = 0;
- while ((ptr = fgets(line, sizeof line, fp))) {
- if (strncmp(ptr, "Groups:", 7) != 0)
- continue;
+ if (call_stack_alloc_groups(frame->root, ngroups) != 0) {
+ gf_log(this->name, GF_LOG_ERROR,
+ "failed to allocate gid buffer");
+ goto out;
+ }
+ while ((ptr = fgets(line, sizeof line, fp))) {
+ if (strncmp(ptr, "Groups:", 7) == 0) {
+ found_groups = _gf_true;
+ break;
+ }
+ }
+ if (!found_groups) {
+ gf_log(this->name, GF_LOG_ERROR, "cannot find gid list in %s",
+ filename);
+ break;
+ }
ptr = line + 8;
for (ptr = strtok_r(ptr, " \t\r\n", &saveptr); ptr;
ptr = strtok_r(NULL, " \t\r\n", &saveptr)) {
errno = 0;
id = strtol(ptr, &endptr, 0);
- if (errno == ERANGE)
- break;
- if (!endptr || *endptr)
+ if (errno == ERANGE || !endptr || *endptr) {
+ gf_log(this->name, GF_LOG_ERROR, "failed to parse %s",
+ filename);
break;
- frame->root->groups[idx++] = id;
- if (idx == FUSE_MAX_AUX_GROUPS)
+ }
+ if (idx < call_stack_groups_capacity(frame->root))
+ frame->root->groups[idx] = id;
+ idx++;
+ if (idx == GF_MAX_AUX_GROUPS)
break;
}
-
- frame->root->ngrps = idx;
- break;
+ if (idx > call_stack_groups_capacity(frame->root)) {
+ ngroups = idx;
+ rewind(fp);
+ } else {
+ frame->root->ngrps = idx;
+ break;
+ }
}
+ out:
+ if (fp)
+ fclose(fp);
}
-
-out:
- if (fp)
- fclose(fp);
#elif defined(GF_SOLARIS_HOST_OS)
char filename[32];
char scratch[128];
@@ -245,7 +268,7 @@ out:
fp = fopen(filename, "r");
if (fp != NULL) {
if (fgets(scratch, sizeof scratch, fp) != NULL) {
- ngrps = MIN(prcred->pr_ngroups, FUSE_MAX_AUX_GROUPS);
+ ngrps = MIN(prcred->pr_ngroups, GF_MAX_AUX_GROUPS);
if (call_stack_alloc_groups(frame->root, ngrps) != 0) {
fclose(fp);
return;
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index 99513b4e8c3..ac4d94cb743 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -776,6 +776,7 @@ main ()
[ $(echo $volume_str_temp | grep -c "/") -eq 1 ] &&
[ "$volume_id_temp" != "snaps" ] && {
volume_id=$volume_id_temp;
+ [ ${first_char} = '/' ] && volume_id=/$volume_id;
subdir_mount=$(echo "$volume_str_temp" | cut -f2- -d '/');
}
}
diff --git a/xlators/mount/fuse/utils/mount_glusterfs.in b/xlators/mount/fuse/utils/mount_glusterfs.in
index d43fc97d084..3a5feb606d7 100755
--- a/xlators/mount/fuse/utils/mount_glusterfs.in
+++ b/xlators/mount/fuse/utils/mount_glusterfs.in
@@ -469,6 +469,7 @@ parse_options()
main ()
{
+#if !defined(__FreeBSD__)
## `mount` on OSX specifies options as first argument
echo $1|grep -q -- "-o"
if [ $? -eq 0 ]; then
@@ -478,7 +479,7 @@ main ()
volfile_loc=$1
mount_point=$2
fi
-
+#endif /* __FreeBSD__ */
while getopts "Vo:h" opt; do
case "${opt}" in
o)
@@ -499,6 +500,12 @@ main ()
esac
done
+#ifdef __FreeBSD__
+ shift $((OPTIND - 1))
+ volfile_loc="$1"
+ mount_point="$2"
+#endif /* __FreeBSD__ */
+
[ -r "$volfile_loc" ] || {
# '%' included to support ipv6 link local addresses
server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:%.\-]*\):.*/\1/p');