summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/common-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/common-utils.c')
-rw-r--r--libglusterfs/src/common-utils.c659
1 files changed, 630 insertions, 29 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 6e94169de..827475282 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -44,6 +44,8 @@
#include "stack.h"
#include "globals.h"
#include "lkowner.h"
+#include "syscall.h"
+#include <ifaddrs.h>
#ifndef AI_ADDRCONFIG
#define AI_ADDRCONFIG 0
@@ -57,6 +59,16 @@ struct dnscache6 {
struct addrinfo *next;
};
+void
+md5_wrapper(const unsigned char *data, size_t len, char *md5)
+{
+ unsigned short i = 0;
+ unsigned short lim = MD5_DIGEST_LENGTH*2+1;
+ unsigned char scratch[MD5_DIGEST_LENGTH] = {0,};
+ MD5(data, len, scratch);
+ for (; i < MD5_DIGEST_LENGTH; i++)
+ snprintf(md5 + i * 2, lim-i*2, "%02x", scratch[i]);
+}
/* works similar to mkdir(1) -p.
*/
@@ -113,6 +125,35 @@ out:
}
int
+gf_lstat_dir (const char *path, struct stat *stbuf_in)
+{
+ int ret = -1;
+ struct stat stbuf = {0,};
+
+ if (path == NULL) {
+ errno = EINVAL;
+ goto out;
+ }
+
+ ret = sys_lstat (path, &stbuf);
+ if (ret)
+ goto out;
+
+ if (!S_ISDIR (stbuf.st_mode)) {
+ errno = ENOTDIR;
+ ret = -1;
+ goto out;
+ }
+ ret = 0;
+
+out:
+ if (!ret && stbuf_in)
+ *stbuf_in = stbuf;
+
+ return ret;
+}
+
+int
log_base2 (unsigned long x)
{
int val = 0;
@@ -238,30 +279,101 @@ err:
}
+struct xldump {
+ int lineno;
+ FILE *logfp;
+};
+
+
+static int
+nprintf (struct xldump *dump, const char *fmt, ...)
+{
+ va_list ap;
+ int ret = 0;
+
+
+ ret += fprintf (dump->logfp, "%3d: ", ++dump->lineno);
+
+ va_start (ap, fmt);
+ ret += vfprintf (dump->logfp, fmt, ap);
+ va_end (ap);
+
+ ret += fprintf (dump->logfp, "\n");
+
+ return ret;
+}
+
+
+static int
+xldump_options (dict_t *this, char *key, data_t *value, void *d)
+{
+ nprintf (d, " option %s %s", key, value->data);
+ return 0;
+}
+
+
+static void
+xldump_subvolumes (xlator_t *this, void *d)
+{
+ xlator_list_t *subv = NULL;
+ int len = 0;
+ char *subvstr = NULL;
+
+ subv = this->children;
+ if (!this->children)
+ return;
+
+ for (subv = this->children; subv; subv = subv->next)
+ len += (strlen (subv->xlator->name) + 1);
+
+ subvstr = GF_CALLOC (1, len, gf_common_mt_strdup);
+
+ len = 0;
+ for (subv = this->children; subv; subv= subv->next)
+ len += sprintf (subvstr + len, "%s%s", subv->xlator->name,
+ subv->next ? " " : "");
+
+ nprintf (d, " subvolumes %s", subvstr);
+
+ GF_FREE (subvstr);
+}
+
+
+static void
+xldump (xlator_t *each, void *d)
+{
+ nprintf (d, "volume %s", each->name);
+ nprintf (d, " type %s", each->type);
+ dict_foreach (each->options, xldump_options, d);
+
+ xldump_subvolumes (each, d);
+
+ nprintf (d, "end-volume");
+ nprintf (d, "");
+}
+
+
void
-gf_log_volume_file (FILE *specfp)
+gf_log_dump_graph (FILE *specfp, glusterfs_graph_t *graph)
{
- int lcount = 0;
- char data[GF_UNIT_KB];
glusterfs_ctx_t *ctx;
+ struct xldump xld = {0, };
- ctx = THIS->ctx;
- fseek (specfp, 0L, SEEK_SET);
+ ctx = THIS->ctx;
+ xld.logfp = ctx->log.gf_log_logfile;
- fprintf (ctx->log.gf_log_logfile, "Given volfile:\n");
+ fprintf (ctx->log.gf_log_logfile, "Final graph:\n");
fprintf (ctx->log.gf_log_logfile,
"+---------------------------------------"
"---------------------------------------+\n");
- while (fgets (data, GF_UNIT_KB, specfp) != NULL){
- lcount++;
- fprintf (ctx->log.gf_log_logfile, "%3d: %s", lcount, data);
- }
+
+ xlator_foreach_depth_first (graph->top, xldump, &xld);
+
fprintf (ctx->log.gf_log_logfile,
- "\n+---------------------------------------"
+ "+---------------------------------------"
"---------------------------------------+\n");
fflush (ctx->log.gf_log_logfile);
- fseek (specfp, 0L, SEEK_SET);
}
static void
@@ -407,6 +519,14 @@ gf_print_trace (int32_t signum, glusterfs_ctx_t *ctx)
fd = fileno (ctx->log.gf_log_logfile);
+ /* Now every gf_log call will just write to a buffer and when the
+ * buffer becomes full, its written to the log-file. Suppose the process
+ * crashes and prints the backtrace in the log-file, then the previous
+ * log information will still be in the buffer itself. So flush the
+ * contents of the buffer to the log file before printing the backtrace
+ * which helps in debugging.
+ */
+ fflush (ctx->log.gf_log_logfile);
/* Pending frames, (if any), list them in order */
ret = write (fd, "pending frames:\n", 16);
if (ret < 0)
@@ -658,6 +778,8 @@ gf_string2time (const char *str, uint32_t *n)
old_errno = errno;
errno = 0;
value = strtol (str, &tail, 0);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -701,6 +823,8 @@ gf_string2percent (const char *str, double *n)
old_errno = errno;
errno = 0;
value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -734,6 +858,8 @@ _gf_string2long (const char *str, long *n, int base)
old_errno = errno;
errno = 0;
value = strtol (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -774,6 +900,8 @@ _gf_string2ulong (const char *str, unsigned long *n, int base)
old_errno = errno;
errno = 0;
value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -814,6 +942,8 @@ _gf_string2uint (const char *str, unsigned int *n, int base)
old_errno = errno;
errno = 0;
value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -845,6 +975,8 @@ _gf_string2double (const char *str, double *n)
old_errno = errno;
errno = 0;
value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -876,6 +1008,8 @@ _gf_string2longlong (const char *str, long long *n, int base)
old_errno = errno;
errno = 0;
value = strtoll (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -916,6 +1050,8 @@ _gf_string2ulonglong (const char *str, unsigned long long *n, int base)
old_errno = errno;
errno = 0;
value = strtoull (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -989,7 +1125,7 @@ gf_string2int8 (const char *str, int8_t *n)
if (rv != 0)
return rv;
- if (l >= INT8_MIN && l <= INT8_MAX) {
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
*n = (int8_t) l;
return 0;
}
@@ -1008,7 +1144,7 @@ gf_string2int16 (const char *str, int16_t *n)
if (rv != 0)
return rv;
- if (l >= INT16_MIN && l <= INT16_MAX) {
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
*n = (int16_t) l;
return 0;
}
@@ -1027,7 +1163,7 @@ gf_string2int32 (const char *str, int32_t *n)
if (rv != 0)
return rv;
- if (l >= INT32_MIN && l <= INT32_MAX) {
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
*n = (int32_t) l;
return 0;
}
@@ -1046,7 +1182,7 @@ gf_string2int64 (const char *str, int64_t *n)
if (rv != 0)
return rv;
- if (l >= INT64_MIN && l <= INT64_MAX) {
+ if ((l >= INT64_MIN) && (l <= INT64_MAX)) {
*n = (int64_t) l;
return 0;
}
@@ -1280,6 +1416,8 @@ gf_string2bytesize (const char *str, uint64_t *n)
old_errno = errno;
errno = 0;
value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -1303,6 +1441,11 @@ gf_string2bytesize (const char *str, uint64_t *n)
return -1;
}
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+
*n = (uint64_t) value;
return 0;
@@ -1313,7 +1456,7 @@ gf_string2percent_or_bytesize (const char *str,
uint64_t *n,
gf_boolean_t *is_percent)
{
- uint64_t value = 0ULL;
+ double value = 0ULL;
char *tail = NULL;
int old_errno = 0;
const char *s = NULL;
@@ -1335,7 +1478,9 @@ gf_string2percent_or_bytesize (const char *str,
old_errno = errno;
errno = 0;
- value = strtoull (str, &tail, 10);
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
if (errno == ERANGE || errno == EINVAL)
return -1;
@@ -1360,7 +1505,13 @@ gf_string2percent_or_bytesize (const char *str,
return -1;
}
- *n = value;
+ /* Error out if we cannot store the value in uint64 */
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
+
+ *n = (uint64_t) value;
return 0;
}
@@ -1650,6 +1801,19 @@ valid_host_name (char *address, int length)
goto out;
}
+ if (!isalnum (dup_addr[length - 1]) && (dup_addr[length - 1] != '*')) {
+ ret = 0;
+ goto out;
+ }
+
+ /* Check for consecutive dots, which is invalid in a hostname and is
+ * ignored by strtok()
+ */
+ if (strstr (dup_addr, "..")) {
+ ret = 0;
+ goto out;
+ }
+
/* gen-name */
temp_str = strtok_r (dup_addr, ".", &save_ptr);
do {
@@ -1686,8 +1850,13 @@ valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc)
tmp = gf_strdup (address);
- /* To prevent cases where last character is '.' */
+ /*
+ * To prevent cases where last character is '.' and which have
+ * consecutive dots like ".." as strtok ignore consecutive
+ * delimeters.
+ */
if (length <= 0 ||
+ (strstr (address, "..")) ||
(!isdigit (tmp[length - 1]) && (tmp[length - 1] != '*'))) {
ret = 0;
goto out;
@@ -1800,6 +1969,50 @@ out:
return ret;
}
+/**
+ * gf_sock_union_equal_addr - check if two given gf_sock_unions have same addr
+ *
+ * @param a - first sock union
+ * @param b - second sock union
+ * @return _gf_true if a and b have same ipv{4,6} addr, _gf_false otherwise
+ */
+gf_boolean_t
+gf_sock_union_equal_addr (union gf_sock_union *a,
+ union gf_sock_union *b)
+{
+ if (!a || !b) {
+ gf_log ("common-utils", GF_LOG_ERROR, "Invalid arguments"
+ " to gf_sock_union_equal_addr");
+ return _gf_false;
+ }
+
+ if (a->storage.ss_family != b->storage.ss_family)
+ return _gf_false;
+
+ switch (a->storage.ss_family) {
+ case AF_INET:
+ if (a->sin.sin_addr.s_addr == b->sin.sin_addr.s_addr)
+ return _gf_true;
+ else
+ return _gf_false;
+
+ case AF_INET6:
+ if (memcmp ((void *)(&a->sin6.sin6_addr),
+ (void *)(&b->sin6.sin6_addr),
+ sizeof (a->sin6.sin6_addr)))
+ return _gf_false;
+ else
+ return _gf_true;
+
+ default:
+ gf_log ("common-utils", GF_LOG_DEBUG,
+ "Unsupported/invalid address family");
+ break;
+ }
+
+ return _gf_false;
+}
+
/*Thread safe conversion function*/
char *
uuid_utoa (uuid_t uuid)
@@ -2169,10 +2382,11 @@ generate_glusterfs_ctx_id (void)
char *
gf_get_reserved_ports ()
{
+ char *ports_info = NULL;
+#if defined GF_LINUX_HOST_OS
int proc_fd = -1;
char *proc_file = "/proc/sys/net/ipv4/ip_local_reserved_ports";
char buffer[4096] = {0,};
- char *ports_info = NULL;
int32_t ret = -1;
proc_fd = open (proc_file, O_RDONLY);
@@ -2201,6 +2415,7 @@ gf_get_reserved_ports ()
out:
if (proc_fd != -1)
close (proc_fd);
+#endif /* GF_LINUX_HOST_OS */
return ports_info;
}
@@ -2208,6 +2423,7 @@ int
gf_process_reserved_ports (gf_boolean_t *ports)
{
int ret = -1;
+#if defined GF_LINUX_HOST_OS
char *ports_info = NULL;
char *tmp = NULL;
char *blocked_port = NULL;
@@ -2220,23 +2436,18 @@ gf_process_reserved_ports (gf_boolean_t *ports)
goto out;
}
- blocked_port = strtok_r (ports_info, ",",&tmp);
- if (!blocked_port || !strcmp (blocked_port, ports_info)) {
- if (!blocked_port)
- blocked_port = ports_info;
- gf_ports_reserved (blocked_port, ports);
- blocked_port = strtok_r (NULL, ",", &tmp);
- }
+ blocked_port = strtok_r (ports_info, ",\n",&tmp);
while (blocked_port) {
gf_ports_reserved (blocked_port, ports);
- blocked_port = strtok_r (NULL, ",", &tmp);
+ blocked_port = strtok_r (NULL, ",\n", &tmp);
}
ret = 0;
out:
GF_FREE (ports_info);
+#endif /* GF_LINUX_HOST_OS */
return ret;
}
@@ -2305,3 +2516,393 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports)
out:
return result;
}
+
+/* Takes in client ip{v4,v6} and returns associated hostname, if any
+ * Also, allocates memory for the hostname.
+ * Returns: 0 for success, -1 for failure
+ */
+int
+gf_get_hostname_from_ip (char *client_ip, char **hostname)
+{
+ int ret = -1;
+ struct sockaddr *client_sockaddr = NULL;
+ struct sockaddr_in client_sock_in = {0};
+ struct sockaddr_in6 client_sock_in6 = {0};
+ char client_hostname[NI_MAXHOST] = {0};
+ char *client_ip_copy = NULL;
+ char *tmp = NULL;
+ char *ip = NULL;
+
+ /* if ipv4, reverse lookup the hostname to
+ * allow FQDN based rpc authentication
+ */
+ if (valid_ipv4_address (client_ip, strlen (client_ip), 0) == _gf_false) {
+ /* most times, we get a.b.c.d:port form, so check that */
+ client_ip_copy = gf_strdup (client_ip);
+ if (!client_ip_copy)
+ goto out;
+
+ ip = strtok_r (client_ip_copy, ":", &tmp);
+ } else {
+ ip = client_ip;
+ }
+
+ if (valid_ipv4_address (ip, strlen (ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *)&client_sock_in;
+ client_sock_in.sin_family = AF_INET;
+ ret = inet_pton (AF_INET, ip,
+ (void *)&client_sock_in.sin_addr.s_addr);
+
+ } else if (valid_ipv6_address (ip, strlen (ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *) &client_sock_in6;
+
+ client_sock_in6.sin6_family = AF_INET6;
+ ret = inet_pton (AF_INET6, ip,
+ (void *)&client_sock_in6.sin6_addr);
+ } else {
+ goto out;
+ }
+
+ if (ret != 1) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = getnameinfo (client_sockaddr,
+ sizeof (*client_sockaddr),
+ client_hostname, sizeof (client_hostname),
+ NULL, 0, 0);
+ if (ret) {
+ gf_log ("common-utils", GF_LOG_ERROR,
+ "Could not lookup hostname of %s : %s",
+ client_ip, gai_strerror (ret));
+ ret = -1;
+ goto out;
+ }
+
+ *hostname = gf_strdup ((char *)client_hostname);
+ out:
+ if (client_ip_copy)
+ GF_FREE (client_ip_copy);
+
+ return ret;
+}
+
+gf_boolean_t
+gf_interface_search (char *ip)
+{
+ int32_t ret = -1;
+ gf_boolean_t found = _gf_false;
+ struct ifaddrs *ifaddr, *ifa;
+ int family;
+ char host[NI_MAXHOST];
+ xlator_t *this = NULL;
+ char *pct = NULL;
+
+ this = THIS;
+
+ ret = getifaddrs (&ifaddr);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "getifaddrs() failed: %s\n",
+ gai_strerror(ret));
+ goto out;
+ }
+
+ for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
+ if (!ifa->ifa_addr) {
+ /*
+ * This seemingly happens if an interface hasn't
+ * been bound to a particular protocol (seen with
+ * TUN devices).
+ */
+ continue;
+ }
+ family = ifa->ifa_addr->sa_family;
+
+ if (family != AF_INET && family != AF_INET6)
+ continue;
+
+ ret = getnameinfo (ifa->ifa_addr,
+ (family == AF_INET) ? sizeof(struct sockaddr_in) :
+ sizeof(struct sockaddr_in6),
+ host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "getnameinfo() failed: %s\n",
+ gai_strerror(ret));
+ goto out;
+ }
+
+ /*
+ * Sometimes the address comes back as addr%eth0 or
+ * similar. Since % is an invalid character, we can
+ * strip it out with confidence that doing so won't
+ * harm anything.
+ */
+ pct = index(host,'%');
+ if (pct) {
+ *pct = '\0';
+ }
+
+ if (strncmp (ip, host, NI_MAXHOST) == 0) {
+ gf_log (this->name, GF_LOG_DEBUG,
+ "%s is local address at interface %s",
+ ip, ifa->ifa_name);
+ found = _gf_true;
+ goto out;
+ }
+ }
+out:
+ if(ifaddr)
+ freeifaddrs (ifaddr);
+ return found;
+}
+
+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;
+}
+
+gf_boolean_t
+gf_is_loopback_localhost (const struct sockaddr *sa, char *hostname)
+{
+ GF_ASSERT (sa);
+
+ gf_boolean_t is_local = _gf_false;
+ const struct in_addr *addr4 = NULL;
+ const struct in6_addr *addr6 = NULL;
+ uint8_t *ap = NULL;
+ struct in6_addr loopbackaddr6 = IN6ADDR_LOOPBACK_INIT;
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ addr4 = &(((struct sockaddr_in *)sa)->sin_addr);
+ ap = (uint8_t*)&addr4->s_addr;
+ if (ap[0] == 127)
+ is_local = _gf_true;
+ break;
+
+ case AF_INET6:
+ addr6 = &(((struct sockaddr_in6 *)sa)->sin6_addr);
+ if (memcmp (addr6, &loopbackaddr6,
+ sizeof (loopbackaddr6)) == 0)
+ is_local = _gf_true;
+ break;
+
+ default:
+ if (hostname)
+ gf_log ("glusterd", GF_LOG_ERROR,
+ "unknown address family %d for %s",
+ sa->sa_family, hostname);
+ break;
+ }
+
+ return is_local;
+}
+
+gf_boolean_t
+gf_is_local_addr (char *hostname)
+{
+ int32_t ret = -1;
+ struct addrinfo *result = NULL;
+ struct addrinfo *res = NULL;
+ gf_boolean_t found = _gf_false;
+ char *ip = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ ret = getaddrinfo (hostname, NULL, NULL, &result);
+
+ if (ret != 0) {
+ gf_log (this->name, GF_LOG_ERROR, "error in getaddrinfo: %s\n",
+ gai_strerror(ret));
+ goto out;
+ }
+
+ for (res = result; res != NULL; res = res->ai_next) {
+ gf_log (this->name, GF_LOG_DEBUG, "%s ",
+ get_ip_from_addrinfo (res, &ip));
+
+ found = gf_is_loopback_localhost (res->ai_addr, hostname)
+ || gf_interface_search (ip);
+ if (found)
+ goto out;
+ }
+
+out:
+ if (result)
+ freeaddrinfo (result);
+
+ if (!found)
+ gf_log (this->name, GF_LOG_DEBUG, "%s is not local", hostname);
+
+ return found;
+}
+
+gf_boolean_t
+gf_is_same_address (char *name1, char *name2)
+{
+ struct addrinfo *addr1 = NULL;
+ struct addrinfo *addr2 = NULL;
+ struct addrinfo *p = NULL;
+ struct addrinfo *q = NULL;
+ gf_boolean_t ret = _gf_false;
+ int gai_err = 0;
+
+ gai_err = getaddrinfo(name1,NULL,NULL,&addr1);
+ if (gai_err != 0) {
+ gf_log (name1, GF_LOG_WARNING,
+ "error in getaddrinfo: %s\n", gai_strerror(gai_err));
+ goto out;
+ }
+
+ gai_err = getaddrinfo(name2,NULL,NULL,&addr2);
+ if (gai_err != 0) {
+ gf_log (name2, GF_LOG_WARNING,
+ "error in getaddrinfo: %s\n", gai_strerror(gai_err));
+ goto out;
+ }
+
+ for (p = addr1; p; p = p->ai_next) {
+ for (q = addr2; q; q = q->ai_next) {
+ if (p->ai_addrlen != q->ai_addrlen) {
+ continue;
+ }
+ if (memcmp(p->ai_addr,q->ai_addr,p->ai_addrlen)) {
+ continue;
+ }
+ ret = _gf_true;
+ goto out;
+ }
+ }
+
+out:
+ if (addr1) {
+ freeaddrinfo(addr1);
+ }
+ if (addr2) {
+ freeaddrinfo(addr2);
+ }
+ return ret;
+
+}
+
+
+/* Sets log file path from user provided arguments */
+int
+gf_set_log_file_path (cmd_args_t *cmd_args)
+{
+ int i = 0;
+ int j = 0;
+ int ret = 0;
+ char tmp_str[1024] = {0,};
+
+ if (!cmd_args)
+ goto done;
+
+ if (cmd_args->mount_point) {
+ j = 0;
+ i = 0;
+ if (cmd_args->mount_point[0] == '/')
+ i = 1;
+ for (; i < strlen (cmd_args->mount_point); i++,j++) {
+ tmp_str[j] = cmd_args->mount_point[i];
+ if (cmd_args->mount_point[i] == '/')
+ tmp_str[j] = '-';
+ }
+
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log",
+ tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (cmd_args->volfile) {
+ j = 0;
+ i = 0;
+ if (cmd_args->volfile[0] == '/')
+ i = 1;
+ for (; i < strlen (cmd_args->volfile); i++,j++) {
+ tmp_str[j] = cmd_args->volfile[i];
+ if (cmd_args->volfile[i] == '/')
+ tmp_str[j] = '-';
+ }
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s.log",
+ tmp_str);
+ if (ret > 0)
+ ret = 0;
+ goto done;
+ }
+
+ if (cmd_args->volfile_server) {
+
+ ret = gf_asprintf (&cmd_args->log_file,
+ DEFAULT_LOG_FILE_DIRECTORY "/%s-%s-%d.log",
+ cmd_args->volfile_server,
+ cmd_args->volfile_id, getpid());
+ if (ret > 0)
+ ret = 0;
+ }
+done:
+ return ret;
+}
+
+int
+gf_thread_create (pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void *), void *arg)
+{
+ sigset_t set, old;
+ int ret;
+
+ sigemptyset (&set);
+
+ sigfillset (&set);
+ sigdelset (&set, SIGSEGV);
+ sigdelset (&set, SIGBUS);
+ sigdelset (&set, SIGILL);
+ sigdelset (&set, SIGSYS);
+ sigdelset (&set, SIGFPE);
+ sigdelset (&set, SIGABRT);
+
+ pthread_sigmask (SIG_BLOCK, &set, &old);
+
+ ret = pthread_create (thread, attr, start_routine, arg);
+
+ pthread_sigmask (SIG_SETMASK, &old, NULL);
+
+ return ret;
+}