summaryrefslogtreecommitdiffstats
path: root/libglusterfsclient
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@zresearch.com>2009-04-20 12:29:21 -0700
committerAnand V. Avati <avati@amp.gluster.com>2009-04-21 12:48:09 +0530
commit86a1c646eeea353643bd6bd5eb040cf584b407c1 (patch)
treefbb545527c3114b82135d3b1b2de733c90c59c70 /libglusterfsclient
parent7c7fd9039b0d0ba17190677f864c5a22d46ab4d6 (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>
Diffstat (limited to 'libglusterfsclient')
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient-internals.h11
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.c163
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.h4
3 files changed, 178 insertions, 0 deletions
diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h
index 24364b079..9646b0575 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 ef8e93057..4fcc9b6ce 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 3e6749247..b37813dd6 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