patches/root_inode.patch | 110 +++++++++
xlators/cluster/cloud/src/Makefile.am | 6
xlators/cluster/cloud/src/cloud-mem-types.h | 6
xlators/cluster/cloud/src/cloud.c | 318 ++++++++++++++++++++--------
4 files changed, 346 insertions(+), 94 deletions(-)
New commits:
commit e760714b0ec60530eeba4dc0778525ec49386731
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Tue Jan 18 14:38:50 2011 -0500
Store virtualized xlator in rpc_transport_t.
diff --git a/patches/root_inode.patch b/patches/root_inode.patch
index d426828..b78ef2e 100644
--- a/patches/root_inode.patch
+++ b/patches/root_inode.patch
@@ -53,6 +53,18 @@ index e583e8c..d0fe7f3 100644
char init_succeeded;
void *private;
struct mem_acct mem_acct;
+diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
+index 9db24c0..33b38fb 100644
+--- a/rpc/rpc-lib/src/rpc-transport.h
++++ b/rpc/rpc-lib/src/rpc-transport.h
+@@ -212,6 +212,7 @@ struct rpc_transport {
+ uint64_t total_bytes_write;
+
+ struct list_head list;
++ void *xlator_data;
+ };
+
+ struct rpc_transport_ops {
diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
index 69fb5f6..5e617cf 100644
--- a/xlators/protocol/server/src/server-helpers.c
@@ -84,3 +96,15 @@ index 69fb5f6..5e617cf 100644
state->resolve.fd_no = -1;
state->resolve2.fd_no = -1;
+diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
+index 7c92441..ecb199e 100644
+--- a/xlators/protocol/server/src/server.c
++++ b/xlators/protocol/server/src/server.c
+@@ -422,6 +422,7 @@ server_rpc_notify (rpcsvc_t *rpc, void *xl, rpcsvc_event_t event,
+ conn = get_server_conn_state (this, xprt);
+ if (conn)
+ server_connection_cleanup (this, conn);
++ xprt->xlator_data = NULL;
+
+ gf_log (this->name, GF_LOG_INFO,
+ "disconnected connection from %s",
diff --git a/xlators/cluster/cloud/src/cloud.c b/xlators/cluster/cloud/src/cloud.c
index a3a9d09..e800ba1 100644
--- a/xlators/cluster/cloud/src/cloud.c
+++ b/xlators/cluster/cloud/src/cloud.c
@@ -64,25 +64,16 @@ typedef struct {
static char special_dir[] = "/_auth/";
static char user_prefix[] = "user-";
-/* TBD: use a scalable per-instance data structure */
-#define MAX_CONNS 10
-struct {
- void *xprt;
- xlator_t *subvol;
-} conn_list[MAX_CONNS];
-
xlator_t *
get_subvol (xlator_t *this, void *state, char *purpose)
{
- int i;
rpc_transport_t *xprt = ((server_state_t *)state)->xprt;
+ xlator_t *subvol = xprt->xlator_data;
- for (i = 0; i < MAX_CONNS; ++i) {
- if (conn_list[i].xprt == xprt) {
- gf_log(this->name,CLOUD_LEVEL,"forcing %s to %s",
- purpose,conn_list[i].subvol->name);
- return conn_list[i].subvol;
- }
+ if (subvol) {
+ gf_log(this->name,CLOUD_LEVEL,"forcing %s to %s",
+ purpose,subvol->name);
+ return subvol;
}
gf_log(this->name,CLOUD_LEVEL,"using default for %s",purpose);
@@ -98,20 +89,6 @@ root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
gf_log(this->name,GF_LOG_ERROR,"%s: op_ret = %d, op_errno = %d",
__func__, op_ret, op_errno);
-#if 0
- if (!op_ret) {
- xlator_t *subvol;
-
- subvol = frame->local;
- frame->local = NULL;
- gf_log(this->name,GF_LOG_ERROR," root inode for %s is %llu",
- subvol->name, stbuf->ia_ino);
- inode->ino = 1;
- inode->ia_type = stbuf->ia_type;
- subvol->itable->root = inode;
- }
-#endif
-
/* TBD: free frame/stack */
return 0;
}
@@ -119,47 +96,29 @@ root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
void
set_subvol (xlator_t *this, void *state, xlator_t *subvol)
{
- int i;
- int found = MAX_CONNS;
rpc_transport_t *xprt = ((server_state_t *)state)->xprt;
call_frame_t *frame = NULL;
- static loc_t loc = { .path = "/", .inode = NULL };
- dict_t *dict = NULL;
- static uuid_t gfid; /* TBD: might as well be global. */
-
- for (i = 0; i < MAX_CONNS; ++i) {
- if (conn_list[i].xprt == xprt) {
- found = i;
- break;
+ static loc_t loc = { .path = "/", .inode = NULL };
+ dict_t *dict = NULL;
+ static uuid_t gfid; /* TBD: might as well be global. */
+
+ gf_log(this->name,CLOUD_LEVEL,"associating %p with %s",
+ xprt, subvol->name);
+ xprt->xlator_data = subvol;
+ /* TBD: this bit should really be done from init */
+ frame = create_frame(this,this->ctx->pool);
+ if (frame) {
+ frame->local = subvol;
+ dict = dict_new();
+ if (dict) {
+ memset(gfid,0,15);
+ gfid[15] = 1;
+ dict_set_static_bin(dict,"gfid-req",gfid,16);
+ /* TBD: return value */
+ STACK_WIND(frame,root_lookup_cbk,subvol,
+ subvol->fops->lookup,&loc,dict);
+ dict_unref(dict);
}
- if ((found == MAX_CONNS) && !conn_list[i].xprt) {
- found = i;
- }
- }
-
- if (found < MAX_CONNS) {
- gf_log(this->name,CLOUD_LEVEL,"associating %p with %s",
- xprt, subvol->name);
- conn_list[found].xprt = xprt;
- conn_list[found].subvol = subvol;
- /* TBD: this bit should really be done from init */
- frame = create_frame(this,this->ctx->pool);
- if (frame) {
- frame->local = subvol;
- dict = dict_new();
- if (dict) {
- memset(gfid,0,15);
- gfid[15] = 1;
- dict_set_static_bin(dict,"gfid-req",gfid,16);
- /* TBD: return value */
- STACK_WIND(frame,root_lookup_cbk,subvol,
- subvol->fops->lookup,&loc,dict);
- dict_unref(dict);
- }
- }
- }
- else {
- gf_log(this->name,GF_LOG_ERROR,"subvol table full");
}
}
commit 9a7aaba99a14e14003c8cc6f6b913ed664fb6fa0
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Tue Jan 18 12:58:35 2011 -0500
Use per-tenant inode tables for more complete separation.
diff --git a/patches/root_inode.patch b/patches/root_inode.patch
new file mode 100644
index 0000000..d426828
--- /dev/null
+++ b/patches/root_inode.patch
@@ -0,0 +1,86 @@
+diff --git a/libglusterfs/src/defaults.c b/libglusterfs/src/defaults.c
+index 718afeb..ed07a75 100644
+--- a/libglusterfs/src/defaults.c
++++ b/libglusterfs/src/defaults.c
+@@ -1258,3 +1258,11 @@ default_mem_acct_init (xlator_t *this)
+
+ return ret;
+ }
++
++inode_table_t *
++default_get_itbl (xlator_t *this, void *state)
++{
++ (void)state;
++ return this->itable;
++}
++
+diff --git a/libglusterfs/src/defaults.h b/libglusterfs/src/defaults.h
+index 6e45160..7b37a33 100644
+--- a/libglusterfs/src/defaults.h
++++ b/libglusterfs/src/defaults.h
+@@ -676,4 +676,7 @@ default_getspec_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+
+ int32_t
+ default_mem_acct_init (xlator_t *this);
++
++inode_table_t *
++default_get_itbl (xlator_t *this, void *state);
+ #endif /* _DEFAULTS_H */
+diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
+index 37ea816..bfa356b 100644
+--- a/libglusterfs/src/xlator.c
++++ b/libglusterfs/src/xlator.c
+@@ -103,6 +103,10 @@ fill_defaults (xlator_t *xl)
+ if (!xl->mem_acct_init)
+ xl->mem_acct_init = default_mem_acct_init;
+
++ if (!xl->get_itbl) {
++ xl->get_itbl = default_get_itbl;
++ }
++
+ return;
+ }
+
+diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h
+index e583e8c..d0fe7f3 100644
+--- a/libglusterfs/src/xlator.h
++++ b/libglusterfs/src/xlator.h
+@@ -820,6 +820,7 @@ struct _xlator {
+ glusterfs_ctx_t *ctx;
+ glusterfs_graph_t *graph; /* not set for fuse */
+ inode_table_t *itable;
++ inode_table_t *(*get_itbl) (xlator_t *this, void *state);
+ char init_succeeded;
+ void *private;
+ struct mem_acct mem_acct;
+diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c
+index 69fb5f6..5e617cf 100644
+--- a/xlators/protocol/server/src/server-helpers.c
++++ b/xlators/protocol/server/src/server-helpers.c
+@@ -761,6 +761,7 @@ server_alloc_frame (rpcsvc_request_t *req)
+ call_frame_t *frame = NULL;
+ server_state_t *state = NULL;
+ server_connection_t *conn = NULL;
++ xlator_t *xl = NULL;
+
+ GF_VALIDATE_OR_GOTO("server", req, out);
+ GF_VALIDATE_OR_GOTO("server", req->trans, out);
+@@ -777,12 +778,15 @@ server_alloc_frame (rpcsvc_request_t *req)
+ state = GF_CALLOC (1, sizeof (*state), gf_server_mt_state_t);
+ GF_VALIDATE_OR_GOTO("server", state, out);
+
+- if (conn->bound_xl)
+- state->itable = conn->bound_xl->itable;
+-
+ state->xprt = rpc_transport_ref (req->trans);
+ state->conn = conn;
+
++ xl = conn->bound_xl;
++ if (xl) {
++ state->itable = xl->get_itbl(xl,state);
++ }
++ /* TBD: seems like it should be an error for xl to be NULL. */
++
+ state->resolve.fd_no = -1;
+ state->resolve2.fd_no = -1;
+
diff --git a/xlators/cluster/cloud/src/Makefile.am b/xlators/cluster/cloud/src/Makefile.am
index d2b84f8..36271f7 100644
--- a/xlators/cluster/cloud/src/Makefile.am
+++ b/xlators/cluster/cloud/src/Makefile.am
@@ -10,6 +10,10 @@ cloud_la_LIBADD = $(top_builddir)/libglusterfs/src/libglusterfs.la
noinst_HEADERS = cloud-mem-types.h
AM_CFLAGS = -fPIC -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Wall -D$(GF_HOST_OS)\
- -I$(top_srcdir)/libglusterfs/src -shared -nostartfiles $(GF_CFLAGS)
+ -I$(top_srcdir)/libglusterfs/src \
+ -I$(top_srcdir)/rpc/rpc-lib/src \
+ -I$(top_srcdir)/rpc/xdr/src \
+ -I$(top_srcdir)/xlators/protocol/server/src \
+ -shared -nostartfiles $(GF_CFLAGS)
CLEANFILES =
diff --git a/xlators/cluster/cloud/src/cloud.c b/xlators/cluster/cloud/src/cloud.c
index bbfe32b..a3a9d09 100644
--- a/xlators/cluster/cloud/src/cloud.c
+++ b/xlators/cluster/cloud/src/cloud.c
@@ -24,6 +24,9 @@
#include <fnmatch.h>
#include <pthread.h>
#include "xlator.h"
+#include "rpc-transport.h"
+#include "glusterfs3-xdr.h"
+#include "server.h"
#include "glusterfs.h"
#include "byte-order.h"
#include "xlator.h"
@@ -64,17 +67,18 @@ static char user_prefix[] = "user-";
/* TBD: use a scalable per-instance data structure */
#define MAX_CONNS 10
struct {
- void *conn;
- xlator_t *subvol;
+ void *xprt;
+ xlator_t *subvol;
} conn_list[MAX_CONNS];
xlator_t *
-get_subvol (xlator_t *this, void *conn, char *purpose)
+get_subvol (xlator_t *this, void *state, char *purpose)
{
int i;
+ rpc_transport_t *xprt = ((server_state_t *)state)->xprt;
for (i = 0; i < MAX_CONNS; ++i) {
- if (conn_list[i].conn == conn) {
+ if (conn_list[i].xprt == xprt) {
gf_log(this->name,CLOUD_LEVEL,"forcing %s to %s",
purpose,conn_list[i].subvol->name);
return conn_list[i].subvol;
@@ -85,29 +89,99 @@ get_subvol (xlator_t *this, void *conn, char *purpose)
return FIRST_CHILD(this);
}
+int
+root_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int op_ret, int op_errno,
+ inode_t *inode, struct iatt *stbuf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ gf_log(this->name,GF_LOG_ERROR,"%s: op_ret = %d, op_errno = %d",
+ __func__, op_ret, op_errno);
+
+#if 0
+ if (!op_ret) {
+ xlator_t *subvol;
+
+ subvol = frame->local;
+ frame->local = NULL;
+ gf_log(this->name,GF_LOG_ERROR," root inode for %s is %llu",
+ subvol->name, stbuf->ia_ino);
+ inode->ino = 1;
+ inode->ia_type = stbuf->ia_type;
+ subvol->itable->root = inode;
+ }
+#endif
+
+ /* TBD: free frame/stack */
+ return 0;
+}
+
void
-set_subvol (xlator_t *this, void *conn, xlator_t *subvol)
+set_subvol (xlator_t *this, void *state, xlator_t *subvol)
{
- int i;
+ int i;
+ int found = MAX_CONNS;
+ rpc_transport_t *xprt = ((server_state_t *)state)->xprt;
+ call_frame_t *frame = NULL;
+ static loc_t loc = { .path = "/", .inode = NULL };
+ dict_t *dict = NULL;
+ static uuid_t gfid; /* TBD: might as well be global. */
for (i = 0; i < MAX_CONNS; ++i) {
- if (!conn_list[i].conn) {
- gf_log(this->name,CLOUD_LEVEL,"associating %p with %s",
- conn, subvol->name);
- conn_list[i].conn = conn;
- conn_list[i].subvol = subvol;
- return;
+ if (conn_list[i].xprt == xprt) {
+ found = i;
+ break;
}
+ if ((found == MAX_CONNS) && !conn_list[i].xprt) {
+ found = i;
+ }
+ }
+
+ if (found < MAX_CONNS) {
+ gf_log(this->name,CLOUD_LEVEL,"associating %p with %s",
+ xprt, subvol->name);
+ conn_list[found].xprt = xprt;
+ conn_list[found].subvol = subvol;
+ /* TBD: this bit should really be done from init */
+ frame = create_frame(this,this->ctx->pool);
+ if (frame) {
+ frame->local = subvol;
+ dict = dict_new();
+ if (dict) {
+ memset(gfid,0,15);
+ gfid[15] = 1;
+ dict_set_static_bin(dict,"gfid-req",gfid,16);
+ /* TBD: return value */
+ STACK_WIND(frame,root_lookup_cbk,subvol,
+ subvol->fops->lookup,&loc,dict);
+ dict_unref(dict);
+ }
+ }
+ }
+ else {
+ gf_log(this->name,GF_LOG_ERROR,"subvol table full");
+ }
+}
+
+inode_table_t *
+cloud_get_itbl (xlator_t *this, void *state)
+{
+ xlator_t *subvol = get_subvol(this,state,(char *)__func__);
+
+ if (subvol && subvol->itable && (subvol != FIRST_CHILD(this))) {
+ return subvol->itable;
}
+
+ return this->itable;
}
void
cloud_check_auth (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- char *subdir = (char *)(loc->path) + sizeof(special_dir) - 1;
- char *password = NULL;
- cloud_priv *priv = (cloud_priv *)(this->private);
- cloud_subvol *sv = NULL;
+ char *subdir = (char *)(loc->path)+sizeof(special_dir)-1;
+ char *password = NULL;
+ cloud_priv *priv = (cloud_priv *)(this->private);
+ cloud_subvol *sv = NULL;
gf_log(this->name,CLOUD_LEVEL,"got special mkdir(%s)",subdir);
@@ -134,7 +208,10 @@ cloud_check_auth (call_frame_t *frame, xlator_t *this, loc_t *loc)
gf_log(this->name,GF_LOG_WARNING,
"forcing this connection to subvol %s",subdir);
*(--password) = '=';
- set_subvol(this,frame->root->trans,sv->xlator);
+ if (!sv->xlator->itable) {
+ sv->xlator->itable = inode_table_new(0,sv->xlator);
+ }
+ set_subvol(this,frame->root->state,sv->xlator);
STACK_UNWIND_STRICT(mkdir,frame,0,0,NULL,NULL,NULL,NULL);
}
@@ -159,7 +236,7 @@ cloud_mkdir (call_frame_t *frame, xlator_t *this,
return 0;
}
- next = get_subvol(this,frame->root->trans,"mkdir");
+ next = get_subvol(this,frame->root->state,"mkdir");
STACK_WIND(frame,cloud_mkdir_cbk,next,next->fops->mkdir,
loc,mode,params);
return 0;
@@ -171,6 +248,20 @@ cloud_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_t *inode, struct iatt *stbuf, dict_t *xattr,
struct iatt *postparent)
{
+ inode_table_t *table = NULL;
+
+ /*
+ * Copied from server_lookup_cbk because they use BOUND_XL and
+ * thus don't properly evaluate whether it's necessary.
+ */
+ if (inode && inode->table && stbuf) {
+ gf_log(this->name,GF_LOG_ERROR,"patching up root inode");
+ if (inode == inode->table->root) {
+ stbuf->ia_ino = 1;
+ uuid_copy (stbuf->ia_gfid, inode->table->root->gfid);
+ }
+ }
+
STACK_UNWIND_STRICT(lookup,frame,op_ret,op_errno,
inode, stbuf, xattr, postparent);
return 0;
@@ -180,7 +271,17 @@ int
cloud_lookup (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr_req)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"lookup");
+ xlator_t *next = NULL;
+
+ gf_log(this->name,GF_LOG_ERROR,"lookup path is %s",loc->path);
+
+ if (strcmp(loc->path,"/")) {
+ next = get_subvol(this,frame->root->state,"lookup");
+ }
+ else {
+ gf_log(this->name,GF_LOG_ERROR,"NOT virtualizing lookup");
+ next = FIRST_CHILD(this);
+ }
STACK_WIND(frame,cloud_lookup_cbk,next,next->fops->lookup,
loc, xattr_req);
@@ -203,13 +304,24 @@ cloud_create (call_frame_t *frame, xlator_t *this,
loc_t *loc, int32_t flags, mode_t mode,
fd_t *fd, dict_t *params)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"create");
+ xlator_t *next = get_subvol(this,frame->root->state,"create");
STACK_WIND(frame,cloud_create_cbk,next,next->fops->create,
loc, flags, mode, fd, params);
return 0;
}
+/*
+ * For now, getxattr/setxattr on the root are not virtualized because some
+ * internal xattrs (e.g. those used by DHT/AFR) are initialized before we
+ * virtualize but needed after. The result if we did things normally would
+ * be that the post-virtualization calls would fail, leaving the translators
+ * that need them very confused.
+ *
+ * TBD: look for pre-virtualization calls to "special" xattrs and fan them out
+ * to the other subvolumes.
+ */
+
int
cloud_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno, dict_t *xattr)
@@ -222,7 +334,15 @@ int
cloud_getxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, const char *key)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"getxattr");
+ xlator_t *next = NULL;
+
+ if (strcmp(loc->path,"/")) {
+ next = get_subvol(this,frame->root->state,"getxattr");
+ }
+ else {
+ gf_log(this->name,GF_LOG_ERROR,"NOT virtualizing getxattr");
+ next = FIRST_CHILD(this);
+ }
STACK_WIND(frame,cloud_getxattr_cbk,next,next->fops->getxattr,loc,key);
return 0;
@@ -240,7 +360,7 @@ int
cloud_open (call_frame_t *frame, xlator_t *this,
loc_t *loc, int flags, fd_t *fd, int wbflags)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"open");
+ xlator_t *next = get_subvol(this,frame->root->state,"open");
STACK_WIND(frame,cloud_open_cbk,next,next->fops->open,
loc,flags,fd,wbflags);
@@ -258,7 +378,7 @@ cloud_stat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_stat (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"stat");
+ xlator_t *next = get_subvol(this,frame->root->state,"stat");
STACK_WIND(frame,cloud_stat_cbk,next,next->fops->stat,loc);
return 0;
@@ -275,7 +395,7 @@ cloud_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_fstat (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"fstat");
+ xlator_t *next = get_subvol(this,frame->root->state,"fstat");
STACK_WIND(frame,cloud_fstat_cbk,next,next->fops->fstat,fd);
return 0;
@@ -293,7 +413,7 @@ cloud_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"truncate");
+ xlator_t *next = get_subvol(this,frame->root->state,"truncate");
STACK_WIND(frame,cloud_truncate_cbk,next,next->fops->truncate,
loc,offset);
@@ -303,13 +423,15 @@ cloud_truncate (call_frame_t *frame, xlator_t *this, loc_t *loc, off_t offset)
int
cloud_ftruncate (call_frame_t *frame, xlator_t *this, fd_t *fd, off_t offset)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"ftruncate");
+ xlator_t *next = get_subvol(this,frame->root->state,"ftruncate");
STACK_WIND(frame,cloud_truncate_cbk,next,next->fops->ftruncate,
fd,offset);
return 0;
}
+/* See comment near cloud_getxattr about why we don't always virtualize. */
+
int
cloud_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int op_ret, int op_errno)
@@ -322,7 +444,15 @@ int
cloud_setxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *xattr, int flags)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"setxattr");
+ xlator_t *next = NULL;
+
+ if (strcmp(loc->path,"/")) {
+ next = get_subvol(this,frame->root->state,"setxattr");
+ }
+ else {
+ gf_log(this->name,GF_LOG_ERROR,"NOT virtualizing setxattr");
+ next = FIRST_CHILD(this);
+ }
STACK_WIND(frame,cloud_setxattr_cbk,next,next->fops->setxattr,
loc, xattr, flags);
@@ -344,7 +474,7 @@ int
cloud_readv (call_frame_t *frame, xlator_t *this,
fd_t *fd, size_t size, off_t off)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"readv");
+ xlator_t *next = get_subvol(this,frame->root->state,"readv");
STACK_WIND(frame,cloud_readv_cbk,next,next->fops->readv,fd,size,off);
return 0;
@@ -364,7 +494,7 @@ cloud_writev (call_frame_t *frame, xlator_t *this,
fd_t *fd, struct iovec *vector, int count, off_t off,
struct iobref *iobref)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"writev");
+ xlator_t *next = get_subvol(this,frame->root->state,"writev");
STACK_WIND(frame,cloud_writev_cbk,next,next->fops->writev,
fd, vector, count, off, iobref);
@@ -382,7 +512,7 @@ cloud_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_flush (call_frame_t *frame, xlator_t *this, fd_t *fd)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"flush");
+ xlator_t *next = get_subvol(this,frame->root->state,"flush");
STACK_WIND(frame,cloud_flush_cbk,next,next->fops->flush,fd);
return 0;
@@ -399,7 +529,7 @@ cloud_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc, fd_t *fd)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"opendir");
+ xlator_t *next = get_subvol(this,frame->root->state,"opendir");
STACK_WIND(frame,cloud_opendir_cbk,next,next->fops->opendir,loc,fd);
return 0;
@@ -417,7 +547,7 @@ int
cloud_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t yoff)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"readdir");
+ xlator_t *next = get_subvol(this,frame->root->state,"readdir");
STACK_WIND(frame,cloud_readdir_cbk,next,next->fops->readdir,
fd,size,yoff);
@@ -436,7 +566,7 @@ int
cloud_readdirp (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
off_t yoff)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"readdirp");
+ xlator_t *next = get_subvol(this,frame->root->state,"readdirp");
STACK_WIND(frame,cloud_readdirp_cbk,next,next->fops->readdirp,
fd,size,yoff);
@@ -455,7 +585,7 @@ cloud_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"unlink");
+ xlator_t *next = get_subvol(this,frame->root->state,"unlink");
STACK_WIND(frame,cloud_unlink_cbk,next,next->fops->unlink,loc);
return 0;
@@ -473,7 +603,7 @@ cloud_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
int
cloud_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"rmdir");
+ xlator_t *next = get_subvol(this,frame->root->state,"rmdir");
STACK_WIND(frame,cloud_rmdir_cbk,next,next->fops->rmdir,loc,flags);
return 0;
@@ -492,7 +622,7 @@ int
cloud_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
struct iatt *stbuf, int32_t valid)
{
- xlator_t *next = get_subvol(this,frame->root->trans,"setattr");
+ xlator_t *next = get_subvol(this,frame->root->state,"setattr");
STACK_WIND(frame,cloud_setattr_cbk,next,next->fops->setattr,
loc,stbuf,valid);
@@ -596,8 +726,6 @@ init (xlator_t *this)
dict_t *options = NULL;
int ret = 0;
char *log_str = NULL;
- xlator_list_t *trav = NULL;
- int i = 0;
cloud_priv *priv = NULL;
if (!this)
@@ -642,6 +770,7 @@ init (xlator_t *this)
}
dict_foreach(options,collect_users,this);
+ this->get_itbl = cloud_get_itbl;
return 0;
}
commit 4144fd4dba0b1651eaa532b8c53dec87bb0ad3e3
Author: Jeff Darcy <jdarcy(a)redhat.com>
Date: Mon Jan 3 17:09:20 2011 -0500
Use options for specifying users (tenants).
diff --git a/xlators/cluster/cloud/src/cloud-mem-types.h b/xlators/cluster/cloud/src/cloud-mem-types.h
index 49f3f63..5727cb8 100644
--- a/xlators/cluster/cloud/src/cloud-mem-types.h
+++ b/xlators/cluster/cloud/src/cloud-mem-types.h
@@ -23,10 +23,8 @@
#include "mem-types.h"
enum gf_cloud_mem_types_ {
- gf_cloud_mt_cloud_conf = gf_common_mt_end + 1,
- gf_cloud_mt_cloud_fd,
- gf_cloud_mt_rename,
- gf_cloud_mt_rename_gen,
+ gf_cloud_mt_cloud_priv = gf_common_mt_end + 1,
+ gf_cloud_mt_cloud_subvol,
gf_cloud_mt_end
};
#endif
diff --git a/xlators/cluster/cloud/src/cloud.c b/xlators/cluster/cloud/src/cloud.c
index ebfc68d..bbfe32b 100644
--- a/xlators/cluster/cloud/src/cloud.c
+++ b/xlators/cluster/cloud/src/cloud.c
@@ -49,19 +49,17 @@
#define CLOUD_LEVEL GF_LOG_DEBUG
-static char special_dir[] = "/_auth/";
+typedef struct {
+ dict_t *users;
+} cloud_priv;
-/* TBD: initialize subdir list from option */
-struct {
- char *name;
- char *password;
+typedef struct {
xlator_t *xlator;
-} subvol_list[] = {
- { "foo", "passw0rd" },
- { "bar", "passw1rd" },
- { "ugh", "not_there" },
- { NULL }
-};
+ char password[1];
+} cloud_subvol;
+
+static char special_dir[] = "/_auth/";
+static char user_prefix[] = "user-";
/* TBD: use a scalable per-instance data structure */
#define MAX_CONNS 10
@@ -106,9 +104,10 @@ set_subvol (xlator_t *this, void *conn, xlator_t *subvol)
void
cloud_check_auth (call_frame_t *frame, xlator_t *this, loc_t *loc)
{
- char *subdir = (char *)(loc->path) + sizeof(special_dir) - 1;
- char *password = NULL;
- int i = 0;
+ char *subdir = (char *)(loc->path) + sizeof(special_dir) - 1;
+ char *password = NULL;
+ cloud_priv *priv = (cloud_priv *)(this->private);
+ cloud_subvol *sv = NULL;
gf_log(this->name,CLOUD_LEVEL,"got special mkdir(%s)",subdir);
@@ -119,30 +118,24 @@ cloud_check_auth (call_frame_t *frame, xlator_t *this, loc_t *loc)
}
*(password++) = '\0';
- for (i = 0; subvol_list[i].name; ++i) {
- if (strcmp(subdir,subvol_list[i].name)) {
- continue;
- }
- if (strcmp(password,subvol_list[i].password)) {
- gf_log(this->name,CLOUD_LEVEL,"bad password for %s",
- subdir);
- continue;
- }
- if (!subvol_list[i].xlator) {
- gf_log(this->name,CLOUD_LEVEL,"no translator for %s",
- subdir);
- continue;
- }
- gf_log(this->name,GF_LOG_WARNING,
- "forcing this connection to subvol %s",subdir);
+ if (dict_get_ptr(priv->users,subdir,(void **)&sv) != 0) {
+ *(--password) = '=';
+ STACK_UNWIND_STRICT(mkdir,frame,-1,ENOENT,NULL,NULL,NULL,NULL);
+ return;
+ }
+
+ if (strcmp(password,sv->password)) {
+ gf_log(this->name,CLOUD_LEVEL,"bad password for %s", subdir);
*(--password) = '=';
- set_subvol(this,frame->root->trans,subvol_list[i].xlator);
- STACK_UNWIND_STRICT(mkdir,frame,0,0,NULL,NULL,NULL,NULL);
+ STACK_UNWIND_STRICT(mkdir,frame,-1,EPERM,NULL,NULL,NULL,NULL);
return;
}
+ gf_log(this->name,GF_LOG_WARNING,
+ "forcing this connection to subvol %s",subdir);
*(--password) = '=';
- STACK_UNWIND_STRICT(mkdir,frame,-1,EPERM,NULL,NULL,NULL,NULL);
+ set_subvol(this,frame->root->trans,sv->xlator);
+ STACK_UNWIND_STRICT(mkdir,frame,0,0,NULL,NULL,NULL,NULL);
}
int
@@ -166,7 +159,7 @@ cloud_mkdir (call_frame_t *frame, xlator_t *this,
return 0;
}
- next = get_subvol(this,frame->root->trans,"lookup");
+ next = get_subvol(this,frame->root->trans,"mkdir");
STACK_WIND(frame,cloud_mkdir_cbk,next,next->fops->mkdir,
loc,mode,params);
return 0;
@@ -551,6 +544,52 @@ mem_acct_init (xlator_t *this)
return ret;
}
+void
+collect_users (dict_t *this, char *key, data_t *value, void *ctx)
+{
+ char *user = NULL;
+ char *pass = NULL;
+ xlator_t *xlator = (xlator_t *)ctx;
+ cloud_priv *priv = (cloud_priv *)(xlator->private);
+ cloud_subvol *sv = NULL;
+ xlator_list_t *trav = NULL;
+
+ if (strncmp(key,user_prefix,sizeof(user_prefix)-1)) {
+ return;
+ }
+
+ user = key + sizeof(user_prefix) - 1;
+ for (trav = xlator->children; trav; trav = trav->next) {
+ if (!strcmp(trav->xlator->name,user)) {
+ break;
+ }
+ }
+ if (!trav) {
+ gf_log(xlator->name,GF_LOG_ERROR,"no such subvol %s",user);
+ return;
+ }
+
+ pass = data_to_str(value);
+ sv = GF_CALLOC(sizeof(*sv)+strlen(pass),1,gf_cloud_mt_cloud_subvol);
+ if (!sv) {
+ gf_log(xlator->name,GF_LOG_ERROR,
+ "could not allocate subvol structure for %s", user);
+ return;
+ }
+
+ sv->xlator = trav->xlator;
+ strcpy(sv->password,pass);
+
+ if (dict_set_ptr(priv->users,user,sv) != 0) {
+ gf_log(xlator->name,GF_LOG_ERROR,
+ "could not set data for user %s", user);
+ GF_FREE(sv);
+ return;
+ }
+
+ gf_log(xlator->name,CLOUD_LEVEL, "added user %s", user);
+}
+
int
init (xlator_t *this)
{
@@ -559,6 +598,7 @@ init (xlator_t *this)
char *log_str = NULL;
xlator_list_t *trav = NULL;
int i = 0;
+ cloud_priv *priv = NULL;
if (!this)
return -1;
@@ -574,6 +614,22 @@ init (xlator_t *this)
"dangling volume. check volfile ");
}
+ priv = GF_CALLOC(1,sizeof(cloud_priv),gf_cloud_mt_cloud_priv);
+ if (!priv) {
+ gf_log(this->name,GF_LOG_ERROR,
+ "could not allocate private structure");
+ return -1;
+ }
+
+ priv->users = dict_new();
+ if (!priv->users) {
+ gf_log(this->name,GF_LOG_ERROR,
+ "could not allocate user dict");
+ GF_FREE(priv);
+ return -1;
+ }
+
+ this->private = priv;
options = this->options;
ret = dict_get_str (options, "log-level", &log_str);
@@ -585,17 +641,7 @@ init (xlator_t *this)
}
}
- for (i = 0; subvol_list[i].name; ++i) {
- for (trav = this->children; trav; trav = trav->next) {
- if (!strcmp(subvol_list[i].name,trav->xlator->name)) {
- gf_log(this->name,CLOUD_LEVEL,
- "mapping %s -> %p",
- subvol_list[i].name, trav->xlator->name);
- subvol_list[i].xlator = trav->xlator;
- break;
- }
- }
- }
+ dict_foreach(options,collect_users,this);
return 0;
}
@@ -607,6 +653,9 @@ fini (xlator_t *this)
if (!this)
return;
+ dict_unref(((cloud_priv *)(this->private))->users);
+ GF_FREE(this->private);
+
gf_log (this->name, GF_LOG_NORMAL,
"cloud translator unloaded");
return;
@@ -659,5 +708,8 @@ struct volume_options options[] = {
{ .key = {"log-level"},
.type = GF_OPTION_TYPE_STR,
},
+ { .key = {"user-*"},
+ .type = GF_OPTION_TYPE_STR,
+ },
{ .key = {NULL} },
};