From f50e5eb7777ee31701f5d757ffa8de2c238b5e50 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 20 Jun 2011 07:59:27 +0000 Subject: Glusterd: IPV6 support for glusterfs. Signed-off-by: Gaurav Signed-off-by: Anand Avati BUG: 2456 (IPv6 support for glusterd) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2456 --- 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(-) diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index a8aebaeb0..0097703f6 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 :" "", 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); @@ -844,14 +847,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 :" "", words[brick_index]); ret = -1; goto out; } else { + delimiter = strrchr(words[brick_index], ':'); cli_path_strip_trailing_slashes (delimiter + 1); } @@ -938,14 +940,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 " ":", 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]); @@ -958,14 +959,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 " ":", 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 d55781e23..8d37405c6 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -523,7 +523,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 758868343..295435af7 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 e42945bf0..9afa28058 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 89daa5a92..e26e1d95f 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 1880ec502..56e03e662 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 01a403c0a..e0fc07e7f 100755 --- a/xlators/mount/fuse/utils/mount.glusterfs.in +++ b/xlators/mount/fuse/utils/mount.glusterfs.in @@ -210,7 +210,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 20600bb7c..4fced68f5 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 -- cgit