diff options
author | Shehjar Tikoo <shehjart@zresearch.com> | 2009-04-20 12:29:21 -0700 |
---|---|---|
committer | Anand V. Avati <avati@amp.gluster.com> | 2009-04-21 12:48:09 +0530 |
commit | 86a1c646eeea353643bd6bd5eb040cf584b407c1 (patch) | |
tree | fbb545527c3114b82135d3b1b2de733c90c59c70 | |
parent | 7c7fd9039b0d0ba17190677f864c5a22d46ab4d6 (diff) |
libglusterfsclient: Add virtual mount point support
One part of the glusterfsclient library requires users
to use a handle to address a particular glusterfs context.
This can become cumbersome for applications that need to use multiple
such context. For such applications, we make it easy by letting them
define virtual mount points(VMPs), which are just paths that identify
a particular glusterfs context. This is done through a new
glusterfs_mount(..) interface.
Subsequenly, any path based operations, that pre-pend a VMP before
the files and directories inside the glusterfsd export, get internally
routed to the correct glusterfs context. This helps users do away
with the need to maintain their own path-to-glusterfs_handle_t
mapping.
The old handle-based interface still exists for whoever wishes to use
it.
Signed-off-by: Anand V. Avati <avati@amp.gluster.com>
-rwxr-xr-x | libglusterfsclient/src/libglusterfsclient-internals.h | 11 | ||||
-rwxr-xr-x | libglusterfsclient/src/libglusterfsclient.c | 163 | ||||
-rwxr-xr-x | libglusterfsclient/src/libglusterfsclient.h | 4 |
3 files changed, 178 insertions, 0 deletions
diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h index 24364b079ff..9646b0575ad 100755 --- a/libglusterfsclient/src/libglusterfsclient-internals.h +++ b/libglusterfsclient/src/libglusterfsclient-internals.h @@ -219,4 +219,15 @@ libgf_client_lookup (libglusterfs_client_ctx_t *ctx, dict_t **dict, dict_t *xattr_req); +/* We're not expecting more than 10-15 + * VMPs per process so a list is acceptable. + */ +struct vmp_entry { + struct list_head list; + char * vmp; + int vmplen; + glusterfs_handle_t handle; +}; + + #endif diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c index ef8e93057b0..4fcc9b6ce71 100755 --- a/libglusterfsclient/src/libglusterfsclient.c +++ b/libglusterfsclient/src/libglusterfsclient.c @@ -43,6 +43,7 @@ #include <sys/vfs.h> #include <utime.h> #include <sys/param.h> +#include <list.h> #define LIBGF_XL_NAME "libglusterfsclient" #define LIBGLUSTERFS_INODE_TABLE_LRU_LIMIT 1000 //14057 @@ -55,6 +56,12 @@ int32_t libgf_client_readlink (libglusterfs_client_ctx_t *ctx, loc_t *loc, static int first_init = 1; static int first_fini = 1; +/* The global list of virtual mount points. This is only the + * head of list so will be empty.*/ +struct vmp_entry vmplist; +int vmpentries = 0; + +#define libgf_vmp_virtual_path(entry, path) ((char *)(path + (entry->vmplen-1))) char * zr_build_process_uuid () @@ -839,6 +846,162 @@ glusterfs_init (glusterfs_init_params_t *init_ctx) return ctx; } +struct vmp_entry * +libgf_init_vmpentry (char *vmp, glusterfs_handle_t *vmphandle) +{ + struct vmp_entry *entry = NULL; + int vmplen = 0; + int appendslash = 0; + + entry = CALLOC (1, sizeof (struct vmp_entry)); + if (!entry) + return NULL; + + vmplen = strlen (vmp); + if (vmp[vmplen - 1] != '/') { + vmplen++; + appendslash = 1; + } + + entry->vmp = CALLOC (vmplen, sizeof (char)); + strcpy (entry->vmp, vmp); + if (appendslash) + entry->vmp[vmplen-1] = '/'; + entry->vmplen = vmplen; + entry->handle = vmphandle; + INIT_LIST_HEAD (&entry->list); + return entry; +} + +int +libgf_vmp_map_ghandle (char *vmp, glusterfs_handle_t *vmphandle) +{ + int ret = -1; + struct vmp_entry *vmpentry = NULL; + + /* FIXME: We dont check if the given vmp already exists + * in the table, but we should add this check later. + */ + vmpentry = libgf_init_vmpentry (vmp, vmphandle); + if (!vmpentry) + goto out; + + if (vmpentries == 0) + INIT_LIST_HEAD (&vmplist.list); + + list_add_tail (&vmpentry->list, &vmplist.list); + ++vmpentries; + ret = 0; +out: + + return ret; +} + +/* Returns the number of characters that match between an entry + * and the path. + */ +int +libgf_strmatchcount (char *string1, int s1len, char *string2, int s2len) +{ + int i = 0; + int tosearch = 0; + int matchcount = 0; + + s1len = strlen (string1); + s2len = strlen (string2); + + if (s1len <= s2len) + tosearch = s1len; + else + tosearch = s2len; + + for (;i < tosearch; i++) { + if (string1[i] == string2[i]) + matchcount++; + else + break; + } + + return matchcount; +} + +int +libgf_vmp_entry_match (struct vmp_entry *entry, char *path) +{ + return libgf_strmatchcount (entry->vmp, entry->vmplen, path, + strlen(path)); +} + +struct vmp_entry * +libgf_vmp_search_entry (char *path) +{ + struct vmp_entry *entry = NULL; + int matchcount = 0; + struct vmp_entry *maxentry = NULL; + int maxcount = 0; + + if (!path) + goto out; + + if (list_empty (&vmplist.list)) { + gf_log (LIBGF_XL_NAME, GF_LOG_ERROR, "Virtual Mount Point " + "list is empty."); + goto out; + } + + list_for_each_entry(entry, &vmplist.list, list) { + matchcount = libgf_vmp_entry_match (entry, path); + if ((matchcount == entry->vmplen) && (matchcount > maxcount)) { + maxcount = matchcount; + maxentry = entry; + } + } + +out: + if (maxentry) + gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Entry found: %s: %s", + path, maxentry->vmp); + else + gf_log (LIBGF_XL_NAME, GF_LOG_DEBUG, "VMP Entry not found"); + + return maxentry; +} + +/* Path must be validated already. */ +glusterfs_handle_t +libgf_vmp_get_ghandle (char * path) +{ + struct vmp_entry *entry = NULL; + + entry = libgf_vmp_search_entry (path); + + if (entry == NULL) + return NULL; + + return entry->handle; +} + +int +glusterfs_mount (char *vmp, glusterfs_init_params_t *ipars) +{ + glusterfs_handle_t vmphandle = NULL; + int ret = -1; + + GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, vmp, out); + GF_VALIDATE_OR_GOTO (LIBGF_XL_NAME, ipars, out); + + vmphandle = glusterfs_init (ipars); + if (!vmphandle) { + errno = EINVAL; + goto out; + } + + ret = libgf_vmp_map_ghandle (vmp, vmphandle); + +out: + + return ret; +} void glusterfs_reset (void) diff --git a/libglusterfsclient/src/libglusterfsclient.h b/libglusterfsclient/src/libglusterfsclient.h index 3e674924794..b37813dd6aa 100755 --- a/libglusterfsclient/src/libglusterfsclient.h +++ b/libglusterfsclient/src/libglusterfsclient.h @@ -228,6 +228,10 @@ glusterfs_mknod(glusterfs_handle_t handle, const char *pathname, mode_t mode, char * glusterfs_realpath (glusterfs_handle_t handle, const char *path, char *resolved_path); + +int +glusterfs_mount (char *vmp, glusterfs_init_params_t *ipars); + /* FIXME: review the need for these apis */ /* added for log related initialization in booster fork implementation */ void |