Patchwork [BUG:2456] Glusterd: IPV6 support for glusterfs.

login
register
Submitter Gaurav
Date 2011-06-20 13:29:27
Message ID <1308576567-10445-1-git-send-email-gaurav@gluster.com>
Download mbox | patch
Permalink /patch/7564/
State Accepted
Delegated to: Vijay Bellur
Headers show

Comments

Gaurav - 2011-06-20 13:29:27
From: Gaurav <gaurav@gluster.com>


Signed-off-by: Gaurav <gaurav@gluster.com>
---
 cli/src/cli-cmd-parser.c                    |   38 +++---
 cli/src/cli.c                               |    2 +-
 libglusterfs/src/common-utils.c             |   39 ++++++
 libglusterfs/src/common-utils.h             |    3 +
 rpc/rpc-lib/src/rpc-transport.c             |    2 +-
 xlators/mgmt/glusterd/src/glusterd-utils.c  |  175 +++++++++++++--------------
 xlators/mount/fuse/utils/mount.glusterfs.in |    2 +-
 xlators/mount/fuse/utils/mount_glusterfs.in |    2 +-
 8 files changed, 152 insertions(+), 111 deletions(-)

Patch

diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index 3e33184..046c38e 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -49,7 +49,6 @@  str_getunamb (const char *tok, char **opwords)
         return (char *)cli_getunamb (tok, (void **)opwords, id_sel);
 }
 
-
 int32_t
 cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
                       char **bricks, int *brick_count)
@@ -60,11 +59,11 @@  cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
         char                *space = " ";
         char            *delimiter = NULL;
         char            *host_name = NULL;
-        char                  *tmp = NULL;
         char        *free_list_ptr = NULL;
         char               *tmpptr = NULL;
         int                      j = 0;
         int         brick_list_len = 0;
+        char             *tmp_host = NULL;
 
         GF_ASSERT (words);
         GF_ASSERT (wordcount);
