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@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@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@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} }, };