summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2012-07-16 13:51:09 -0400
committerVijay Bellur <vbellur@redhat.com>2012-12-12 00:12:01 -0500
commitf62a8026be3875afd38fb1899e1fa235c8f1a6fb (patch)
tree979e00e416f3bdcabce611f7d65d7a695651df5a
parent19a8495a01702b94343c8e252396a13f6d70d09d (diff)
libglusterfs,mount/fuse: implement gidcache mechanism in fuse-bridge
This change genericizes the cache mechanism implemented in commit 8efd2845 into libglusterfs/src/gidcache.[ch] and adds fuse-bridge as a client. The cache mechanism is fundamentally equivalent, with some minor changes: - Change cache key from uid_t to uint64_t. - Modify the cache add logic to locate and use an entry with a matching ID, should it already exist. This addresses a bug in the existing mechanism where an expired entry supercedes a newly added entry in lookup, causing repeated adds and flushing of a cache bucket. The fuse group cache is disabled by default. It can be enabled via the 'gid-timeout' fuse-bridge translator option and accompanying mount option (i.e., '-o gid-timeout=1' for a 1s entry timeout). BUG: 800892 Change-Id: I0b34a2263ca48dbb154790a4a44fc70b733e9114 Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-on: https://code.engineering.redhat.com/gerrit/1853 Reviewed-by: Vijay Bellur <vbellur@redhat.com> Tested-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--glusterfsd/src/glusterfsd.c22
-rw-r--r--glusterfsd/src/glusterfsd.h1
-rw-r--r--libglusterfs/src/Makefile.am5
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c13
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h3
-rw-r--r--xlators/mount/fuse/src/fuse-helpers.c42
-rw-r--r--xlators/mount/fuse/src/fuse-mem-types.h1
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in5
8 files changed, 88 insertions, 4 deletions
diff --git a/glusterfsd/src/glusterfsd.c b/glusterfsd/src/glusterfsd.c
index 90f12e9f77b..9e21204929f 100644
--- a/glusterfsd/src/glusterfsd.c
+++ b/glusterfsd/src/glusterfsd.c
@@ -182,6 +182,9 @@ static struct argp_option gf_options[] = {
{"attribute-timeout", ARGP_ATTRIBUTE_TIMEOUT_KEY, "SECONDS", 0,
"Set attribute timeout to SECONDS for inodes in fuse kernel module "
"[default: 1]"},
+ {"gid-timeout", ARGP_GID_TIMEOUT_KEY, "SECONDS", 0,
+ "Set auxilary group list timeout to SECONDS for fuse translator "
+ "[default: 0]"},
{"client-pid", ARGP_CLIENT_PID_KEY, "PID", OPTION_HIDDEN,
"client will authenticate itself with process id PID to server"},
{"user-map-root", ARGP_USER_MAP_ROOT_KEY, "USER", OPTION_HIDDEN,
@@ -382,6 +385,16 @@ create_fuse_mount (glusterfs_ctx_t *ctx)
}
}
+ if (cmd_args->gid_timeout) {
+ ret = dict_set_int32(master->options, "gid-timeout",
+ cmd_args->gid_timeout);
+ if (ret < 0) {
+ gf_log("glusterfsd", GF_LOG_ERROR, "failed to set dict "
+ "value for key gid-timeout");
+ goto err;
+ }
+ }
+
switch (cmd_args->fuse_direct_io_mode) {
case GF_OPTION_DISABLE: /* disable */
ret = dict_set_static_ptr (master->options, ZR_DIRECT_IO_OPT,
@@ -828,7 +841,14 @@ parse_opts (int key, char *arg, struct argp_state *state)
ctx = glusterfs_ctx_get ();
ctx->mem_accounting = 1;
break;
- }
+
+ case ARGP_GID_TIMEOUT_KEY:
+ if (!gf_string2int(arg, &cmd_args->gid_timeout))
+ break;
+
+ argp_failure(state, -1, 0, "unknown group list timeout %s", arg);
+ break;
+ }
return 0;
}
diff --git a/glusterfsd/src/glusterfsd.h b/glusterfsd/src/glusterfsd.h
index e832b87a21a..03585cf22ee 100644
--- a/glusterfsd/src/glusterfsd.h
+++ b/glusterfsd/src/glusterfsd.h
@@ -89,6 +89,7 @@ enum argp_option_keys {
ARGP_SELINUX_KEY = 158,
/* glusterfs upstream includes options 159-162, but we dont */
ARGP_INODE32_KEY = 159, /* 163 upstream */
+ ARGP_GID_TIMEOUT_KEY = 160,
};
struct _gfd_vol_top_priv_t {
diff --git a/libglusterfs/src/Makefile.am b/libglusterfs/src/Makefile.am
index dd07aaa4ea7..798b309093a 100644
--- a/libglusterfs/src/Makefile.am
+++ b/libglusterfs/src/Makefile.am
@@ -23,7 +23,8 @@ libglusterfs_la_SOURCES = dict.c xlator.c logging.c \
$(CONTRIBDIR)/uuid/uuid_time.c $(CONTRIBDIR)/uuid/compare.c \
$(CONTRIBDIR)/uuid/isnull.c $(CONTRIBDIR)/uuid/unpack.c syncop.c \
$(CONTRIBDIR)/stdlib/gf_mkostemp.c \
- graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c event-history.c
+ graph-print.c trie.c run.c options.c fd-lk.c circ-buff.c \
+ event-history.c gidcache.c
nodist_libglusterfs_la_SOURCES = y.tab.c graph.lex.c
@@ -37,7 +38,7 @@ noinst_HEADERS = common-utils.h defaults.h dict.h glusterfs.h hashfn.h \
rbthash.h iatt.h latency.h mem-types.h $(CONTRIBDIR)/uuid/uuidd.h \
$(CONTRIBDIR)/uuid/uuid.h $(CONTRIBDIR)/uuid/uuidP.h \
$(CONTRIB_BUILDDIR)/uuid/uuid_types.h syncop.h graph-utils.h trie.h run.h \
- options.h lkowner.h fd-lk.h circ-buff.h event-history.h
+ options.h lkowner.h fd-lk.h circ-buff.h event-history.h gidcache.h
EXTRA_DIST = graph.l graph.y
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 78f8c0125b0..07859c60a4a 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -4565,6 +4565,15 @@ init (xlator_t *this_xl)
GF_ASSERT (ret == 0);
}
+ GF_OPTION_INIT("gid-timeout", priv->gid_cache_timeout, int32,
+ cleanup_exit);
+
+ if (gid_cache_init(&priv->gid_cache, priv->gid_cache_timeout) < 0) {
+ gf_log("glusterfs-fuse", GF_LOG_ERROR, "Failed to initialize "
+ "group cache.");
+ goto cleanup_exit;
+ }
+
cmd_args = &this_xl->ctx->cmd_args;
fsname = cmd_args->volfile;
if (!fsname && cmd_args->volfile_server) {
@@ -4729,5 +4738,9 @@ struct volume_options options[] = {
.type = GF_OPTION_TYPE_BOOL,
.default_value = "false"
},
+ { .key = {"gid-timeout"},
+ .type = GF_OPTION_TYPE_INT,
+ .default_value = "0"
+ },
{ .key = {NULL} },
};
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index 6b0ba54819f..f9d897c3037 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -55,6 +55,7 @@
#include "list.h"
#include "dict.h"
#include "syncop.h"
+#include "gidcache.h"
#if defined(GF_LINUX_HOST_OS) || defined(__NetBSD__)
#define FUSE_OP_HIGH (FUSE_POLL + 1)
@@ -109,6 +110,8 @@ struct fuse_private {
gf_boolean_t acl;
gf_boolean_t selinux;
gf_boolean_t read_only;
+ int32_t gid_cache_timeout;
+ gid_cache_t gid_cache;
gf_boolean_t enable_ino32;
fdtable_t *fdtable;
diff --git a/xlators/mount/fuse/src/fuse-helpers.c b/xlators/mount/fuse/src/fuse-helpers.c
index 55b60de1cd8..c582291a1d8 100644
--- a/xlators/mount/fuse/src/fuse-helpers.c
+++ b/xlators/mount/fuse/src/fuse-helpers.c
@@ -248,6 +248,46 @@ out:
#endif /* GF_LINUX_HOST_OS */
}
+/*
+ * Get the groups for the PID associated with this frame. If enabled,
+ * use the gid cache to reduce group list collection.
+ */
+static void get_groups(fuse_private_t *priv, call_frame_t *frame)
+{
+ int i;
+ const gid_list_t *gl;
+ gid_list_t agl;
+
+ if (!priv->gid_cache_timeout) {
+ frame_fill_groups(frame);
+ return;
+ }
+
+ gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid);
+ if (gl) {
+ frame->root->ngrps = gl->gl_count;
+ for (i = 0; i < gl->gl_count; i++)
+ frame->root->groups[i] = gl->gl_list[i];
+ gid_cache_release(&priv->gid_cache, gl);
+ return;
+ }
+
+ frame_fill_groups (frame);
+
+ agl.gl_id = frame->root->pid;
+ agl.gl_count = frame->root->ngrps;
+ agl.gl_list = GF_CALLOC(frame->root->ngrps, sizeof(gid_t),
+ gf_fuse_mt_gids_t);
+ if (!agl.gl_list)
+ return;
+
+ for (i = 0; i < frame->root->ngrps; i++)
+ agl.gl_list[i] = frame->root->groups[i];
+
+ if (gid_cache_add(&priv->gid_cache, &agl) != 1)
+ GF_FREE(agl.gl_list);
+}
+
call_frame_t *
get_call_frame_for_req (fuse_state_t *state)
{
@@ -275,7 +315,7 @@ get_call_frame_for_req (fuse_state_t *state)
state->lk_owner);
}
- frame_fill_groups (frame);
+ get_groups(priv, frame);
if (priv && priv->client_pid_set)
frame->root->pid = priv->client_pid;
diff --git a/xlators/mount/fuse/src/fuse-mem-types.h b/xlators/mount/fuse/src/fuse-mem-types.h
index 9c6a1c67a7a..d1c5e511b0e 100644
--- a/xlators/mount/fuse/src/fuse-mem-types.h
+++ b/xlators/mount/fuse/src/fuse-mem-types.h
@@ -31,6 +31,7 @@ enum gf_fuse_mem_types_ {
gf_fuse_mt_fuse_state_t,
gf_fuse_mt_fd_ctx_t,
gf_fuse_mt_graph_switch_args_t,
+ gf_fuse_mt_gids_t,
gf_fuse_mt_end
};
#endif
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index e11d79d29b2..f3d3839e8fa 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -105,6 +105,10 @@ start_glusterfs ()
cmd_line=$(echo "$cmd_line --volume-name=$volume_name");
fi
+ if [ -n "$gid_timeout" ]; then
+ cmd_line=$(echo "$cmd_line --gid-timeout=$gid_timeout");
+ fi
+
if [ -z "$volfile_loc" ]; then
if [ -n "$server_ip" ]; then
if [ -n "$server_port" ]; then
@@ -279,6 +283,7 @@ main ()
volfile_max_fetch_attempts=$value ;;
"backupvolfile-server")
backupvolfile_server=$value ;;
+ "gid-timeout") gid_timeout=$value ;;
*) echo "unknown option $key (ignored)" ;;
esac
esac