@@ -75,14 +74,13 @@  cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
         strncpy (brick_list, space, strlen (space));
         brick_list_len++;
         while (brick_index < wordcount) {
-                delimiter = strchr (words[brick_index], ':');
-                if (!delimiter || delimiter == words[brick_index]
-                    || *(delimiter+1) != '/') {
+                if (validate_brick_name ((char *)words[brick_index])) {
                         cli_out ("wrong brick type: %s, use <HOSTNAME>:"
                                  "<export-dir-abs-path>", words[brick_index]);
                         ret = -1;
                         goto out;
                 } else {
+                        delimiter = strrchr (words[brick_index], ':');
                         cli_path_strip_trailing_slashes (delimiter + 1);
                 }
 
@@ -94,7 +92,13 @@  cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
                         goto out;
                 }
 
-                host_name = gf_strdup (words[brick_index]);
+                tmp_host = gf_strdup ((char *)words[brick_index]);
+                if (!tmp_host) {
+                        gf_log ("cli", GF_LOG_ERROR, "Out of memory");
+                        ret = -1;
+                        goto out;
+                }
+                get_host_name (tmp_host, &host_name);
                 if (!host_name) {
                         ret = -1;
                         gf_log("cli",GF_LOG_ERROR, "Unable to allocate "
@@ -102,20 +106,19 @@  cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,
                         goto out;
                 }
 
-                strtok_r (host_name, ":", &tmp);
                 if (!(strcmp (host_name, "localhost") &&
                       strcmp (host_name, "127.0.0.1"))) {
                         cli_out ("Please provide a valid hostname/ip other "
                                  "than localhost or 127.0.0.1");
                         ret = -1;
-                        GF_FREE (host_name);
+                        GF_FREE (tmp_host);
                         goto out;
                 }
-                if (!valid_host_name(host_name, strlen(host_name))) {
+                if (!valid_internet_address (host_name)) {
                         cli_out ("internet address '%s' does not comform to "
 			         "standards", host_name);
                 }
-                GF_FREE (host_name);
+                GF_FREE (tmp_host);
                 tmp_list = gf_strdup (brick_list + 1);
                 if (free_list_ptr) {
                         GF_FREE (free_list_ptr);
@@ -764,14 +767,13 @@  cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,
         }
 
         while (brick_index < wordcount) {
-                delimiter = strchr(words[brick_index], ':');
-                if (!delimiter || delimiter == words[brick_index]
-                    || *(delimiter+1) != '/') {
+                if (validate_brick_name ((char *)words[brick_index])) {
                         cli_out ("wrong brick type: %s, use <HOSTNAME>:"
                                  "<export-dir-abs-path>", words[brick_index]);
                         ret = -1;
                         goto out;
                 } else {
+                        delimiter = strrchr(words[brick_index], ':');
                         cli_path_strip_trailing_slashes (delimiter + 1);
                 }
 
@@ -858,14 +860,13 @@  cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
                 goto out;
         }
 
-        delimiter = strchr ((char *)words[3], ':');
-        if (!delimiter || delimiter == words[3]
-            || *(delimiter+1) != '/') {
+        if (validate_brick_name ((char *)words[3])) {
                 cli_out ("wrong brick type: %s, use "
                         "<HOSTNAME>:<export-dir-abs-path>", words[3]);
                 ret = -1;
                 goto out;
         } else {
+                delimiter = strrchr ((char *)words[3], ':');
                 cli_path_strip_trailing_slashes (delimiter + 1);
         }
         ret = dict_set_str (dict, "src-brick", (char *)words[3]);
@@ -878,14 +879,13 @@  cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,
                 goto out;
         }
 
-        delimiter = strchr ((char *)words[4], ':');
-        if (!delimiter || delimiter == words[4]
-            || *(delimiter+1) != '/') {
+        if (validate_brick_name ((char *)words[4])) {
                 cli_out ("wrong brick type: %s, use "
                         "<HOSTNAME>:<export-dir-abs-path>", words[4]);
                 ret = -1;
                 goto out;
         } else {
+                delimiter = strrchr ((char *)words[4], ':');
                 cli_path_strip_trailing_slashes (delimiter + 1);
         }
 
diff --git a/cli/src/cli.c b/cli/src/cli.c
index 491c11b..1946ed2 100644
--- a/cli/src/cli.c
+++ b/cli/src/cli.c
@@ -517,7 +517,7 @@  cli_rpc_init (struct cli_state *state)
         if (ret)
                 goto out;
 
-        ret = dict_set_str (options, "transport.address-family", "inet");
+        ret = dict_set_str (options, "transport.address-family", "inet/inet6");
         if (ret)
                 goto out;
 
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 96beee1..82c74f8 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1785,3 +1785,42 @@  out:
         return flag;
 }
 
+int
+validate_brick_name (char *brick)
+{
+        char *delimiter = NULL;
+        int  ret = 0;
+        delimiter = strrchr (brick, ':');
+        if (!delimiter || delimiter == brick
+            || *(delimiter+1) != '/') {
+                ret = -1;
+        }
+        return ret;
+}
+
+char *
+get_host_name (char *word, char **host)
+{
+        char *delimiter = NULL;
+        delimiter = strrchr (word, ':');
+        if (delimiter)
+                *delimiter = '\0';
+        else
+                return NULL;
+        *host = word;
+        return *host;
+}
+
+
+char *
+get_path_name (char *word, char **path)
+{
+        char *delimiter = NULL;
+        delimiter = strchr (word, '/');
+        if (!delimiter)
+                return NULL;
+        *path = delimiter;
+        return *path;
+}
+
+
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index e42945b..9afa280 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -369,4 +369,7 @@  void gf_array_insertionsort (void *a, int l, int r, size_t elem_size,
 int gf_is_str_int (const char *value);
 
 char *gf_uint64_2human_readable (uint64_t);
+int validate_brick_name (char *brick);
+char *get_host_name (char *word, char **host);
+char *get_path_name (char *word, char **path);
 #endif /* _COMMON_UTILS_H */
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index 89daa5a..e26e1d9 100644
--- a/rpc/rpc-lib/src/rpc-transport.c
+++ b/rpc/rpc-lib/src/rpc-transport.c
@@ -1004,7 +1004,7 @@  rpc_transport_inet_options_build (dict_t **options, const char *hostname, int po
                         port);
                 goto out;
         }
-        ret = dict_set_str (dict, "transport.address-family", "inet");
+        ret = dict_set_str (dict, "transport.address-family", "inet/inet6");
         if (ret) {
                 gf_log (THIS->name, GF_LOG_WARNING,
                         "failed to set addr-family with inet");
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 8c04231..1b9d191 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -128,6 +128,40 @@  glusterd_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
         return is_local;
 }
 
+char *
+get_ip_from_addrinfo (struct addrinfo *addr, char **ip)
+{
+        char buf[64];
+        void *in_addr = NULL;
+        struct sockaddr_in *s4 = NULL;
+        struct sockaddr_in6 *s6 = NULL;
+
+        switch (addr->ai_family)
+        {
+                case AF_INET:
+                        s4 = (struct sockaddr_in *)addr->ai_addr;
+                        in_addr = &s4->sin_addr;
+                        break;
+
+                case AF_INET6:
+                        s6 = (struct sockaddr_in6 *)addr->ai_addr;
+                        in_addr = &s6->sin6_addr;
+                        break;
+
+                default:
+                        gf_log ("glusterd", GF_LOG_ERROR, "Invalid family");
+                        return NULL;
+        }
+
+        if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) {
+                gf_log ("glusterd", GF_LOG_ERROR, "String conversion failed");
+                return NULL;
+        }
+
+        *ip = strdup (buf);
+        return *ip;
+}
+
 int32_t
 glusterd_is_local_addr (char *hostname)
 {
@@ -135,13 +169,8 @@  glusterd_is_local_addr (char *hostname)
         struct          addrinfo *result = NULL;
         struct          addrinfo *res = NULL;
         int32_t         found = 0;
-        struct          ifconf buf = {0,};
         int             sd = -1;
-        struct ifreq    *ifr = NULL;
-        struct ifreq    *ifr_end = NULL;
-        int32_t         size = 0;
-        char            buff[1024] = {0,};
-        gf_boolean_t    need_free = _gf_false;
+        char            *ip = NULL;
 
         ret = getaddrinfo (hostname, NULL, NULL, &result);
 
@@ -157,58 +186,26 @@  glusterd_is_local_addr (char *hostname)
                         goto out;
         }
 
-
-        sd = socket (AF_INET, SOCK_DGRAM, 0);
-        if (sd == -1)
-                goto out;
-
-        buf.ifc_len = sizeof (buff);
-        buf.ifc_buf = buff;
-        size = buf.ifc_len;
-
-        ret = ioctl (sd, SIOCGIFCONF, &buf);
-        if (ret) {
-                goto out;
-        }
-
-        while (size <= buf.ifc_len) {
-                size += sizeof (struct ifreq);
-                buf.ifc_len = size;
-                if (need_free)
-                        GF_FREE (buf.ifc_req);
-                buf.ifc_req = GF_CALLOC (1, size, gf_gld_mt_ifreq);
-                need_free = 1;
-                ret = ioctl (sd, SIOCGIFCONF, &buf);
-                if (ret) {
-                        goto out;
-                }
-        }
-
-        ifr_end = (struct ifreq *)&buf.ifc_buf[buf.ifc_len];
-
         for (res = result; res != NULL; res = res->ai_next) {
-                ifr = buf.ifc_req;
-                while (ifr < ifr_end) {
-                        if ((ifr->ifr_addr.sa_family == res->ai_addr->sa_family)
-                            && (memcmp (&ifr->ifr_addr, res->ai_addr,
-                                        res->ai_addrlen) == 0)) {
-                                found = 1;
-                                goto out;
-                        }
-                        ifr++;
+                gf_log ("glusterd", GF_LOG_DEBUG, "%s ", get_ip_from_addrinfo (res, &ip));
+                sd = socket (res->ai_family, SOCK_DGRAM, 0);
+                if (sd == -1)
+                        goto out;
+                /*If bind succeeds then its a local address*/
+                ret = bind (sd, res->ai_addr, res->ai_addrlen);
+                if (ret == 0) {
+                        found = _gf_true;
+                        gf_log ("glusterd", GF_LOG_INFO, "%s is local", get_ip_from_addrinfo (res, &ip));
+                        close (sd);
+                        break;
                 }
+                close (sd);
         }
 
 out:
-        if (sd >= 0)
-                close (sd);
-
         if (result)
                 freeaddrinfo (result);
 
-        if (need_free)
-                GF_FREE (buf.ifc_req);
-
         if (found)
                 gf_log ("glusterd", GF_LOG_DEBUG, "%s is local", hostname);
         else
@@ -653,21 +650,18 @@  glusterd_brickinfo_from_brick (char *brick,
         glusterd_brickinfo_t    *new_brickinfo = NULL;
         char                    *hostname = NULL;
         char                    *path = NULL;
-        char                    *tmp = NULL;
-        char                    *tmpstr = NULL;
+        char                    *tmp_host = NULL;
+        char                    *tmp_path = NULL;
 
         GF_ASSERT (brick);
         GF_ASSERT (brickinfo);
 
-        tmp = gf_strdup (brick);
-        if (!tmp) {
-                gf_log ("glusterd", GF_LOG_ERROR,
-                        "Out of memory");
-                goto out;
-        }
-
-        hostname = strtok_r (tmp, ":", &tmpstr);
-        path = strtok_r (NULL, ":", &tmpstr);
+        tmp_host = gf_strdup (brick);
+        if (tmp_host)
+                get_host_name (tmp_host, &hostname);
+        tmp_path = gf_strdup (brick);
+        if (tmp_path)
+                get_path_name (tmp_path, &path);
 
         GF_ASSERT (hostname);
         GF_ASSERT (path);
@@ -684,8 +678,10 @@  glusterd_brickinfo_from_brick (char *brick,
 
         ret = 0;
 out:
-        if (tmp)
-                GF_FREE (tmp);
+        if (tmp_host)
+                GF_FREE (tmp_host);
+        if (tmp_host)
+                GF_FREE (tmp_path);
         gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
         return ret;
 }
@@ -771,26 +767,20 @@  glusterd_volume_brickinfo_get_by_brick (char *brick,
         int32_t                 ret = -1;
         char                    *hostname = NULL;
         char                    *path = NULL;
-        char                    *dup_brick = NULL;
-        char                    *free_ptr = NULL;
+        char                    *tmp_host = NULL;
+        char                    *tmp_path = NULL;
 
         GF_ASSERT (brick);
         GF_ASSERT (volinfo);
 
         gf_log ("", GF_LOG_INFO, "brick: %s", brick);
 
-        dup_brick = gf_strdup (brick);
-        if (!dup_brick) {
-                gf_log ("", GF_LOG_ERROR,
-                        "Out of memory");
-                ret = -1;
-                goto out;
-        } else {
-                free_ptr = dup_brick;
-        }
-
-        hostname = strtok (dup_brick, ":");
-        path = strtok (NULL, ":");
+        tmp_host = gf_strdup (brick);
+        if (tmp_host)
+                get_host_name (tmp_host, &hostname);
+        tmp_path = gf_strdup (brick);
+        if (tmp_path)
+                get_path_name (tmp_path, &path);
 
         if (!hostname || !path) {
                 gf_log ("", GF_LOG_ERROR,
@@ -803,9 +793,10 @@  glusterd_volume_brickinfo_get_by_brick (char *brick,
         ret = glusterd_volume_brickinfo_get (NULL, hostname, path, volinfo,
                                              brickinfo);
 out:
-        if (free_ptr)
-                GF_FREE (free_ptr);
-
+        if (tmp_host)
+                GF_FREE (tmp_host);
+        if (tmp_path)
+                GF_FREE (tmp_path);
         gf_log ("", GF_LOG_DEBUG, "Returning %d", ret);
         return ret;
 }
@@ -2259,21 +2250,29 @@  glusterd_remote_hostname_get (rpcsvc_request_t *req, char *remote_host, int len)
         GF_ASSERT (req->trans);
 
         char *name = NULL;
-        char *delimiter = NULL;
+        char *hostname = NULL;
+        char *tmp_host = NULL;
+        int  ret = 0;
 
         name = req->trans->peerinfo.identifier;
-        strncpy (remote_host, name, len);
-        delimiter = strchr (remote_host, ':');
+        tmp_host = gf_strdup (name);
+        if (tmp_host)
+                get_host_name (tmp_host, &hostname);
 
-        GF_ASSERT (delimiter);
-        if (!delimiter) {
+        GF_ASSERT (hostname);
+        if (!hostname) {
                 memset (remote_host, 0, len);
-                return -1;
+                ret = -1;
+                goto out;
         }
 
-        *delimiter = '\0';
+        strncpy (remote_host, hostname, strlen (hostname));
 
-        return 0;
+
+out:
+        if (tmp_host)
+                GF_FREE (tmp_host);
+        return ret;
 }
 
 int
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index e429eca..1c5a548 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -189,7 +189,7 @@  main ()
     volfile_loc="$1";
 
     [ -r "$volfile_loc" ] || {
-	server_ip=$(echo "$volfile_loc" | sed -n 's/\([^\:]*\).*/\1/p');
+        server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:.\-]*\):.*/\1/p');
         test_str=$(echo "$volfile_loc" | sed -n 's/.*:\([^ ]*\).*/\1/p');
         [ -n "$test_str" ] && {
             volume_id="$test_str";
diff --git a/xlators/mount/fuse/utils/mount_glusterfs.in b/xlators/mount/fuse/utils/mount_glusterfs.in
index 20600bb..4fced68 100755
--- a/xlators/mount/fuse/utils/mount_glusterfs.in
+++ b/xlators/mount/fuse/utils/mount_glusterfs.in
@@ -172,7 +172,7 @@  main ()
     done
     
     [ -r "$volfile_loc" ] || {
-	server_ip=$(echo "$volfile_loc" | sed -n 's/\([^\:]*\).*/\1/p');
+        server_ip=$(echo "$volfile_loc" | sed -n 's/\([a-zA-Z0-9:.\-]*\):.*/\1/p');
 	volfile_loc="";
     }
     # following line is product of love towards sed