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.c3162
1 files changed, 2251 insertions, 911 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index e4c7e2c31..827475282 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -1,20 +1,11 @@
/*
- Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.com>
+ Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
This file is part of GlusterFS.
- GlusterFS is free software; you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- GlusterFS is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see
- <http://www.gnu.org/licenses/>.
+ This file is licensed to you under your choice of the GNU Lesser
+ General Public License, version 3 or any later version (LGPLv3 or
+ later), or the GNU General Public License, version 2 (GPLv2), in all
+ cases as published by the Free Software Foundation.
*/
#ifndef _CONFIG_H
@@ -40,22 +31,127 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
+#include <stdlib.h>
+
+#if defined GF_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+#include <sys/sysctl.h>
+#endif
#include "logging.h"
#include "common-utils.h"
#include "revision.h"
#include "glusterfs.h"
#include "stack.h"
+#include "globals.h"
+#include "lkowner.h"
+#include "syscall.h"
+#include <ifaddrs.h>
+
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
typedef int32_t (*rw_op_t)(int32_t fd, char *buf, int32_t size);
typedef int32_t (*rwv_op_t)(int32_t fd, const struct iovec *buf, int32_t size);
-
struct dnscache6 {
- struct addrinfo *first;
- struct addrinfo *next;
+ struct addrinfo *first;
+ 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.
+ */
+int
+mkdir_p (char *path, mode_t mode, gf_boolean_t allow_symlinks)
+{
+ int i = 0;
+ int ret = -1;
+ char dir[PATH_MAX] = {0,};
+ struct stat stbuf = {0,};
+
+ strcpy (dir, path);
+ i = (dir[0] == '/')? 1: 0;
+ do {
+ if (path[i] != '/' && path[i] != '\0')
+ continue;
+
+ dir[i] = '\0';
+ ret = mkdir (dir, mode);
+ if (ret && errno != EEXIST) {
+ gf_log ("", GF_LOG_ERROR, "Failed due to reason %s",
+ strerror (errno));
+ goto out;
+ }
+
+ if (ret && errno == EEXIST && !allow_symlinks) {
+ ret = lstat (dir, &stbuf);
+ if (ret)
+ goto out;
+
+ if (S_ISLNK (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "%s is a symlink",
+ dir);
+ goto out;
+ }
+ }
+ dir[i] = '/';
+
+ } while (path[i++] != '\0');
+
+ ret = stat (dir, &stbuf);
+ if (ret || !S_ISDIR (stbuf.st_mode)) {
+ ret = -1;
+ gf_log ("", GF_LOG_ERROR, "Failed to create directory, "
+ "possibly some of the components were not directories");
+ goto out;
+ }
+
+ ret = 0;
+out:
+
+ return ret;
+}
+
+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)
@@ -73,138 +169,211 @@ log_base2 (unsigned long x)
int32_t
gf_resolve_ip6 (const char *hostname,
- uint16_t port,
- int family,
- void **dnscache,
- struct addrinfo **addr_info)
-{
- int32_t ret = 0;
- struct addrinfo hints;
- struct dnscache6 *cache = NULL;
- char service[NI_MAXSERV], host[NI_MAXHOST];
-
- if (!hostname) {
- gf_log ("resolver", GF_LOG_WARNING, "hostname is NULL");
- return -1;
- }
+ uint16_t port,
+ int family,
+ void **dnscache,
+ struct addrinfo **addr_info)
+{
+ int32_t ret = 0;
+ struct addrinfo hints;
+ struct dnscache6 *cache = NULL;
+ char service[NI_MAXSERV], host[NI_MAXHOST];
+
+ if (!hostname) {
+ gf_log_callingfn ("resolver", GF_LOG_WARNING, "hostname is NULL");
+ return -1;
+ }
- if (!*dnscache) {
- *dnscache = GF_CALLOC (1, sizeof (struct dnscache6),
- gf_common_mt_dnscache6);
+ if (!*dnscache) {
+ *dnscache = GF_CALLOC (1, sizeof (struct dnscache6),
+ gf_common_mt_dnscache6);
if (!*dnscache)
return -1;
- }
-
- cache = *dnscache;
- if (cache->first && !cache->next) {
- freeaddrinfo(cache->first);
- cache->first = cache->next = NULL;
- gf_log ("resolver", GF_LOG_TRACE,
- "flushing DNS cache");
- }
+ }
- if (!cache->first) {
- char *port_str = NULL;
- gf_log ("resolver", GF_LOG_TRACE,
- "DNS cache not present, freshly probing hostname: %s",
- hostname);
+ cache = *dnscache;
+ if (cache->first && !cache->next) {
+ freeaddrinfo(cache->first);
+ cache->first = cache->next = NULL;
+ gf_log ("resolver", GF_LOG_TRACE,
+ "flushing DNS cache");
+ }
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = family;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_ADDRCONFIG;
+ if (!cache->first) {
+ char *port_str = NULL;
+ gf_log ("resolver", GF_LOG_TRACE,
+ "DNS cache not present, freshly probing hostname: %s",
+ hostname);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = family;
+ hints.ai_socktype = SOCK_STREAM;
+#ifndef __NetBSD__
+ hints.ai_flags = AI_ADDRCONFIG;
+#endif
- ret = gf_asprintf (&port_str, "%d", port);
+ ret = gf_asprintf (&port_str, "%d", port);
if (-1 == ret) {
gf_log ("resolver", GF_LOG_ERROR, "asprintf failed");
return -1;
}
- if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) {
- gf_log ("resolver", GF_LOG_ERROR,
- "getaddrinfo failed (%s)", gai_strerror (ret));
-
- GF_FREE (*dnscache);
- *dnscache = NULL;
- GF_FREE (port_str);
- return -1;
- }
- GF_FREE (port_str);
-
- cache->next = cache->first;
- }
+ if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) {
+ gf_log ("resolver", GF_LOG_ERROR,
+ "getaddrinfo failed (%s)", gai_strerror (ret));
- if (cache->next) {
- ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
- cache->next->ai_addrlen,
- host, sizeof (host),
- service, sizeof (service),
- NI_NUMERICHOST);
- if (ret != 0) {
- gf_log ("resolver",
- GF_LOG_ERROR,
- "getnameinfo failed (%s)", gai_strerror (ret));
- goto err;
- }
-
- gf_log ("resolver", GF_LOG_TRACE,
- "returning ip-%s (port-%s) for hostname: %s and port: %d",
- host, service, hostname, port);
-
- *addr_info = cache->next;
- }
+ GF_FREE (*dnscache);
+ *dnscache = NULL;
+ GF_FREE (port_str);
+ return -1;
+ }
+ GF_FREE (port_str);
+
+ cache->next = cache->first;
+ }
+
+ if (cache->next) {
+ ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
+ cache->next->ai_addrlen,
+ host, sizeof (host),
+ service, sizeof (service),
+ NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_log ("resolver", GF_LOG_ERROR,
+ "getnameinfo failed (%s)", gai_strerror (ret));
+ goto err;
+ }
+
+ gf_log ("resolver", GF_LOG_DEBUG,
+ "returning ip-%s (port-%s) for hostname: %s and port: %d",
+ host, service, hostname, port);
+
+ *addr_info = cache->next;
+ }
if (cache->next)
cache->next = cache->next->ai_next;
- if (cache->next) {
- ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
- cache->next->ai_addrlen,
- host, sizeof (host),
- service, sizeof (service),
- NI_NUMERICHOST);
- if (ret != 0) {
- gf_log ("resolver",
- GF_LOG_ERROR,
- "getnameinfo failed (%s)", gai_strerror (ret));
- goto err;
- }
-
- gf_log ("resolver", GF_LOG_TRACE,
- "next DNS query will return: ip-%s port-%s", host, service);
- }
+ if (cache->next) {
+ ret = getnameinfo((struct sockaddr *)cache->next->ai_addr,
+ cache->next->ai_addrlen,
+ host, sizeof (host),
+ service, sizeof (service),
+ NI_NUMERICHOST);
+ if (ret != 0) {
+ gf_log ("resolver", GF_LOG_ERROR,
+ "getnameinfo failed (%s)", gai_strerror (ret));
+ goto err;
+ }
- return 0;
+ gf_log ("resolver", GF_LOG_DEBUG,
+ "next DNS query will return: ip-%s port-%s", host, service);
+ }
+
+ return 0;
err:
- freeaddrinfo (cache->first);
- cache->first = cache->next = NULL;
- GF_FREE (cache);
- *dnscache = NULL;
- return -1;
+ freeaddrinfo (cache->first);
+ cache->first = cache->next = NULL;
+ GF_FREE (cache);
+ *dnscache = NULL;
+ return -1;
+}
+
+
+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)
{
- extern FILE *gf_log_logfile;
- int lcount = 0;
- char data[GF_UNIT_KB];
+ glusterfs_ctx_t *ctx;
+ struct xldump xld = {0, };
- fseek (specfp, 0L, SEEK_SET);
- fprintf (gf_log_logfile, "Given volfile:\n");
- fprintf (gf_log_logfile,
- "+---------------------------------------"
- "---------------------------------------+\n");
- while (fgets (data, GF_UNIT_KB, specfp) != NULL){
- lcount++;
- fprintf (gf_log_logfile, "%3d: %s", lcount, data);
- }
- fprintf (gf_log_logfile,
- "\n+---------------------------------------"
- "---------------------------------------+\n");
- fflush (gf_log_logfile);
- fseek (specfp, 0L, SEEK_SET);
+ ctx = THIS->ctx;
+ xld.logfp = ctx->log.gf_log_logfile;
+
+ fprintf (ctx->log.gf_log_logfile, "Final graph:\n");
+ fprintf (ctx->log.gf_log_logfile,
+ "+---------------------------------------"
+ "---------------------------------------+\n");
+
+ xlator_foreach_depth_first (graph->top, xldump, &xld);
+
+ fprintf (ctx->log.gf_log_logfile,
+ "+---------------------------------------"
+ "---------------------------------------+\n");
+ fflush (ctx->log.gf_log_logfile);
}
static void
@@ -212,201 +381,223 @@ gf_dump_config_flags (int fd)
{
int ret = 0;
- ret = write (fd, "configuration details:\n", 23);
+ ret = write (fd, "configuration details:\n", 23);
if (ret == -1)
goto out;
/* have argp */
#ifdef HAVE_ARGP
- ret = write (fd, "argp 1\n", 7);
+ ret = write (fd, "argp 1\n", 7);
if (ret == -1)
goto out;
#endif
/* ifdef if found backtrace */
#ifdef HAVE_BACKTRACE
- ret = write (fd, "backtrace 1\n", 12);
+ ret = write (fd, "backtrace 1\n", 12);
if (ret == -1)
goto out;
#endif
/* Berkeley-DB version has cursor->get() */
#ifdef HAVE_BDB_CURSOR_GET
- ret = write (fd, "bdb->cursor->get 1\n", 19);
+ ret = write (fd, "bdb->cursor->get 1\n", 19);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <db.h> header file. */
#ifdef HAVE_DB_H
- ret = write (fd, "db.h 1\n", 7);
+ ret = write (fd, "db.h 1\n", 7);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <dlfcn.h> header file. */
#ifdef HAVE_DLFCN_H
- ret = write (fd, "dlfcn 1\n", 8);
+ ret = write (fd, "dlfcn 1\n", 8);
if (ret == -1)
goto out;
#endif
/* define if fdatasync exists */
#ifdef HAVE_FDATASYNC
- ret = write (fd, "fdatasync 1\n", 12);
+ ret = write (fd, "fdatasync 1\n", 12);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the `pthread' library (-lpthread). */
#ifdef HAVE_LIBPTHREAD
- ret = write (fd, "libpthread 1\n", 13);
+ ret = write (fd, "libpthread 1\n", 13);
if (ret == -1)
goto out;
#endif
/* define if llistxattr exists */
#ifdef HAVE_LLISTXATTR
- ret = write (fd, "llistxattr 1\n", 13);
+ ret = write (fd, "llistxattr 1\n", 13);
if (ret == -1)
goto out;
#endif
/* define if found setfsuid setfsgid */
#ifdef HAVE_SET_FSID
- ret = write (fd, "setfsid 1\n", 10);
+ ret = write (fd, "setfsid 1\n", 10);
if (ret == -1)
goto out;
#endif
/* define if found spinlock */
#ifdef HAVE_SPINLOCK
- ret = write (fd, "spinlock 1\n", 11);
+ ret = write (fd, "spinlock 1\n", 11);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <sys/epoll.h> header file. */
#ifdef HAVE_SYS_EPOLL_H
- ret = write (fd, "epoll.h 1\n", 10);
+ ret = write (fd, "epoll.h 1\n", 10);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <sys/extattr.h> header file. */
#ifdef HAVE_SYS_EXTATTR_H
- ret = write (fd, "extattr.h 1\n", 12);
+ ret = write (fd, "extattr.h 1\n", 12);
if (ret == -1)
goto out;
#endif
/* Define to 1 if you have the <sys/xattr.h> header file. */
#ifdef HAVE_SYS_XATTR_H
- ret = write (fd, "xattr.h 1\n", 10);
+ ret = write (fd, "xattr.h 1\n", 10);
if (ret == -1)
goto out;
#endif
/* define if found st_atim.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
- ret = write (fd, "st_atim.tv_nsec 1\n", 18);
+ ret = write (fd, "st_atim.tv_nsec 1\n", 18);
if (ret == -1)
goto out;
#endif
/* define if found st_atimespec.tv_nsec */
#ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC
- ret = write (fd, "st_atimespec.tv_nsec 1\n",23);
+ ret = write (fd, "st_atimespec.tv_nsec 1\n",23);
if (ret == -1)
goto out;
#endif
/* Define to the full name and version of this package. */
#ifdef PACKAGE_STRING
- {
- char msg[128];
- sprintf (msg, "package-string: %s\n", PACKAGE_STRING);
- ret = write (fd, msg, strlen (msg));
+ {
+ char msg[128];
+ sprintf (msg, "package-string: %s\n", PACKAGE_STRING);
+ ret = write (fd, msg, strlen (msg));
if (ret == -1)
goto out;
- }
+ }
#endif
out:
- return;
+ return;
}
/* Obtain a backtrace and print it to stdout. */
/* TODO: It looks like backtrace_symbols allocates memory,
it may be problem because mostly memory allocation/free causes 'sigsegv' */
+
void
-gf_print_trace (int32_t signum)
+gf_print_trace (int32_t signum, glusterfs_ctx_t *ctx)
{
- extern FILE *gf_log_logfile;
- struct tm *tm = NULL;
char msg[1024] = {0,};
- char timestr[256] = {0,};
- time_t utime = 0;
+ char timestr[64] = {0,};
int ret = 0;
int fd = 0;
- fd = fileno (gf_log_logfile);
-
- /* Pending frames, (if any), list them in order */
- ret = write (fd, "pending frames:\n", 16);
- {
- glusterfs_ctx_t *ctx = glusterfs_ctx_get ();
- struct list_head *trav = ((call_pool_t *)ctx->pool)->all_frames.next;
- while (trav != (&((call_pool_t *)ctx->pool)->all_frames)) {
- call_frame_t *tmp = (call_frame_t *)(&((call_stack_t *)trav)->frames);
- if (tmp->root->type == GF_OP_TYPE_FOP)
- sprintf (msg,"frame : type(%d) op(%s)\n",
- tmp->root->type,
- gf_fop_list[tmp->root->op]);
- if (tmp->root->type == GF_OP_TYPE_MGMT)
- sprintf (msg,"frame : type(%d) op(%s)\n",
- tmp->root->type,
- gf_mgmt_list[tmp->root->op]);
-
- ret = write (fd, msg, strlen (msg));
- trav = trav->next;
- }
- ret = write (fd, "\n", 1);
- }
+ 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)
+ goto out;
- sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
- ret = write (fd, msg, strlen (msg));
+ {
+ struct list_head *trav = ((call_pool_t *)ctx->pool)->all_frames.next;
+ while (trav != (&((call_pool_t *)ctx->pool)->all_frames)) {
+ call_frame_t *tmp = (call_frame_t *)(&((call_stack_t *)trav)->frames);
+ if (tmp->root->type == GF_OP_TYPE_FOP)
+ sprintf (msg,"frame : type(%d) op(%s)\n",
+ tmp->root->type,
+ gf_fop_list[tmp->root->op]);
+ else
+ sprintf (msg,"frame : type(%d) op(%d)\n",
+ tmp->root->type,
+ tmp->root->op);
+
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
+
+ trav = trav->next;
+ }
+ ret = write (fd, "\n", 1);
+ if (ret < 0)
+ goto out;
+ }
+
+ sprintf (msg, "patchset: %s\n", GLUSTERFS_REPOSITORY_REVISION);
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
- sprintf (msg, "signal received: %d\n", signum);
- ret = write (fd, msg, strlen (msg));
+ sprintf (msg, "signal received: %d\n", signum);
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
{
/* Dump the timestamp of the crash too, so the previous logs
can be related */
- utime = time (NULL);
- tm = localtime (&utime);
- strftime (timestr, 256, "%Y-%m-%d %H:%M:%S\n", tm);
+ gf_time_fmt (timestr, sizeof timestr, time (NULL), gf_timefmt_FT);
ret = write (fd, "time of crash: ", 15);
+ if (ret < 0)
+ goto out;
ret = write (fd, timestr, strlen (timestr));
+ if (ret < 0)
+ goto out;
}
- gf_dump_config_flags (fd);
+ gf_dump_config_flags (fd);
#if HAVE_BACKTRACE
- /* Print 'backtrace' */
- {
- void *array[200];
- size_t size;
-
- size = backtrace (array, 200);
- backtrace_symbols_fd (&array[1], size-1, fd);
- sprintf (msg, "---------\n");
- ret = write (fd, msg, strlen (msg));
- }
+ /* Print 'backtrace' */
+ {
+ void *array[200];
+ size_t size;
+
+ size = backtrace (array, 200);
+ backtrace_symbols_fd (&array[1], size-1, fd);
+ sprintf (msg, "---------\n");
+ ret = write (fd, msg, strlen (msg));
+ if (ret < 0)
+ goto out;
+ }
#endif /* HAVE_BACKTRACE */
- /* Send a signal to terminate the process */
- signal (signum, SIG_DFL);
- raise (signum);
+out:
+ /* Send a signal to terminate the process */
+ signal (signum, SIG_DFL);
+ raise (signum);
}
void
@@ -418,97 +609,90 @@ trap (void)
char *
gf_trim (char *string)
{
- register char *s, *t;
+ register char *s, *t;
- if (string == NULL)
- {
- return NULL;
- }
+ if (string == NULL) {
+ return NULL;
+ }
- for (s = string; isspace (*s); s++)
- ;
+ for (s = string; isspace (*s); s++)
+ ;
- if (*s == 0)
- return s;
+ if (*s == 0)
+ return s;
- t = s + strlen (s) - 1;
- while (t > s && isspace (*t))
- t--;
- *++t = '\0';
+ t = s + strlen (s) - 1;
+ while (t > s && isspace (*t))
+ t--;
+ *++t = '\0';
- return s;
+ return s;
}
int
gf_strsplit (const char *str, const char *delim,
- char ***tokens, int *token_count)
-{
- char *_running = NULL;
- char *running = NULL;
- char *token = NULL;
- char **token_list = NULL;
- int count = 0;
- int i = 0;
- int j = 0;
-
- if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL)
- {
- return -1;
- }
+ char ***tokens, int *token_count)
+{
+ char *_running = NULL;
+ char *running = NULL;
+ char *token = NULL;
+ char **token_list = NULL;
+ int count = 0;
+ int i = 0;
+ int j = 0;
+
+ if (str == NULL || delim == NULL || tokens == NULL || token_count == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ return -1;
+ }
_running = gf_strdup (str);
- if (_running == NULL)
- {
- return -1;
- }
- running = _running;
+ if (_running == NULL)
+ return -1;
- while ((token = strsep (&running, delim)) != NULL)
- {
- if (token[0] != '\0')
- count++;
- }
- GF_FREE (_running);
+ running = _running;
+
+ while ((token = strsep (&running, delim)) != NULL) {
+ if (token[0] != '\0')
+ count++;
+ }
+ GF_FREE (_running);
_running = gf_strdup (str);
- if (_running == NULL)
- {
- return -1;
- }
- running = _running;
+ if (_running == NULL)
+ return -1;
- if ((token_list = GF_CALLOC (count, sizeof (char *),
- gf_common_mt_char)) == NULL)
- {
- GF_FREE (_running);
- return -1;
- }
+ running = _running;
- while ((token = strsep (&running, delim)) != NULL)
- {
- if (token[0] == '\0')
- continue;
+ if ((token_list = GF_CALLOC (count, sizeof (char *),
+ gf_common_mt_char)) == NULL) {
+ GF_FREE (_running);
+ return -1;
+ }
+
+ while ((token = strsep (&running, delim)) != NULL) {
+ if (token[0] == '\0')
+ continue;
token_list[i] = gf_strdup (token);
- if (token_list[i] == NULL)
- goto free_exit;
+ if (token_list[i] == NULL)
+ goto free_exit;
i++;
- }
+ }
- GF_FREE (_running);
+ GF_FREE (_running);
- *tokens = token_list;
- *token_count = count;
- return 0;
+ *tokens = token_list;
+ *token_count = count;
+ return 0;
free_exit:
- GF_FREE (_running);
- for (j = 0; j < i; j++)
- {
- GF_FREE (token_list[j]);
- }
- GF_FREE (token_list);
- return -1;
+ GF_FREE (_running);
+ for (j = 0; j < i; j++)
+ GF_FREE (token_list[j]);
+
+ GF_FREE (token_list);
+ return -1;
}
int
@@ -523,9 +707,10 @@ gf_strstr (const char *str, const char *delim, const char *match)
tmp_str = strdup (str);
if (str == NULL || delim == NULL || match == NULL || tmp_str == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
ret = -1;
- goto out;
- }
+ goto out;
+ }
tmp = strtok_r (tmp_str, delim, &save_ptr);
@@ -540,8 +725,7 @@ gf_strstr (const char *str, const char *delim, const char *match)
}
out:
- if (tmp_str)
- free (tmp_str);
+ free (tmp_str);
return ret;
@@ -550,870 +734,882 @@ out:
int
gf_volume_name_validate (const char *volume_name)
{
- const char *vname = NULL;
+ const char *vname = NULL;
- if (volume_name == NULL)
- {
- return -1;
- }
+ if (volume_name == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ return -1;
+ }
- if (!isalpha (volume_name[0]))
- {
- return 1;
- }
+ if (!isalpha (volume_name[0]))
+ return 1;
- for (vname = &volume_name[1]; *vname != '\0'; vname++)
- {
- if (!(isalnum (*vname) || *vname == '_'))
- return 1;
- }
+ for (vname = &volume_name[1]; *vname != '\0'; vname++) {
+ if (!(isalnum (*vname) || *vname == '_'))
+ return 1;
+ }
- return 0;
+ return 0;
}
int
gf_string2time (const char *str, uint32_t *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- return -1;
- }
- break;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, 0);
+ old_errno = errno;
+ errno = 0;
+ value = strtol (str, &tail, 0);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (!((tail[0] == '\0') ||
- ((tail[0] == 's') && (tail[1] == '\0')) ||
- ((tail[0] == 's') && (tail[1] == 'e') && (tail[2] == 'c') && (tail[3] == '\0'))))
- {
- return -1;
- }
+ if (!((tail[0] == '\0') ||
+ ((tail[0] == 's') && (tail[1] == '\0')) ||
+ ((tail[0] == 's') && (tail[1] == 'e') &&
+ (tail[2] == 'c') && (tail[3] == '\0'))))
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
-
int
-gf_string2percent (const char *str, uint32_t *n)
+gf_string2percent (const char *str, double *n)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ double value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- return -1;
- }
- break;
- }
+ old_errno = errno;
+ errno = 0;
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, 0);
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (errno == 0)
- {
- errno = old_errno;
- }
-
- if (!((tail[0] == '\0') ||
- ((tail[0] == '%') && (tail[1] == '\0'))))
- {
- return -1;
- }
+ if (!((tail[0] == '\0') ||
+ ((tail[0] == '%') && (tail[1] == '\0'))))
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2long (const char *str, long *n, int base)
{
- long value = 0;
- char *tail = NULL;
- int old_errno = 0;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtol (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtol (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2ulong (const char *str, unsigned long *n, int base)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoul (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2uint (const char *str, unsigned int *n, int base)
{
- unsigned long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoul (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtoul (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = (unsigned int)value;
+ *n = (unsigned int)value;
- return 0;
+ return 0;
}
static int
_gf_string2double (const char *str, double *n)
{
- double value = 0.0;
- char *tail = NULL;
- int old_errno = 0;
-
- if (str == NULL || n == NULL) {
- errno = EINVAL;
- return -1;
- }
+ double value = 0.0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtod (str, &tail);
+ old_errno = errno;
+ errno = 0;
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL) {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0) {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0') {
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2longlong (const char *str, long long *n, int base)
{
- long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoll (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtoll (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
static int
_gf_string2ulonglong (const char *str, unsigned long long *n, int base)
{
- unsigned long long value = 0;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
-
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ unsigned long long value = 0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- old_errno = errno;
- errno = 0;
- value = strtoull (str, &tail, base);
+ old_errno = errno;
+ errno = 0;
+ value = strtoull (str, &tail, base);
+ if (str == tail)
+ errno = EINVAL;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (tail[0] != '\0')
- {
- /* bala: invalid integer format */
- return -1;
- }
+ if (tail[0] != '\0')
+ return -1;
- *n = value;
+ *n = value;
- return 0;
+ return 0;
}
int
gf_string2long (const char *str, long *n)
{
- return _gf_string2long (str, n, 0);
+ return _gf_string2long (str, n, 0);
}
int
gf_string2ulong (const char *str, unsigned long *n)
{
- return _gf_string2ulong (str, n, 0);
+ return _gf_string2ulong (str, n, 0);
}
int
gf_string2int (const char *str, int *n)
{
- return _gf_string2long (str, (long *) n, 0);
+ long l = 0;
+ int ret = 0;
+
+ ret = _gf_string2long (str, &l, 0);
+
+ *n = l;
+ return ret;
}
int
gf_string2uint (const char *str, unsigned int *n)
{
- return _gf_string2uint (str, n, 0);
+ return _gf_string2uint (str, n, 0);
}
int
gf_string2double (const char *str, double *n)
{
- return _gf_string2double (str, n);
+ return _gf_string2double (str, n);
}
int
gf_string2longlong (const char *str, long long *n)
{
- return _gf_string2longlong (str, n, 0);
+ return _gf_string2longlong (str, n, 0);
}
int
gf_string2ulonglong (const char *str, unsigned long long *n)
{
- return _gf_string2ulonglong (str, n, 0);
+ return _gf_string2ulonglong (str, n, 0);
}
int
gf_string2int8 (const char *str, int8_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT8_MIN && l <= INT8_MAX)
- {
- *n = (int8_t) l;
- return 0;
- }
+ if ((l >= INT8_MIN) && (l <= INT8_MAX)) {
+ *n = (int8_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2int16 (const char *str, int16_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT16_MIN && l <= INT16_MAX)
- {
- *n = (int16_t) l;
- return 0;
- }
+ if ((l >= INT16_MIN) && (l <= INT16_MAX)) {
+ *n = (int16_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2int32 (const char *str, int32_t *n)
{
- long l = 0L;
- int rv = 0;
+ long l = 0L;
+ int rv = 0;
- rv = _gf_string2long (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2long (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT32_MIN && l <= INT32_MAX)
- {
- *n = (int32_t) l;
- return 0;
- }
+ if ((l >= INT32_MIN) && (l <= INT32_MAX)) {
+ *n = (int32_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2int64 (const char *str, int64_t *n)
{
- long long l = 0LL;
- int rv = 0;
+ long long l = 0LL;
+ int rv = 0;
- rv = _gf_string2longlong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2longlong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= INT64_MIN && l <= INT64_MAX)
- {
- *n = (int64_t) l;
- return 0;
- }
+ if ((l >= INT64_MIN) && (l <= INT64_MAX)) {
+ *n = (int64_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint8 (const char *str, uint8_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT8_MAX)
- {
- *n = (uint8_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT8_MAX) {
+ *n = (uint8_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint16 (const char *str, uint16_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT16_MAX)
- {
- *n = (uint16_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT16_MAX) {
+ *n = (uint16_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint32 (const char *str, uint32_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT32_MAX)
- {
- *n = (uint32_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT32_MAX) {
+ *n = (uint32_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint64 (const char *str, uint64_t *n)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ unsigned long long l = 0ULL;
+ int rv = 0;
- rv = _gf_string2ulonglong (str, &l, 0);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulonglong (str, &l, 0);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT64_MAX)
- {
- *n = (uint64_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT64_MAX) {
+ *n = (uint64_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2ulong_base10 (const char *str, unsigned long *n)
{
- return _gf_string2ulong (str, n, 10);
+ return _gf_string2ulong (str, n, 10);
}
int
gf_string2uint_base10 (const char *str, unsigned int *n)
{
- return _gf_string2uint (str, n, 10);
+ return _gf_string2uint (str, n, 10);
}
int
gf_string2uint8_base10 (const char *str, uint8_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT8_MAX)
- {
- *n = (uint8_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT8_MAX) {
+ *n = (uint8_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint16_base10 (const char *str, uint16_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT16_MAX)
- {
- *n = (uint16_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT16_MAX) {
+ *n = (uint16_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint32_base10 (const char *str, uint32_t *n)
{
- unsigned long l = 0L;
- int rv = 0;
+ unsigned long l = 0L;
+ int rv = 0;
- rv = _gf_string2ulong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT32_MAX)
- {
- *n = (uint32_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT32_MAX) {
+ *n = (uint32_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
}
int
gf_string2uint64_base10 (const char *str, uint64_t *n)
{
- unsigned long long l = 0ULL;
- int rv = 0;
+ unsigned long long l = 0ULL;
+ int rv = 0;
- rv = _gf_string2ulonglong (str, &l, 10);
- if (rv != 0)
- return rv;
+ rv = _gf_string2ulonglong (str, &l, 10);
+ if (rv != 0)
+ return rv;
- if (l >= 0 && l <= UINT64_MAX)
- {
- *n = (uint64_t) l;
- return 0;
- }
+ if (l >= 0 && l <= UINT64_MAX) {
+ *n = (uint64_t) l;
+ return 0;
+ }
- errno = ERANGE;
- return -1;
+ errno = ERANGE;
+ return -1;
+}
+
+char *
+gf_uint64_2human_readable (uint64_t n)
+{
+ int ret = 0;
+ char *str = NULL;
+
+ if (n >= GF_UNIT_PB) {
+ ret = gf_asprintf (&str, "%.1lfPB", ((double) n)/GF_UNIT_PB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_TB) {
+ ret = gf_asprintf (&str, "%.1lfTB", ((double) n)/GF_UNIT_TB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_GB) {
+ ret = gf_asprintf (&str, "%.1lfGB", ((double) n)/GF_UNIT_GB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_MB) {
+ ret = gf_asprintf (&str, "%.1lfMB", ((double) n)/GF_UNIT_MB);
+ if (ret < 0)
+ goto err;
+ } else if (n >= GF_UNIT_KB) {
+ ret = gf_asprintf (&str, "%.1lfKB", ((double) n)/GF_UNIT_KB);
+ if (ret < 0)
+ goto err;
+ } else {
+ ret = gf_asprintf (&str, "%luBytes", n);
+ if (ret < 0)
+ goto err;
+ }
+ return str;
+err:
+ return NULL;
}
int
gf_string2bytesize (const char *str, uint64_t *n)
{
- uint64_t value = 0ULL;
- char *tail = NULL;
- int old_errno = 0;
- const char *s = NULL;
+ double value = 0.0;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
- if (str == NULL || n == NULL)
- {
- errno = EINVAL;
- return -1;
- }
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
- for (s = str; *s != '\0'; s++)
- {
- if (isspace (*s))
- {
- continue;
- }
- if (*s == '-')
- {
- /* bala: we do not support suffixed (-) sign and
- invalid integer format */
- return -1;
- }
- break;
- }
+ old_errno = errno;
+ errno = 0;
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
- old_errno = errno;
- errno = 0;
- value = strtoull (str, &tail, 10);
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
- if (errno == ERANGE || errno == EINVAL)
- {
- return -1;
- }
+ if (errno == 0)
+ errno = old_errno;
- if (errno == 0)
- {
- errno = old_errno;
- }
+ if (tail[0] != '\0')
+ {
+ if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
+ value *= GF_UNIT_KB;
+ else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
+ value *= GF_UNIT_MB;
+ else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
+ value *= GF_UNIT_GB;
+ else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
+ value *= GF_UNIT_TB;
+ else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
+ value *= GF_UNIT_PB;
+ else
+ return -1;
+ }
- if (tail[0] != '\0')
- {
- if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
- {
- value *= GF_UNIT_KB;
- }
- else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
- {
- value *= GF_UNIT_MB;
- }
- else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
- {
- value *= GF_UNIT_GB;
- }
- else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
- {
- value *= GF_UNIT_TB;
- }
- else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
- {
- value *= GF_UNIT_PB;
- }
- else
- {
- /* bala: invalid integer format */
- return -1;
- }
- }
+ if ((UINT64_MAX - value) < 0) {
+ errno = ERANGE;
+ return -1;
+ }
- *n = value;
+ *n = (uint64_t) value;
- return 0;
+ return 0;
+}
+
+int
+gf_string2percent_or_bytesize (const char *str,
+ uint64_t *n,
+ gf_boolean_t *is_percent)
+{
+ double value = 0ULL;
+ char *tail = NULL;
+ int old_errno = 0;
+ const char *s = NULL;
+
+ if (str == NULL || n == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING,
+ "argument invalid");
+ errno = EINVAL;
+ return -1;
+ }
+
+ for (s = str; *s != '\0'; s++) {
+ if (isspace (*s))
+ continue;
+ if (*s == '-')
+ return -1;
+ break;
+ }
+
+ old_errno = errno;
+ errno = 0;
+ value = strtod (str, &tail);
+ if (str == tail)
+ errno = EINVAL;
+
+ if (errno == ERANGE || errno == EINVAL)
+ return -1;
+
+ if (errno == 0)
+ errno = old_errno;
+
+ if (tail[0] != '\0') {
+ if (strcasecmp (tail, GF_UNIT_KB_STRING) == 0)
+ value *= GF_UNIT_KB;
+ else if (strcasecmp (tail, GF_UNIT_MB_STRING) == 0)
+ value *= GF_UNIT_MB;
+ else if (strcasecmp (tail, GF_UNIT_GB_STRING) == 0)
+ value *= GF_UNIT_GB;
+ else if (strcasecmp (tail, GF_UNIT_TB_STRING) == 0)
+ value *= GF_UNIT_TB;
+ else if (strcasecmp (tail, GF_UNIT_PB_STRING) == 0)
+ value *= GF_UNIT_PB;
+ else if (strcasecmp (tail, GF_UNIT_PERCENT_STRING) == 0)
+ *is_percent = _gf_true;
+ else
+ return -1;
+ }
+
+ /* 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;
}
int64_t
gf_str_to_long_long (const char *number)
{
- int64_t unit = 1;
- int64_t ret = 0;
- char *endptr = NULL ;
- if (!number)
- return 0;
-
- ret = strtoll (number, &endptr, 0);
-
- if (endptr) {
- switch (*endptr) {
- case 'G':
- case 'g':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024 * 1024 * 1024;
- break;
- case 'M':
- case 'm':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024 * 1024;
- break;
- case 'K':
- case 'k':
- if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
- unit = 1024;
- break;
- case '%':
- unit = 1;
- break;
- default:
- unit = 1;
- break;
- }
- }
- return ret * unit;
+ int64_t unit = 1;
+ int64_t ret = 0;
+ char *endptr = NULL ;
+ if (!number)
+ return 0;
+
+ ret = strtoll (number, &endptr, 0);
+
+ if (endptr) {
+ switch (*endptr) {
+ case 'G':
+ case 'g':
+ if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
+ unit = 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ case 'm':
+ if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
+ unit = 1024 * 1024;
+ break;
+ case 'K':
+ case 'k':
+ if ((* (endptr + 1) == 'B') ||(* (endptr + 1) == 'b'))
+ unit = 1024;
+ break;
+ case '%':
+ unit = 1;
+ break;
+ default:
+ unit = 1;
+ break;
+ }
+ }
+ return ret * unit;
}
int
gf_string2boolean (const char *str, gf_boolean_t *b)
{
- if (str == NULL) {
- return -1;
- }
+ if (str == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ return -1;
+ }
- if ((strcasecmp (str, "1") == 0) ||
- (strcasecmp (str, "on") == 0) ||
- (strcasecmp (str, "yes") == 0) ||
- (strcasecmp (str, "true") == 0) ||
- (strcasecmp (str, "enable") == 0)) {
- *b = _gf_true;
- return 0;
- }
+ if ((strcasecmp (str, "1") == 0) ||
+ (strcasecmp (str, "on") == 0) ||
+ (strcasecmp (str, "yes") == 0) ||
+ (strcasecmp (str, "true") == 0) ||
+ (strcasecmp (str, "enable") == 0)) {
+ *b = _gf_true;
+ return 0;
+ }
- if ((strcasecmp (str, "0") == 0) ||
- (strcasecmp (str, "off") == 0) ||
- (strcasecmp (str, "no") == 0) ||
- (strcasecmp (str, "false") == 0) ||
- (strcasecmp (str, "disable") == 0)) {
- *b = _gf_false;
- return 0;
- }
+ if ((strcasecmp (str, "0") == 0) ||
+ (strcasecmp (str, "off") == 0) ||
+ (strcasecmp (str, "no") == 0) ||
+ (strcasecmp (str, "false") == 0) ||
+ (strcasecmp (str, "disable") == 0)) {
+ *b = _gf_false;
+ return 0;
+ }
- return -1;
+ return -1;
}
int
gf_lockfd (int fd)
{
- struct gf_flock fl;
+ struct gf_flock fl;
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- return fcntl (fd, F_SETLK, &fl);
+ return fcntl (fd, F_SETLK, &fl);
}
int
gf_unlockfd (int fd)
{
- struct gf_flock fl;
+ struct gf_flock fl;
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
- return fcntl (fd, F_SETLK, &fl);
+ return fcntl (fd, F_SETLK, &fl);
}
static void
@@ -1469,65 +1665,6 @@ get_checksum_for_file (int fd, uint32_t *checksum)
}
-/* One should pass the command here with command with full path,
- otherwise, execv will fail */
-int
-gf_system (const char *command)
-{
- int ret = -1;
- pid_t pid = 0;
- int status = 0;
- int idx = 0;
- char *dupcmd = NULL;
- char *arg = NULL;
- char *tmp = NULL;
- char *argv[100] = { NULL, };
-
- dupcmd = gf_strdup (command);
- if (!dupcmd)
- goto out;
-
- pid = fork ();
- if (pid < 0) {
- /* failure */
- goto out;
- }
- if (pid == 0) {
- /* Child process */
- /* Step 0: Prepare the argv */
- arg = strtok_r (dupcmd, " ", &tmp);
- while (arg) {
- argv[idx] = arg;
- arg = strtok_r (NULL, " ", &tmp);
- idx++;
- }
- /* Step 1: Close all 'fd' */
- for (idx = 3; idx < 65536; idx++) {
- close (idx);
- }
- /* Step 2: execv (); */
- ret = execvp (argv[0], argv);
-
- /* Code will not come here at all */
- gf_log ("", GF_LOG_ERROR, "execv of (%s) failed", command);
-
- kill (getpid(), SIGKILL);
- }
- if (pid > 0) {
- /* Current, ie, parent process */
- pid = waitpid (pid, &status, 0);
- if (WIFEXITED(status) && WEXITSTATUS(status) == EXIT_SUCCESS)
- ret = 0;
- else
- ret = -1;
- }
-out:
- if (dupcmd)
- GF_FREE (dupcmd);
-
- return ret;
-}
-
int
get_checksum_for_path (char *path, uint32_t *checksum)
{
@@ -1540,7 +1677,7 @@ get_checksum_for_path (char *path, uint32_t *checksum)
fd = open (path, O_RDWR);
if (fd == -1) {
- gf_log ("", GF_LOG_ERROR, "Unable to open %s, errno: %d",
+ gf_log (THIS->name, GF_LOG_ERROR, "Unable to open %s, errno: %d",
path, errno);
goto out;
}
@@ -1566,3 +1703,1206 @@ strtail (char *str, const char *pattern)
return NULL;
}
+
+void
+skipwhite (char **s)
+{
+ while (isspace (**s))
+ (*s)++;
+}
+
+char *
+nwstrtail (char *str, char *pattern)
+{
+ for (;;) {
+ skipwhite (&str);
+ skipwhite (&pattern);
+
+ if (*str != *pattern || !*str)
+ break;
+
+ str++;
+ pattern++;
+ }
+
+ return *pattern ? NULL : str;
+}
+
+void
+skipword (char **s)
+{
+ if (!*s)
+ return;
+
+ skipwhite (s);
+
+ while (!isspace(**s))
+ (*s)++;
+}
+
+char *
+get_nth_word (const char *str, int n)
+{
+ char buf[4096] = {0};
+ char *start = NULL;
+ char *word = NULL;
+ int i = 0;
+ int word_len = 0;
+ const char *end = NULL;
+
+ if (!str)
+ goto out;
+
+ snprintf (buf, sizeof (buf), "%s", str);
+ start = buf;
+
+ for (i = 0; i < n-1; i++)
+ skipword (&start);
+
+ skipwhite (&start);
+ end = strpbrk ((const char *)start, " \t\n\0");
+
+ if (!end)
+ goto out;
+
+ word_len = abs (end - start);
+
+ word = GF_CALLOC (1, word_len + 1, gf_common_mt_strdup);
+ if (!word)
+ goto out;
+
+ strncpy (word, start, word_len);
+ *(word + word_len) = '\0';
+ out:
+ return word;
+}
+
+/* Syntax formed according to RFC 1912 (RFC 1123 & 952 are more restrictive) *
+ <hname> ::= <gen-name>*["."<gen-name>] *
+ <gen-name> ::= <let-or-digit> <[*[<let-or-digit-or-hyphen>]<let-or-digit>] */
+char
+valid_host_name (char *address, int length)
+{
+ int i = 0;
+ int str_len = 0;
+ char ret = 1;
+ char *dup_addr = NULL;
+ char *temp_str = NULL;
+ char *save_ptr = NULL;
+
+ if ((length > _POSIX_HOST_NAME_MAX) || (length < 1)) {
+ ret = 0;
+ goto out;
+ }
+
+ dup_addr = gf_strdup (address);
+ if (!dup_addr) {
+ ret = 0;
+ 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 {
+ str_len = strlen (temp_str);
+
+ if (!isalnum (temp_str[0]) ||
+ !isalnum (temp_str[str_len-1])) {
+ ret = 0;
+ goto out;
+ }
+ for (i = 1; i < str_len; i++) {
+ if (!isalnum (temp_str[i]) && (temp_str[i] != '-')) {
+ ret = 0;
+ goto out;
+ }
+ }
+ } while ((temp_str = strtok_r (NULL, ".", &save_ptr)));
+
+out:
+ GF_FREE (dup_addr);
+ return ret;
+}
+
+/* Matches all ipv4 address, if wildcard_acc is true '*' wildcard pattern for*
+ subnets is considerd as valid strings as well */
+char
+valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc)
+{
+ int octets = 0;
+ int value = 0;
+ char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
+ char ret = 1;
+ int is_wildcard = 0;
+
+ tmp = gf_strdup (address);
+
+ /*
+ * 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;
+ }
+
+ prev = tmp;
+ prev = strtok_r (tmp, ".", &ptr);
+
+ while (prev != NULL) {
+ octets++;
+ if (wildcard_acc && !strcmp (prev, "*")) {
+ is_wildcard = 1;
+ } else {
+ value = strtol (prev, &endptr, 10);
+ if ((value > 255) || (value < 0) ||
+ (endptr != NULL && *endptr != '\0')) {
+ ret = 0;
+ goto out;
+ }
+ }
+ prev = strtok_r (NULL, ".", &ptr);
+ }
+
+ if ((octets > 4) || (octets < 4 && !is_wildcard)) {
+ ret = 0;
+ }
+
+out:
+ GF_FREE (tmp);
+ return ret;
+}
+
+char
+valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc)
+{
+ int hex_numbers = 0;
+ int value = 0;
+ int i = 0;
+ char *tmp = NULL, *ptr = NULL, *prev = NULL, *endptr = NULL;
+ char ret = 1;
+ int is_wildcard = 0;
+ int is_compressed = 0;
+
+ tmp = gf_strdup (address);
+
+ /* Check for compressed form */
+ if (length <= 0 || tmp[length - 1] == ':') {
+ ret = 0;
+ goto out;
+ }
+ for (i = 0; i < (length - 1) ; i++) {
+ if (tmp[i] == ':' && tmp[i + 1] == ':') {
+ if (is_compressed == 0)
+ is_compressed = 1;
+ else {
+ ret = 0;
+ goto out;
+ }
+ }
+ }
+
+ prev = strtok_r (tmp, ":", &ptr);
+
+ while (prev != NULL) {
+ hex_numbers++;
+ if (wildcard_acc && !strcmp (prev, "*")) {
+ is_wildcard = 1;
+ } else {
+ value = strtol (prev, &endptr, 16);
+ if ((value > 0xffff) || (value < 0)
+ || (endptr != NULL && *endptr != '\0')) {
+ ret = 0;
+ goto out;
+ }
+ }
+ prev = strtok_r (NULL, ":", &ptr);
+ }
+
+ if ((hex_numbers > 8) || (hex_numbers < 8 && !is_wildcard
+ && !is_compressed)) {
+ ret = 0;
+ }
+
+out:
+ GF_FREE (tmp);
+ return ret;
+}
+
+char
+valid_internet_address (char *address, gf_boolean_t wildcard_acc)
+{
+ char ret = 0;
+ int length = 0;
+
+ if (address == NULL) {
+ gf_log_callingfn (THIS->name, GF_LOG_WARNING, "argument invalid");
+ goto out;
+ }
+
+ length = strlen (address);
+ if (length == 0)
+ goto out;
+
+ if (valid_ipv4_address (address, length, wildcard_acc)
+ || valid_ipv6_address (address, length, wildcard_acc)
+ || valid_host_name (address, length))
+ ret = 1;
+
+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)
+{
+ char *uuid_buffer = glusterfs_uuid_buf_get(THIS->ctx);
+ uuid_unparse (uuid, uuid_buffer);
+ return uuid_buffer;
+}
+
+/*Re-entrant conversion function*/
+char *
+uuid_utoa_r (uuid_t uuid, char *dst)
+{
+ if(!dst)
+ return NULL;
+ uuid_unparse (uuid, dst);
+ return dst;
+}
+
+/*Thread safe conversion function*/
+char *
+lkowner_utoa (gf_lkowner_t *lkowner)
+{
+ char *lkowner_buffer = glusterfs_lkowner_buf_get(THIS->ctx);
+ lkowner_unparse (lkowner, lkowner_buffer, GF_LKOWNER_BUF_SIZE);
+ return lkowner_buffer;
+}
+
+/*Re-entrant conversion function*/
+char *
+lkowner_utoa_r (gf_lkowner_t *lkowner, char *dst, int len)
+{
+ if(!dst)
+ return NULL;
+ lkowner_unparse (lkowner, dst, len);
+ return dst;
+}
+
+void* gf_array_elem (void *a, int index, size_t elem_size)
+{
+ uint8_t* ptr = a;
+ return (void*)(ptr + index * elem_size);
+}
+
+void
+gf_elem_swap (void *x, void *y, size_t l) {
+ uint8_t *a = x, *b = y, c;
+ while(l--) {
+ c = *a;
+ *a++ = *b;
+ *b++ = c;
+ }
+}
+
+void
+gf_array_insertionsort (void *A, int l, int r, size_t elem_size,
+ gf_cmp cmp)
+{
+ int i = l;
+ int N = r+1;
+ void *Temp = NULL;
+ int j = 0;
+
+ for(i = l; i < N; i++) {
+ Temp = gf_array_elem (A, i, elem_size);
+ j = i - 1;
+ while((cmp (Temp, gf_array_elem (A, j, elem_size))
+ < 0) && j>=0) {
+ gf_elem_swap (Temp, gf_array_elem (A, j, elem_size),
+ elem_size);
+ Temp = gf_array_elem (A, j, elem_size);
+ j = j-1;
+ }
+ }
+}
+
+int
+gf_is_str_int (const char *value)
+{
+ int flag = 0;
+ char *str = NULL;
+ char *fptr = NULL;
+
+ GF_VALIDATE_OR_GOTO (THIS->name, value, out);
+
+ str = gf_strdup (value);
+ if (!str)
+ goto out;
+
+ fptr = str;
+
+ while (*str) {
+ if (!isdigit(*str)) {
+ flag = 1;
+ goto out;
+ }
+ str++;
+ }
+
+out:
+ GF_FREE (fptr);
+
+ return flag;
+}
+/*
+ * rounds up nr to power of two. If nr is already a power of two, just returns
+ * nr
+ */
+
+inline int32_t
+gf_roundup_power_of_two (int32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_log ("common-utils", GF_LOG_WARNING,
+ "negative number passed");
+ result = -1;
+ goto out;
+ }
+
+ while (result < nr)
+ result *= 2;
+
+out:
+ return result;
+}
+
+/*
+ * rounds up nr to next power of two. If nr is already a power of two, next
+ * power of two is returned.
+ */
+
+inline int32_t
+gf_roundup_next_power_of_two (int32_t nr)
+{
+ int32_t result = 1;
+
+ if (nr < 0) {
+ gf_log ("common-utils", GF_LOG_WARNING,
+ "negative number passed");
+ result = -1;
+ goto out;
+ }
+
+ while (result <= nr)
+ result *= 2;
+
+out:
+ return result;
+}
+
+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;
+}
+
+void
+gf_path_strip_trailing_slashes (char *path)
+{
+ int i = 0;
+ int len = 0;
+
+ if (!path)
+ return;
+
+ len = strlen (path);
+ for (i = len - 1; i > 0; i--) {
+ if (path[i] != '/')
+ break;
+ }
+
+ if (i < (len -1))
+ path [i+1] = '\0';
+
+ return;
+}
+
+uint64_t
+get_mem_size ()
+{
+ uint64_t memsize = -1;
+
+#if defined GF_LINUX_HOST_OS || defined GF_SOLARIS_HOST_OS
+
+ uint64_t page_size = 0;
+ uint64_t num_pages = 0;
+
+ page_size = sysconf (_SC_PAGESIZE);
+ num_pages = sysconf (_SC_PHYS_PAGES);
+
+ memsize = page_size * num_pages;
+#endif
+
+#if defined GF_BSD_HOST_OS || defined GF_DARWIN_HOST_OS
+
+ size_t len = sizeof(memsize);
+ int name [] = { CTL_HW, HW_PHYSMEM };
+
+ sysctl (name, 2, &memsize, &len, NULL, 0);
+#endif
+ return memsize;
+}
+
+/* Strips all whitespace characters in a string and returns length of new string
+ * on success
+ */
+int
+gf_strip_whitespace (char *str, int len)
+{
+ int i = 0;
+ int new_len = 0;
+ char *new_str = NULL;
+
+ GF_ASSERT (str);
+
+ new_str = GF_CALLOC (1, len + 1, gf_common_mt_char);
+ if (new_str == NULL)
+ return -1;
+
+ for (i = 0; i < len; i++) {
+ if (!isspace (str[i]))
+ new_str[new_len++] = str[i];
+ }
+ new_str[new_len] = '\0';
+
+ if (new_len != len) {
+ memset (str, 0, len);
+ strncpy (str, new_str, new_len);
+ }
+
+ GF_FREE (new_str);
+ return new_len;
+}
+
+int
+gf_canonicalize_path (char *path)
+{
+ int ret = -1;
+ int path_len = 0;
+ int dir_path_len = 0;
+ char *tmppath = NULL;
+ char *dir = NULL;
+ char *tmpstr = NULL;
+
+ if (!path || *path != '/')
+ goto out;
+
+ tmppath = gf_strdup (path);
+ if (!tmppath)
+ goto out;
+
+ /* Strip the extra slashes and return */
+ bzero (path, strlen(path));
+ path[0] = '/';
+ dir = strtok_r(tmppath, "/", &tmpstr);
+
+ while (dir) {
+ dir_path_len = strlen(dir);
+ strncpy ((path + path_len + 1), dir, dir_path_len);
+ path_len += dir_path_len + 1;
+ dir = strtok_r (NULL, "/", &tmpstr);
+ if (dir)
+ strncpy ((path + path_len), "/", 1);
+ }
+ path[path_len] = '\0';
+ ret = 0;
+
+ out:
+ if (ret)
+ gf_log ("common-utils", GF_LOG_ERROR,
+ "Path manipulation failed");
+
+ GF_FREE(tmppath);
+
+ return ret;
+}
+
+static const char *__gf_timefmts[] = {
+ "%F %T",
+ "%Y/%m/%d-%T",
+ "%b %d %T",
+ "%F %H%M%S"
+};
+
+static const char *__gf_zerotimes[] = {
+ "0000-00-00 00:00:00",
+ "0000/00/00-00:00:00",
+ "xxx 00 00:00:00",
+ "0000-00-00 000000"
+};
+
+void
+_gf_timestuff (gf_timefmts *fmt, const char ***fmts, const char ***zeros)
+{
+ *fmt = gf_timefmt_last;
+ *fmts = __gf_timefmts;
+ *zeros = __gf_zerotimes;
+}
+
+
+char *
+generate_glusterfs_ctx_id (void)
+{
+ char tmp_str[1024] = {0,};
+ char hostname[256] = {0,};
+ struct timeval tv = {0,};
+ char now_str[32];
+
+ if (gettimeofday (&tv, NULL) == -1) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "gettimeofday: failed %s",
+ strerror (errno));
+ }
+
+ if (gethostname (hostname, 256) == -1) {
+ gf_log ("glusterfsd", GF_LOG_ERROR,
+ "gethostname: failed %s",
+ strerror (errno));
+ }
+
+ gf_time_fmt (now_str, sizeof now_str, tv.tv_sec, gf_timefmt_Ymd_T);
+ snprintf (tmp_str, sizeof tmp_str, "%s-%d-%s:%"
+#ifdef GF_DARWIN_HOST_OS
+ PRId32,
+#else
+ "ld",
+#endif
+ hostname, getpid(), now_str, tv.tv_usec);
+
+ return gf_strdup (tmp_str);
+}
+
+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,};
+ int32_t ret = -1;
+
+ proc_fd = open (proc_file, O_RDONLY);
+ if (proc_fd == -1) {
+ /* What should be done in this case? error out from here
+ * and thus stop the glusterfs process from starting or
+ * continue with older method of using any of the available
+ * port? For now 2nd option is considered.
+ */
+ gf_log ("glusterfs", GF_LOG_WARNING, "could not open "
+ "the file /proc/sys/net/ipv4/ip_local_reserved_ports "
+ "for getting reserved ports info (%s)",
+ strerror (errno));
+ goto out;
+ }
+
+ ret = read (proc_fd, buffer, sizeof (buffer));
+ if (ret < 0) {
+ gf_log ("glusterfs", GF_LOG_WARNING, "could not "
+ "read the file %s for getting reserved ports "
+ "info (%s)", proc_file, strerror (errno));
+ goto out;
+ }
+ ports_info = gf_strdup (buffer);
+
+out:
+ if (proc_fd != -1)
+ close (proc_fd);
+#endif /* GF_LINUX_HOST_OS */
+ return ports_info;
+}
+
+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;
+
+ ports_info = gf_get_reserved_ports ();
+ if (!ports_info) {
+ gf_log ("glusterfs", GF_LOG_WARNING, "Not able to get reserved "
+ "ports, hence there is a possibility that glusterfs "
+ "may consume reserved port");
+ goto out;
+ }
+
+ blocked_port = strtok_r (ports_info, ",\n",&tmp);
+
+ while (blocked_port) {
+ gf_ports_reserved (blocked_port, ports);
+ blocked_port = strtok_r (NULL, ",\n", &tmp);
+ }
+
+ ret = 0;
+
+out:
+ GF_FREE (ports_info);
+#endif /* GF_LINUX_HOST_OS */
+ return ret;
+}
+
+gf_boolean_t
+gf_ports_reserved (char *blocked_port, gf_boolean_t *ports)
+{
+ gf_boolean_t result = _gf_false;
+ char *range_port = NULL;
+ int16_t tmp_port1, tmp_port2 = -1;
+
+ if (strstr (blocked_port, "-") == NULL) {
+ /* get rid of the new line character*/
+ if (blocked_port[strlen(blocked_port) -1] == '\n')
+ blocked_port[strlen(blocked_port) -1] = '\0';
+ if (gf_string2int16 (blocked_port, &tmp_port1) == 0) {
+ if (tmp_port1 > (GF_CLIENT_PORT_CEILING - 1)
+ || tmp_port1 < 0) {
+ gf_log ("glusterfs-socket", GF_LOG_WARNING,
+ "invalid port %d", tmp_port1);
+ result = _gf_true;
+ goto out;
+ } else {
+ gf_log ("glusterfs", GF_LOG_DEBUG,
+ "blocking port %d", tmp_port1);
+ ports[tmp_port1] = _gf_true;
+ }
+ } else {
+ gf_log ("glusterfs-socket", GF_LOG_WARNING, "%s is "
+ "not a valid port identifier", blocked_port);
+ result = _gf_true;
+ goto out;
+ }
+ } else {
+ range_port = strtok (blocked_port, "-");
+ if (!range_port){
+ result = _gf_true;
+ goto out;
+ }
+ if (gf_string2int16 (range_port, &tmp_port1) == 0) {
+ if (tmp_port1 > (GF_CLIENT_PORT_CEILING - 1))
+ tmp_port1 = GF_CLIENT_PORT_CEILING - 1;
+ if (tmp_port1 < 0)
+ tmp_port1 = 0;
+ }
+ range_port = strtok (NULL, "-");
+ if (!range_port) {
+ result = _gf_true;
+ goto out;
+ }
+ /* get rid of the new line character*/
+ if (range_port[strlen(range_port) -1] == '\n')
+ range_port[strlen(range_port) - 1] = '\0';
+ if (gf_string2int16 (range_port, &tmp_port2) == 0) {
+ if (tmp_port2 >
+ (GF_CLIENT_PORT_CEILING - 1))
+ tmp_port2 = GF_CLIENT_PORT_CEILING - 1;
+ if (tmp_port2 < 0)
+ tmp_port2 = 0;
+ }
+ gf_log ("glusterfs", GF_LOG_DEBUG, "lower: %d, higher: %d",
+ tmp_port1, tmp_port2);
+ for (; tmp_port1 <= tmp_port2; tmp_port1++)
+ ports[tmp_port1] = _gf_true;
+ }
+
+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;
+}