]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
created mount helper, can resolve mount addresses
authorYehuda Sadeh <yehuda@hq.newdream.net>
Mon, 17 Nov 2008 23:32:07 +0000 (15:32 -0800)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Mon, 17 Nov 2008 23:32:07 +0000 (15:32 -0800)
src/mount.ceph.c [new file with mode: 0644]

diff --git a/src/mount.ceph.c b/src/mount.ceph.c
new file mode 100644 (file)
index 0000000..04c60e4
--- /dev/null
@@ -0,0 +1,249 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <errno.h>
+#include <sys/mount.h>
+
+#define BUF_SIZE 128
+
+int verboseflag = 0;
+
+static int safe_cat(char **pstr, int *plen, int pos, const char *str2)
+{
+       int len2 = strlen(str2);
+
+       while (*plen < pos + len2 + 1) {
+               *plen += BUF_SIZE;
+               *pstr = realloc(*pstr, (size_t)*plen);
+
+               if (!*pstr) {
+                       printf("Out of memory\n");
+                       exit(1);
+               }
+       }
+
+       strcpy((*pstr)+pos, str2);
+
+       return pos + len2;
+}
+
+char *mount_resolve_dest(char *orig_str)
+{
+       char *new_str;
+       char *mount_path;
+       char *tok, *p, *port_str;
+       int len, pos;
+       int rc;
+
+       mount_path = strrchr(orig_str, ':');
+       if (!mount_path) {
+               printf("source mount path was not specified\n");
+               return NULL;
+       }
+       if (mount_path == orig_str) {
+               printf("server address expected\n");
+               return NULL;
+       }
+
+       *mount_path = '\0';
+       mount_path++;
+
+       if (!*mount_path) {
+               printf("incorrect source mount path\n");
+               return NULL;
+       }
+
+       len = BUF_SIZE;
+       new_str = (char *)malloc(len);
+
+       p = new_str;
+       pos = 0;
+
+       tok = strtok(orig_str, ",");
+
+       while (tok) {
+               int i;
+               struct hostent *ent;
+               char addr[16];
+
+               port_str = strchr(tok, ':');
+               *port_str = 0;
+               port_str++;
+               if (!*port_str)
+                       port_str = NULL;
+
+               ent = gethostbyname(tok);
+
+               if (!ent) {
+                       printf("server name not found: %s\n", tok);
+                       free(new_str);
+                       return 0;
+               }
+
+               snprintf(addr, sizeof(addr), "%u.%u.%u.%u", 
+                       (unsigned char)ent->h_addr[0], 
+                       (unsigned char)ent->h_addr[1], 
+                       (unsigned char)ent->h_addr[2], 
+                       (unsigned char)ent->h_addr[3]);
+
+               pos = safe_cat(&new_str, &len, pos, addr);
+
+               if (port_str) {
+                       pos = safe_cat(&new_str, &len, pos, ":");
+                       pos = safe_cat(&new_str, &len, pos, port_str);
+               }
+
+               tok = strtok(NULL, ",");
+               if (tok)
+                       pos = safe_cat(&new_str, &len, pos, ",");
+
+       }
+
+       pos = safe_cat(&new_str, &len, pos, ":");
+       pos = safe_cat(&new_str, &len, pos, mount_path);
+
+       printf("new_str = %s\n", new_str);
+
+       return new_str;
+}
+
+/*
+ * this one is partialy based on parse_options() from cifs.mount.c
+ */
+static int parse_options(char ** optionsp, int * filesys_flags)
+{
+       const char * data;
+       char * percent_char = NULL;
+       char * value = NULL;
+       char * next_keyword = NULL;
+       char * out = NULL;
+       int out_len = 0;
+       int word_len;
+       int rc = 0;
+       int skip;
+       int pos = 0;
+
+       if (!optionsp || !*optionsp)
+               return 1;
+       data = *optionsp;
+
+       if(verboseflag)
+               printf("parsing options: %s\n", data);
+
+       while(data != NULL) {
+               /*  check if ends with trailing comma */
+               if(*data == 0)
+                       break;
+
+               next_keyword = strchr(data,',');
+       
+               /* temporarily null terminate end of keyword=value pair */
+               if(next_keyword)
+                       *next_keyword++ = 0;
+
+               /* temporarily null terminate keyword to make keyword and value distinct */
+               if ((value = strchr(data, '=')) != NULL) {
+                       *value = '\0';
+                       value++;
+               }
+
+               skip = 1;
+
+               if (strncmp(data, "nosuid", 6) == 0) {
+                       *filesys_flags |= MS_NOSUID;
+               } else if (strncmp(data, "suid", 4) == 0) {
+                       *filesys_flags &= ~MS_NOSUID;
+               } else if (strncmp(data, "nodev", 5) == 0) {
+                       *filesys_flags |= MS_NODEV;
+               } else if ((strncmp(data, "nobrl", 5) == 0) || 
+                          (strncmp(data, "nolock", 6) == 0)) {
+                       *filesys_flags &= ~MS_MANDLOCK;
+               } else if (strncmp(data, "dev", 3) == 0) {
+                       *filesys_flags &= ~MS_NODEV;
+               } else if (strncmp(data, "noexec", 6) == 0) {
+                       *filesys_flags |= MS_NOEXEC;
+               } else if (strncmp(data, "exec", 4) == 0) {
+                       *filesys_flags &= ~MS_NOEXEC;
+               } else if (strncmp(data, "ro", 2) == 0) {
+                       *filesys_flags |= MS_RDONLY;
+               } else if (strncmp(data, "rw", 2) == 0) {
+                       *filesys_flags &= ~MS_RDONLY;
+                } else if (strncmp(data, "remount", 7) == 0) {
+                        *filesys_flags |= MS_REMOUNT;
+               } else {
+                       skip = 0;
+                       /* printf("ceph: Unknown mount option %s\n",data); */
+               }
+
+               /* Copy (possibly modified) option to out */
+               if (!skip) {
+                       word_len = strlen(data);
+                       if (value)
+                               word_len += 1 + strlen(value);
+
+                       if (pos)
+                               pos = safe_cat(&out, &out_len, pos, ",");
+
+                       if (value) {
+                               pos = safe_cat(&out, &out_len, pos, data);
+                               pos = safe_cat(&out, &out_len, pos, "=");
+                               pos = safe_cat(&out, &out_len, pos, value);
+                       } else {
+                               pos = safe_cat(&out, &out_len, pos, data);
+                       }
+                       
+               }
+nocopy:
+               data = next_keyword;
+       }
+
+       *optionsp = out;
+       return 0;
+}
+
+
+int main(int argc, char *argv[])
+{
+       int i;
+       char **new_argv;
+       int flags = 0;
+       int options_pos = 0;
+
+       if (argc < 5)
+               exit(1);
+
+       new_argv = (char **)malloc(sizeof(char *)*argc);
+
+       for (i=0; i<argc; i++) {
+               new_argv[i] = argv[i];
+               if (strcmp(new_argv[i], "-o") == 0) {
+                       options_pos = i+1;
+                       if (options_pos >= argc) {
+                               printf("usage error\n");
+                               exit(1);
+                       }               
+               } else if (strcmp(new_argv[i], "-v") == 0) {
+                       verboseflag = 1;
+               }
+       }
+
+       new_argv[1] = mount_resolve_dest(argv[1]);
+
+       parse_options(&new_argv[options_pos], &flags);
+
+       if (mount(new_argv[1], new_argv[2], "ceph", flags, new_argv[options_pos])) {
+               switch (errno) {
+               case ENODEV:
+                       printf("mount error: cifs filesystem not supported by the system\n");
+                       break;
+               default:
+                       printf("mount error %d = %s\n",errno,strerror(errno));
+               }
+       }
+
+out:
+       free(new_argv); 
+       exit(0);
+}
+