diff options
Diffstat (limited to 'libglusterfs/src/common-utils.c')
| -rw-r--r-- | libglusterfs/src/common-utils.c | 721 |
1 files changed, 445 insertions, 276 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 63cbf13388f..682cbf28055 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -24,7 +24,6 @@ #include <time.h> #include <locale.h> #include <sys/socket.h> -#include <sys/wait.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> @@ -35,25 +34,26 @@ #if defined(GF_BSD_HOST_OS) || defined(GF_DARWIN_HOST_OS) #include <sys/sysctl.h> #endif -#include <libgen.h> #ifndef GF_LINUX_HOST_OS #include <sys/resource.h> #endif +#ifdef HAVE_SYNCFS_SYS +#include <sys/syscall.h> +#endif -#include "compat-errno.h" -#include "logging.h" -#include "common-utils.h" -#include "revision.h" -#include "glusterfs.h" -#include "stack.h" -#include "lkowner.h" -#include "syscall.h" -#include "cli1-xdr.h" +#include "glusterfs/compat-errno.h" +#include "glusterfs/common-utils.h" +#include "glusterfs/revision.h" +#include "glusterfs/glusterfs.h" +#include "glusterfs/stack.h" +#include "glusterfs/lkowner.h" +#include "glusterfs/syscall.h" +#include "glusterfs/globals.h" #define XXH_INLINE_ALL #include "xxhash.h" #include <ifaddrs.h> -#include "libglusterfs-messages.h" -#include "protocol-common.h" +#include "glusterfs/libglusterfs-messages.h" +#include "glusterfs/glusterfs-acl.h" #ifdef __FreeBSD__ #include <pthread_np.h> #undef BIT_SET @@ -65,20 +65,29 @@ char *vol_type_str[] = { "Distribute", - "Stripe", + "Stripe [NOT SUPPORTED from v6.0]", "Replicate", - "Striped-Replicate", + "Striped-Replicate [NOT SUPPORTED from v6.0]", "Disperse", - "Tier", - "Distributed-Stripe", + "Tier [NOT SUPPORTED from v6.0]", + "Distributed-Stripe [NOT SUPPORTED from v6.0]", "Distributed-Replicate", - "Distributed-Striped-Replicate", + "Distributed-Striped-Replicate [NOT SUPPORTED from v6.0]", "Distributed-Disperse", }; 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); +char *xattrs_to_heal[] = {"user.", + POSIX_ACL_ACCESS_XATTR, + POSIX_ACL_DEFAULT_XATTR, + QUOTA_LIMIT_KEY, + QUOTA_LIMIT_OBJECTS_KEY, + GF_SELINUX_XATTR_KEY, + GF_XATTR_MDATA_KEY, + NULL}; + void gf_xxh64_wrapper(const unsigned char *data, size_t const len, unsigned long long const seed, char *xxh64) @@ -306,8 +315,7 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) dir[i] = '\0'; ret = sys_mkdir(dir, mode); if (ret && errno != EEXIST) { - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, - "Failed due to reason"); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, NULL); goto out; } @@ -318,10 +326,8 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) if (S_ISLNK(stbuf.st_mode)) { ret = -1; - gf_msg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, - "%s is a " - "symlink", - dir); + gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_DIR_IS_SYMLINK, "dir=%s", + dir, NULL); goto out; } } @@ -334,10 +340,10 @@ mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks) if (ret == 0) errno = 0; ret = -1; - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, - "Failed" - " to create directory, possibly some of the components" - " were not directories"); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_DIR_OP_FAILED, + "possibly some of the components" + " were not directories", + NULL); goto out; } @@ -410,10 +416,8 @@ gf_rev_dns_lookup(const char *ip) /* Get the FQDN */ ret = gf_get_hostname_from_ip((char *)ip, &fqdn); if (ret != 0) { - gf_msg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, - "could not resolve " - "hostname for %s", - ip); + gf_smsg("resolver", GF_LOG_INFO, errno, LG_MSG_RESOLVE_HOSTNAME_FAILED, + "hostname=%s", ip, NULL); } out: return fqdn; @@ -434,7 +438,7 @@ gf_resolve_path_parent(const char *path) GF_VALIDATE_OR_GOTO(THIS->name, path, out); - if (strlen(path) <= 0) { + if (0 == strlen(path)) { gf_msg_callingfn(THIS->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_STRING, "invalid string for 'path'"); goto out; @@ -502,10 +506,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, } if ((ret = getaddrinfo(hostname, port_str, &hints, &cache->first)) != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, - "getaddrinfo failed" - " (%s)", - gai_strerror(ret)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, + "family=%d", family, "ret=%s", gai_strerror(ret), NULL); GF_FREE(*dnscache); *dnscache = NULL; @@ -522,10 +524,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, cache->next->ai_addrlen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST); if (ret != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "getnameinfo failed" - " (%s)", - gai_strerror(ret)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto err; } @@ -544,10 +544,8 @@ gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, cache->next->ai_addrlen, host, sizeof(host), service, sizeof(service), NI_NUMERICHOST); if (ret != 0) { - gf_msg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "getnameinfo failed" - " (%s)", - gai_strerror(ret)); + gf_smsg("resolver", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto err; } @@ -579,8 +577,14 @@ struct dnscache * gf_dnscache_init(time_t ttl) { struct dnscache *cache = GF_MALLOC(sizeof(*cache), gf_common_mt_dnscache); - if (cache) { - cache->cache_dict = NULL; + if (!cache) + return NULL; + + cache->cache_dict = dict_new(); + if (!cache->cache_dict) { + GF_FREE(cache); + cache = NULL; + } else { cache->ttl = ttl; } @@ -588,6 +592,20 @@ gf_dnscache_init(time_t ttl) } /** + * gf_dnscache_deinit -- cleanup resources used by struct dnscache + */ +void +gf_dnscache_deinit(struct dnscache *cache) +{ + if (!cache) { + gf_msg_plain(GF_LOG_WARNING, "dnscache is NULL"); + return; + } + dict_unref(cache->cache_dict); + GF_FREE(cache); +} + +/** * gf_dnscache_entry_init -- Initialize a dnscache entry * * @return: SUCCESS: Pointer to an allocated dnscache entry struct @@ -635,12 +653,6 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) if (!dnscache) goto out; - if (!dnscache->cache_dict) { - dnscache->cache_dict = dict_new(); - if (!dnscache->cache_dict) { - goto out; - } - } cache = dnscache->cache_dict; /* Quick cache lookup to see if we already hold it */ @@ -648,7 +660,7 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) if (entrydata) { dnsentry = (struct dnscache_entry *)entrydata->data; /* First check the TTL & timestamp */ - if (time(NULL) - dnsentry->timestamp > dnscache->ttl) { + if (gf_time() - dnsentry->timestamp > dnscache->ttl) { gf_dnscache_entry_deinit(dnsentry); entrydata->data = NULL; /* Mark this as 'null' so * dict_del () doesn't try free @@ -679,23 +691,16 @@ gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache) from_cache = _gf_false; out: /* Insert into the cache */ - if (fqdn && !from_cache) { + if (fqdn && !from_cache && ip) { struct dnscache_entry *entry = gf_dnscache_entry_init(); - if (!entry) { - goto out; - } - entry->fqdn = fqdn; - if (!ip) { - gf_dnscache_entry_deinit(entry); - goto out; + if (entry) { + entry->fqdn = fqdn; + entry->ip = gf_strdup(ip); + entry->timestamp = gf_time(); + entrydata = bin_to_data(entry, sizeof(*entry)); + dict_set(cache, (char *)ip, entrydata); } - - entry->ip = gf_strdup(ip); - entry->timestamp = time(NULL); - - entrydata = bin_to_data(entry, sizeof(*entry)); - dict_set(cache, (char *)ip, entrydata); } return fqdn; } @@ -904,7 +909,7 @@ gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx) char msg[1024] = { 0, }; - char timestr[64] = { + char timestr[GF_TIMESTR_SIZE] = { 0, }; call_stack_t *stack = NULL; @@ -944,7 +949,7 @@ gf_print_trace(int32_t signum, glusterfs_ctx_t *ctx) { /* Dump the timestamp of the crash too, so the previous logs can be related */ - gf_time_fmt(timestr, sizeof timestr, time(NULL), gf_timefmt_FT); + gf_time_fmt(timestr, sizeof timestr, gf_time(), gf_timefmt_FT); gf_msg_plain_nomem(GF_LOG_ALERT, "time of crash: "); gf_msg_plain_nomem(GF_LOG_ALERT, timestr); } @@ -1702,7 +1707,7 @@ gf_uint64_2human_readable(uint64_t n) if (ret < 0) goto err; } else { - ret = gf_asprintf(&str, "%luBytes", n); + ret = gf_asprintf(&str, "%" PRIu64 "Bytes", n); if (ret < 0) goto err; } @@ -1946,6 +1951,74 @@ gf_string2boolean(const char *str, gf_boolean_t *b) } int +gf_strn2boolean(const char *str, const int len, gf_boolean_t *b) +{ + if (str == NULL) { + gf_msg_callingfn(THIS->name, GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, + "argument invalid"); + return -1; + } + + switch (len) { + case 1: + if (strcasecmp(str, "1") == 0) { + *b = _gf_true; + return 0; + } else if (strcasecmp(str, "0") == 0) { + *b = _gf_false; + return 0; + } + break; + case 2: + if (strcasecmp(str, "on") == 0) { + *b = _gf_true; + return 0; + } else if (strcasecmp(str, "no") == 0) { + *b = _gf_false; + return 0; + } + break; + case 3: + if (strcasecmp(str, "yes") == 0) { + *b = _gf_true; + return 0; + } else if (strcasecmp(str, "off") == 0) { + *b = _gf_false; + return 0; + } + break; + case 4: + if (strcasecmp(str, "true") == 0) { + *b = _gf_true; + return 0; + } + break; + case 5: + if (strcasecmp(str, "false") == 0) { + *b = _gf_false; + return 0; + } + break; + case 6: + if (strcasecmp(str, "enable") == 0) { + *b = _gf_true; + return 0; + } + break; + case 7: + if (strcasecmp(str, "disable") == 0) { + *b = _gf_false; + return 0; + } + break; + default: + return -1; + break; + } + return -1; +} + +int gf_lockfd(int fd) { struct gf_flock fl; @@ -1972,7 +2045,7 @@ gf_unlockfd(int fd) } static void -compute_checksum(char *buf, size_t size, uint32_t *checksum) +compute_checksum(char *buf, const ssize_t size, uint32_t *checksum) { int ret = -1; char *checksum_buf = NULL; @@ -2003,7 +2076,7 @@ compute_checksum(char *buf, size_t size, uint32_t *checksum) #define GF_CHECKSUM_BUF_SIZE 1024 int -get_checksum_for_file(int fd, uint32_t *checksum) +get_checksum_for_file(int fd, uint32_t *checksum, int op_version) { int ret = -1; char buf[GF_CHECKSUM_BUF_SIZE] = { @@ -2014,8 +2087,12 @@ get_checksum_for_file(int fd, uint32_t *checksum) sys_lseek(fd, 0L, SEEK_SET); do { ret = sys_read(fd, &buf, GF_CHECKSUM_BUF_SIZE); - if (ret > 0) - compute_checksum(buf, GF_CHECKSUM_BUF_SIZE, checksum); + if (ret > 0) { + if (op_version < GD_OP_VERSION_5_4) + compute_checksum(buf, GF_CHECKSUM_BUF_SIZE, checksum); + else + compute_checksum(buf, ret, checksum); + } } while (ret > 0); /* set it back */ @@ -2025,7 +2102,7 @@ get_checksum_for_file(int fd, uint32_t *checksum) } int -get_checksum_for_path(char *path, uint32_t *checksum) +get_checksum_for_path(char *path, uint32_t *checksum, int op_version) { int ret = -1; int fd = -1; @@ -2036,12 +2113,12 @@ get_checksum_for_path(char *path, uint32_t *checksum) fd = open(path, O_RDWR); if (fd == -1) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_ERROR, - "Unable to open %s", path); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_PATH_OPEN_FAILED, + "path=%s", path, NULL); goto out; } - ret = get_checksum_for_file(fd, checksum); + ret = get_checksum_for_file(fd, checksum, op_version); out: if (fd != -1) @@ -2070,8 +2147,8 @@ get_file_mtime(const char *path, time_t *stamp) ret = sys_stat(path, &f_stat); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, - "failed to stat %s", path); + gf_smsg(THIS->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, + "path=%s", path, NULL); goto out; } @@ -2090,7 +2167,7 @@ out: * @ip_str : The IP to check * @network: The network to check the IP against. * - * @return: success: 0 + * @return: success: _gf_true * failure: -EINVAL for bad args, retval of inet_pton otherwise */ gf_boolean_t @@ -2130,14 +2207,14 @@ gf_is_ip_in_net(const char *network, const char *ip_str) /* Convert IP address to a long */ ret = inet_pton(family, ip_str, &ip_buf); if (ret < 0) - gf_msg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, - "inet_pton() failed"); + gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, + NULL); /* Convert network IP address to a long */ ret = inet_pton(family, net_ip, &net_ip_buf); if (ret < 0) { - gf_msg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, - "inet_pton() failed"); + gf_smsg("common-utils", GF_LOG_ERROR, errno, LG_MSG_INET_PTON_FAILED, + NULL); goto out; } @@ -2281,7 +2358,7 @@ next_token(char **tokenp, token_iter_t *tit) * #include <stdio.h> * #include <stdlib.h> * #include <string.h> - * #include "common-utils.h" + * #include "glusterfs/common-utils.h" * * int * main (int argc, char **argv) @@ -2457,6 +2534,31 @@ out: return ret; } +char +valid_cidr_address(char *cidr_address, gf_boolean_t wildcard_acc) +{ + unsigned int net_mask = 0, len = 0; + char *temp = NULL, *cidr_str = NULL, ret = 1; + + cidr_str = strdupa(cidr_address); + temp = strstr(cidr_str, "/"); + if (temp == NULL) + return 0; /* Since Invalid cidr ip address we return 0 */ + + *temp = '\0'; + temp++; + net_mask = (unsigned int)atoi(temp); + + if (net_mask > 32 || net_mask < 1) + return 0; /* Since Invalid cidr ip address we return 0*/ + + len = strlen(cidr_str); + + ret = valid_ipv4_address(cidr_str, len, wildcard_acc); + + return ret; +} + /** * valid_ipv4_subnetwork() takes the pattern and checks if it contains * a valid ipv4 subnetwork pattern i.e. xx.xx.xx.xx/n. IPv4 address @@ -2593,7 +2695,8 @@ out: } char -valid_internet_address(char *address, gf_boolean_t wildcard_acc) +valid_internet_address(char *address, gf_boolean_t wildcard_acc, + gf_boolean_t cidr) { char ret = 0; int length = 0; @@ -2608,6 +2711,10 @@ valid_internet_address(char *address, gf_boolean_t wildcard_acc) if (length == 0) goto out; + if (cidr && valid_cidr_address(address, wildcard_acc)) { + ret = 1; + } + if (valid_ipv4_address(address, length, wildcard_acc) || valid_ipv6_address(address, length, wildcard_acc) || valid_host_name(address, length)) @@ -2687,8 +2794,8 @@ gf_boolean_t gf_sock_union_equal_addr(union gf_sock_union *a, union gf_sock_union *b) { if (!a || !b) { - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Invalid arguments to gf_sock_union_equal_addr"); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, + "gf_sock_union_equal_addr", NULL); return _gf_false; } @@ -2916,8 +3023,8 @@ gf_roundup_power_of_two(int32_t nr) int32_t result = 1; if (nr < 0) { - gf_msg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, - "negative number passed"); + gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, + NULL); result = -1; goto out; } @@ -2940,8 +3047,8 @@ gf_roundup_next_power_of_two(int32_t nr) int32_t result = 1; if (nr < 0) { - gf_msg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, - "negative number passed"); + gf_smsg("common-utils", GF_LOG_WARNING, 0, LG_MSG_NEGATIVE_NUM_PASSED, + NULL); result = -1; goto out; } @@ -2954,16 +3061,6 @@ out: } int -get_vol_type(int type, int dist_count, int brick_count) -{ - if ((type != GF_CLUSTER_TYPE_TIER) && (type > 0) && - (dist_count < brick_count)) - type = type + GF_CLUSTER_TYPE_MAX - 1; - - return type; -} - -int validate_brick_name(char *brick) { char *delimiter = NULL; @@ -3036,7 +3133,7 @@ get_mem_size() memsize = page_size * num_pages; #endif -#if defined GF_DARWIN_HOST_OS +#if defined GF_DARWIN_HOST_OS || defined __FreeBSD__ size_t len = sizeof(memsize); int name[] = {CTL_HW, HW_PHYSMEM}; @@ -3125,8 +3222,7 @@ gf_canonicalize_path(char *path) out: if (ret) - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, - "Path manipulation failed"); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_PATH_ERROR, NULL); GF_FREE(tmppath); @@ -3180,19 +3276,15 @@ gf_get_reserved_ports() * continue with older method of using any of the available * port? For now 2nd option is considered. */ - gf_msg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, - "could not open the file " - "/proc/sys/net/ipv4/ip_local_reserved_ports for " - "getting reserved ports info"); + gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, + " /proc/sys/net/ipv4/ip_local_reserved_ports", NULL); goto out; } ret = sys_read(proc_fd, buffer, sizeof(buffer) - 1); if (ret < 0) { - gf_msg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, - "could not read the file %s for" - " getting reserved ports info", - proc_file); + gf_smsg("glusterfs", GF_LOG_WARNING, errno, LG_MSG_FILE_OP_FAILED, + "file=%s", proc_file, NULL); goto out; } @@ -3220,10 +3312,8 @@ gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling) ports_info = gf_get_reserved_ports(); if (!ports_info) { - gf_msg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR, - "Not able to get reserved" - " ports, hence there is a possibility that glusterfs " - "may consume reserved port"); + gf_smsg("glusterfs", GF_LOG_WARNING, 0, LG_MSG_RESERVED_PORTS_ERROR, + NULL); goto out; } @@ -3259,9 +3349,9 @@ gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling) if (blocked_port[strlen(blocked_port) - 1] == '\n') blocked_port[strlen(blocked_port) - 1] = '\0'; if (gf_string2int32(blocked_port, &tmp_port1) == 0) { - if (tmp_port1 > ceiling || tmp_port1 < 0) { - gf_msg("glusterfs-socket", GF_LOG_WARNING, 0, - LG_MSG_INVALID_PORT, "invalid port %d", tmp_port1); + if (tmp_port1 > GF_PORT_MAX || tmp_port1 < 0) { + gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, + LG_MSG_INVALID_PORT, "port=%d", tmp_port1, NULL); result = _gf_true; goto out; } else { @@ -3272,10 +3362,8 @@ gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling) BIT_SET(ports, tmp_port1); } } else { - gf_msg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT, - "%s is not a valid port " - "identifier", - blocked_port); + gf_smsg("glusterfs-socket", GF_LOG_WARNING, 0, LG_MSG_INVALID_PORT, + "port=%s", blocked_port, NULL); result = _gf_true; goto out; } @@ -3377,10 +3465,8 @@ gf_get_hostname_from_ip(char *client_ip, char **hostname) ret = getnameinfo(client_sockaddr, addr_sz, client_hostname, sizeof(client_hostname), NULL, 0, 0); if (ret) { - gf_msg("common-utils", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "Could not lookup hostname " - "of %s : %s", - client_ip, gai_strerror(ret)); + gf_smsg("common-utils", GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ip=%s", client_ip, "ret=%s", gai_strerror(ret), NULL); ret = -1; goto out; } @@ -3409,8 +3495,8 @@ gf_interface_search(char *ip) ret = getifaddrs(&ifaddr); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, - "getifaddrs() failed: %s\n", gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETIFADDRS_FAILED, "ret=%s", + gai_strerror(ret), NULL); goto out; } @@ -3434,10 +3520,8 @@ gf_interface_search(char *ip) host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, - "getnameinfo() " - "failed: %s\n", - gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETNAMEINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto out; } @@ -3487,14 +3571,12 @@ get_ip_from_addrinfo(struct addrinfo *addr, char **ip) break; default: - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, - "Invalid family"); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, NULL); return NULL; } if (!inet_ntop(addr->ai_family, in_addr, buf, sizeof(buf))) { - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, - "String conversion failed"); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_CONVERSION_FAILED, NULL); return NULL; } @@ -3529,10 +3611,9 @@ gf_is_loopback_localhost(const struct sockaddr *sa, char *hostname) default: if (hostname) - gf_msg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, - "unknown " - "address family %d for %s", - sa->sa_family, hostname); + gf_smsg("glusterd", GF_LOG_ERROR, 0, LG_MSG_INVALID_FAMILY, + "family=%d", sa->sa_family, "hostname=%s", hostname, + NULL); break; } @@ -3562,23 +3643,27 @@ gf_is_local_addr(char *hostname) ret = getaddrinfo(hostname, NULL, &hints, &result); if (ret != 0) { - gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(ret)); + gf_smsg(this->name, GF_LOG_ERROR, 0, LG_MSG_GETADDRINFO_FAILED, + "ret=%s", gai_strerror(ret), NULL); goto out; } for (res = result; res != NULL; res = res->ai_next) { - gf_msg_debug(this->name, 0, "%s ", get_ip_from_addrinfo(res, &ip)); + get_ip_from_addrinfo(res, &ip); + gf_msg_debug(this->name, 0, "%s ", ip); if (ip) { - found = gf_is_loopback_localhost(res->ai_addr, hostname) || - gf_interface_search(ip); + found = (gf_is_loopback_localhost(res->ai_addr, hostname) || + gf_interface_search(ip)); } if (found) { GF_FREE(ip); goto out; } GF_FREE(ip); + /* the above free will not set ip to NULL, and hence, there is + double free possible as the loop continues. set ip to NULL. */ + ip = NULL; } out: @@ -3607,15 +3692,15 @@ gf_is_same_address(char *name1, char *name2) gai_err = getaddrinfo(name1, NULL, &hints, &addr1); if (gai_err != 0) { - gf_msg(name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(gai_err)); + gf_smsg(name1, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s", + gai_strerror(gai_err), NULL); goto out; } gai_err = getaddrinfo(name2, NULL, &hints, &addr2); if (gai_err != 0) { - gf_msg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, - "error in getaddrinfo: %s\n", gai_strerror(gai_err)); + gf_smsg(name2, GF_LOG_WARNING, 0, LG_MSG_GETADDRINFO_FAILED, "error=%s", + gai_strerror(gai_err), NULL); goto out; } @@ -3752,8 +3837,10 @@ gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host, if ((!strcmp(tmp->volfile_server, server->volfile_server) && !strcmp(tmp->transport, server->transport) && (tmp->port == server->port))) { - errno = EEXIST; - ret = -1; + /* Duplicate option given, log and ignore */ + gf_smsg("gluster", GF_LOG_INFO, EEXIST, LG_MSG_DUPLICATE_ENTRY, + NULL); + ret = 0; goto out; } } @@ -3916,19 +4003,63 @@ error_return: return ret; } +void +gf_thread_set_vname(pthread_t thread, const char *name, va_list args) +{ + char thread_name[GF_THREAD_NAME_LIMIT]; + int ret; + + /* Initialize the thread name with the prefix (not NULL terminated). */ + memcpy(thread_name, GF_THREAD_NAME_PREFIX, + sizeof(GF_THREAD_NAME_PREFIX) - 1); + + ret = vsnprintf(thread_name + sizeof(GF_THREAD_NAME_PREFIX) - 1, + sizeof(thread_name) - sizeof(GF_THREAD_NAME_PREFIX) + 1, + name, args); + if (ret < 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, + "name=%s", name, NULL); + return; + } + + if (ret >= sizeof(thread_name)) { + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_THREAD_NAME_TOO_LONG, + "name=%s", thread_name, NULL); + } + +#ifdef GF_LINUX_HOST_OS + ret = pthread_setname_np(thread, thread_name); +#elif defined(__NetBSD__) + ret = pthread_setname_np(thread, thread_name, NULL); +#elif defined(__FreeBSD__) + pthread_set_name_np(thread, thread_name); + ret = 0; +#else + ret = ENOSYS; +#endif + if (ret != 0) { + gf_smsg(THIS->name, GF_LOG_WARNING, ret, LG_MSG_SET_THREAD_FAILED, + "name=%s", thread_name, NULL); + } +} + +void +gf_thread_set_name(pthread_t thread, const char *name, ...) +{ + va_list args; + + va_start(args, name); + gf_thread_set_vname(thread, name, args); + va_end(args); +} + int -gf_thread_create(pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine)(void *), void *arg, const char *name) +gf_thread_vcreate(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, const char *name, + va_list args) { sigset_t set, old; int ret; - char thread_name[GF_THREAD_NAMEMAX + GF_THREAD_NAME_PREFIX_LEN] = { - 0, - }; - /* Max name on Linux is 16 and on NetBSD is 32 - * All Gluster threads have a set prefix of gluster and hence the limit - * of 9 on GF_THREAD_NAMEMAX including the null character. - */ sigemptyset(&old); sigfillset(&set); @@ -3942,20 +4073,12 @@ gf_thread_create(pthread_t *thread, const pthread_attr_t *attr, pthread_sigmask(SIG_BLOCK, &set, &old); ret = pthread_create(thread, attr, start_routine, arg); - snprintf(thread_name, sizeof(thread_name), "%s%s", GF_THREAD_NAME_PREFIX, - name); - - if (0 == ret && name) { -#ifdef GF_LINUX_HOST_OS - pthread_setname_np(*thread, thread_name); -#elif defined(__NetBSD__) - pthread_setname_np(*thread, thread_name, NULL); -#elif defined(__FreeBSD__) - pthread_set_name_np(*thread, thread_name); -#else - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_PTHREAD_NAMING_FAILED, - "Could not set thread name: %s", thread_name); -#endif + if (ret != 0) { + gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_THREAD_CREATE_FAILED, + NULL); + ret = -1; + } else if (name != NULL) { + gf_thread_set_vname(*thread, name, args); } pthread_sigmask(SIG_SETMASK, &old, NULL); @@ -3964,27 +4087,40 @@ gf_thread_create(pthread_t *thread, const pthread_attr_t *attr, } int +gf_thread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, const char *name, + ...) +{ + va_list args; + int ret; + + va_start(args, name); + ret = gf_thread_vcreate(thread, attr, start_routine, arg, name, args); + va_end(args); + + return ret; +} + +int gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *), - void *arg, const char *name) + void *arg, const char *name, ...) { pthread_attr_t attr; + va_list args; int ret = -1; ret = pthread_attr_init(&attr); if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED, - "Thread attribute initialization failed"); + gf_smsg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_ATTR_INIT_FAILED, + NULL); return -1; } pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - ret = gf_thread_create(thread, &attr, start_routine, arg, name); - if (ret) { - gf_msg(THIS->name, GF_LOG_ERROR, ret, LG_MSG_PTHREAD_FAILED, - "Thread creation failed"); - ret = -1; - } + va_start(args, name); + ret = gf_thread_vcreate(thread, &attr, start_routine, arg, name, args); + va_end(args); pthread_attr_destroy(&attr); @@ -3998,8 +4134,7 @@ gf_skip_header_section(int fd, int header_len) ret = sys_lseek(fd, header_len, SEEK_SET); if (ret == (off_t)-1) { - gf_msg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, - "Failed to skip header section"); + gf_smsg("", GF_LOG_ERROR, 0, LG_MSG_SKIP_HEADER_FAILED, NULL); } else { ret = 0; } @@ -4012,6 +4147,14 @@ gf_skip_header_section(int fd, int header_len) gf_boolean_t gf_is_pid_running(int pid) { +#ifdef __FreeBSD__ + int ret = -1; + + ret = sys_kill(pid, 0); + if (ret < 0) { + return _gf_false; + } +#else char fname[32] = { 0, }; @@ -4025,6 +4168,7 @@ gf_is_pid_running(int pid) } sys_close(fd); +#endif return _gf_true; } @@ -4045,14 +4189,15 @@ gf_is_service_running(char *pidfile, int *pid) ret = lockf(fno, F_TEST, 0); if (ret == -1) { running = _gf_true; - goto out; } ret = fscanf(file, "%d", pid); if (ret <= 0) { - gf_msg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, - "Unable to read pidfile: %s", pidfile); + gf_smsg("", GF_LOG_ERROR, errno, LG_MSG_FILE_OP_FAILED, "pidfile=%s", + pidfile, NULL); *pid = -1; + running = _gf_false; + goto out; } running = gf_is_pid_running(*pid); @@ -4123,10 +4268,10 @@ gf_check_log_format(const char *value) log_format = gf_logformat_withmsgid; if (log_format == -1) - gf_msg( - THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, - "Invalid log-format. possible values are " GF_LOG_FORMAT_NO_MSG_ID - "|" GF_LOG_FORMAT_WITH_MSG_ID); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, + "possible_values=" GF_LOG_FORMAT_NO_MSG_ID + "|" GF_LOG_FORMAT_WITH_MSG_ID, + NULL); return log_format; } @@ -4142,9 +4287,9 @@ gf_check_logger(const char *value) logger = gf_logger_syslog; if (logger == -1) - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, - "Invalid logger. possible values are " GF_LOGGER_GLUSTER_LOG - "|" GF_LOGGER_SYSLOG); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_LOG, + "possible_values=" GF_LOGGER_GLUSTER_LOG "|" GF_LOGGER_SYSLOG, + NULL); return logger; } @@ -4216,8 +4361,8 @@ gf_set_timestamp(const char *src, const char *dest) ret = sys_stat(src, &sb); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, - "stat on %s", src); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_FILE_STAT_FAILED, + "stat=%s", src, NULL); goto out; } /* The granularity is nano seconds if `utimensat()` is available, @@ -4233,8 +4378,8 @@ gf_set_timestamp(const char *src, const char *dest) /* dirfd = 0 is ignored because `dest` is an absolute path. */ ret = sys_utimensat(AT_FDCWD, dest, new_time, AT_SYMLINK_NOFOLLOW); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED, - "utimensat on %s", dest); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMENSAT_FAILED, + "dest=%s", dest, NULL); } #else new_time[0].tv_sec = sb.st_atime; @@ -4245,8 +4390,8 @@ gf_set_timestamp(const char *src, const char *dest) ret = sys_utimes(dest, new_time); if (ret) { - gf_msg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED, - "utimes on %s", dest); + gf_smsg(this->name, GF_LOG_ERROR, errno, LG_MSG_UTIMES_FAILED, + "dest=%s", dest, NULL); } #endif out: @@ -4265,7 +4410,7 @@ gf_backtrace_end(char *buf, size_t frames) frames = min(frames, GF_BACKTRACE_LEN - pos - 1); - if (frames <= 0) + if (0 == frames) return; memset(buf + pos, ')', frames); @@ -4311,8 +4456,8 @@ gf_backtrace_fillframes(char *buf) */ ret = sys_unlink(tmpl); if (ret < 0) { - gf_msg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_OP_FAILED, - "Unable to delete temporary file: %s", tmpl); + gf_smsg(THIS->name, GF_LOG_INFO, 0, LG_MSG_FILE_DELETE_FAILED, + "temporary_file=%s", tmpl, NULL); } /*The most recent two frames are the calling function and @@ -4372,8 +4517,7 @@ gf_backtrace_save(char *buf) if ((0 == gf_backtrace_fillframes(bt))) return bt; - gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, - "Failed to save the backtrace."); + gf_smsg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_BACKTRACE_SAVE_FAILED, NULL); return NULL; } @@ -4411,9 +4555,13 @@ fop_log_level(glusterfs_fop_t fop, int op_errno) return GF_LOG_DEBUG; if (fop == GF_FOP_SEEK) { +#ifdef HAVE_SEEK_HOLE if (op_errno == ENXIO) { return GF_LOG_DEBUG; } +#else + return GF_LOG_DEBUG; +#endif } return GF_LOG_ERROR; @@ -4460,16 +4608,16 @@ gf_build_absolute_path(char *current_path, char *relative_path, char **path) */ currentpath_len = strlen(current_path); if (current_path[0] != '/' || (currentpath_len > PATH_MAX)) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Wrong value for current path %s", current_path); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE, + "current-path=%s", current_path, NULL); ret = -EINVAL; goto err; } relativepath_len = strlen(relative_path); if (relative_path[0] == '/' || (relativepath_len > PATH_MAX)) { - gf_msg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, - "Wrong value for relative path %s", relative_path); + gf_smsg(THIS->name, GF_LOG_ERROR, 0, LG_MSG_WRONG_VALUE, + "relative-path=%s", relative_path, NULL); ret = -EINVAL; goto err; } @@ -4585,8 +4733,9 @@ recursive_rmdir(const char *delete_path) goto out; } - GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scratch); - while (entry) { + while ((entry = sys_readdir(dir, scratch))) { + if (gf_irrelevant_entry(entry)) + continue; snprintf(path, PATH_MAX, "%s/%s", delete_path, entry->d_name); ret = sys_lstat(path, &st); if (ret == -1) { @@ -4612,8 +4761,6 @@ recursive_rmdir(const char *delete_path) gf_msg_debug(this->name, 0, "%s %s", ret ? "Failed to remove" : "Removed", entry->d_name); - - GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scratch); } ret = sys_closedir(dir); @@ -4937,8 +5084,8 @@ gf_zero_fill_stat(struct iatt *buf) gf_boolean_t gf_is_valid_xattr_namespace(char *key) { - static char *xattr_namespaces[] = {"trusted.", "security.", "system.", - "user.", NULL}; + static char *xattr_namespaces[] = {"trusted.", "system.", "user.", + "security.", NULL}; int i = 0; for (i = 0; xattr_namespaces[i]; i++) { @@ -5161,62 +5308,6 @@ glusterfs_compute_sha256(const unsigned char *content, size_t size, return 0; } -char * -get_struct_variable(int mem_num, gf_gsync_status_t *sts_val) -{ - switch (mem_num) { - case 0: - return (sts_val->node); - case 1: - return (sts_val->master); - case 2: - return (sts_val->brick); - case 3: - return (sts_val->slave_user); - case 4: - return (sts_val->slave); - case 5: - return (sts_val->slave_node); - case 6: - return (sts_val->worker_status); - case 7: - return (sts_val->crawl_status); - case 8: - return (sts_val->last_synced); - case 9: - return (sts_val->entry); - case 10: - return (sts_val->data); - case 11: - return (sts_val->meta); - case 12: - return (sts_val->failures); - case 13: - return (sts_val->checkpoint_time); - case 14: - return (sts_val->checkpoint_completed); - case 15: - return (sts_val->checkpoint_completion_time); - case 16: - return (sts_val->brick_host_uuid); - case 17: - return (sts_val->last_synced_utc); - case 18: - return (sts_val->checkpoint_time_utc); - case 19: - return (sts_val->checkpoint_completion_time_utc); - case 20: - return (sts_val->slavekey); - case 21: - return (sts_val->session_slave); - default: - goto out; - } - -out: - return NULL; -} - /* * Safe wrapper function for strncpy. * This wrapper makes sure that when there is no null byte among the first n in * source srting for strncpy function call, the string placed in dest will be @@ -5294,3 +5385,81 @@ gf_replace_new_iatt_in_dict(dict_t *xdata) return ret; } + +xlator_cmdline_option_t * +find_xlator_option_in_cmd_args_t(const char *option_name, cmd_args_t *args) +{ + xlator_cmdline_option_t *pos = NULL; + xlator_cmdline_option_t *tmp = NULL; + + list_for_each_entry_safe(pos, tmp, &args->xlator_options, cmd_args) + { + if (strcmp(pos->key, option_name) == 0) + return pos; + } + return NULL; +} + +int +gf_d_type_from_ia_type(ia_type_t type) +{ + switch (type) { + case IA_IFDIR: + return DT_DIR; + case IA_IFCHR: + return DT_CHR; + case IA_IFBLK: + return DT_BLK; + case IA_IFIFO: + return DT_FIFO; + case IA_IFLNK: + return DT_LNK; + case IA_IFREG: + return DT_REG; + case IA_IFSOCK: + return DT_SOCK; + default: + return DT_UNKNOWN; + } +} + +int +gf_nanosleep(uint64_t nsec) +{ + struct timespec req; + struct timespec rem; + int ret = -1; + + req.tv_sec = nsec / GF_SEC_IN_NS; + req.tv_nsec = nsec % GF_SEC_IN_NS; + + do { + ret = nanosleep(&req, &rem); + req = rem; + } while (ret == -1 && errno == EINTR); + + return ret; +} + +int +gf_syncfs(int fd) +{ + int ret = 0; +#if defined(HAVE_SYNCFS) + /* Linux with glibc recent enough. */ + ret = syncfs(fd); +#elif defined(HAVE_SYNCFS_SYS) + /* Linux with no library function. */ + ret = syscall(SYS_syncfs, fd); +#else + /* Fallback to generic UNIX stuff. */ + sync(); +#endif + return ret; +} + +char ** +get_xattrs_to_heal() +{ + return xattrs_to_heal; +} |
