diff options
Diffstat (limited to 'libglusterfs/src/glusterfs/common-utils.h')
-rw-r--r-- | libglusterfs/src/glusterfs/common-utils.h | 1070 |
1 files changed, 1070 insertions, 0 deletions
diff --git a/libglusterfs/src/glusterfs/common-utils.h b/libglusterfs/src/glusterfs/common-utils.h new file mode 100644 index 00000000000..075a355f786 --- /dev/null +++ b/libglusterfs/src/glusterfs/common-utils.h @@ -0,0 +1,1070 @@ +/* + Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + 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 _COMMON_UTILS_H +#define _COMMON_UTILS_H + +#include <stdint.h> +#include <sys/uio.h> +#include <netdb.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <pthread.h> +#include <openssl/md5.h> +#ifndef GF_BSD_HOST_OS +#include <alloca.h> +#endif +#include <limits.h> +#include <fnmatch.h> +#include <uuid/uuid.h> + +#ifndef ffsll +#define ffsll(x) __builtin_ffsll(x) +#endif + +void +trap(void); + +#define GF_UNIVERSAL_ANSWER 42 /* :O */ + +/* To solve type punned error */ +#define VOID(ptr) ((void **)((void *)ptr)) + +#include "glusterfs/logging.h" +#include "glusterfs/glusterfs.h" +#include "glusterfs/locking.h" +#include "glusterfs/mem-pool.h" +#include "glusterfs/compat-uuid.h" +#include "glusterfs/iatt.h" +#include "glusterfs/libglusterfs-messages.h" +#include "protocol-common.h" +#include "glusterfs/iobuf.h" + +#define STRINGIFY(val) #val +#define TOSTRING(val) STRINGIFY(val) + +#define alloca0(size) \ + ({ \ + void *__ptr; \ + __ptr = alloca(size); \ + memset(__ptr, 0, size); \ + __ptr; \ + }) + +#define min(a, b) ((a) < (b) ? (a) : (b)) +#define max(a, b) ((a) > (b) ? (a) : (b)) +#define gf_roof(a, b) ((((a) + (b)-1) / ((b != 0) ? (b) : 1)) * (b)) +#define gf_floor(a, b) (((a) / ((b != 0) ? (b) : 1)) * (b)) + +#define IPv4_ADDR_SIZE 32 + +#define GF_UNIT_KB 1024ULL +#define GF_UNIT_MB 1048576ULL +#define GF_UNIT_GB 1073741824ULL +#define GF_UNIT_TB 1099511627776ULL +#define GF_UNIT_PB 1125899906842624ULL + +#define GF_UNIT_B_STRING "B" +#define GF_UNIT_KB_STRING "KB" +#define GF_UNIT_MB_STRING "MB" +#define GF_UNIT_GB_STRING "GB" +#define GF_UNIT_TB_STRING "TB" +#define GF_UNIT_PB_STRING "PB" + +#define GF_UNIT_PERCENT_STRING "%" + +#define GEOREP "geo-replication" +#define GHADOOP "glusterfs-hadoop" +#define GLUSTERD_NAME "glusterd" + +#define GF_SELINUX_XATTR_KEY "security.selinux" + +#define WIPE(statp) \ + do { \ + typeof(*statp) z = { \ + 0, \ + }; \ + if (statp) \ + *statp = z; \ + } while (0) + +#define IS_EXT_FS(fs_name) \ + (!strcmp(fs_name, "ext2") || !strcmp(fs_name, "ext3") || \ + !strcmp(fs_name, "ext4")) + +/* process mode definitions */ +#define GF_SERVER_PROCESS 0 +#define GF_CLIENT_PROCESS 1 +#define GF_GLUSTERD_PROCESS 2 + +/* Defining this here as it is needed by glusterd for setting + * nfs port in volume status. + */ +#define GF_NFS3_PORT 2049 + +#define GF_CLIENT_PORT_CEILING 1024 +#define GF_IANA_PRIV_PORTS_START 49152 /* RFC 6335 */ +#define GF_CLNT_INSECURE_PORT_CEILING (GF_IANA_PRIV_PORTS_START - 1) +#define GF_PORT_MAX 65535 +#define GF_PORT_ARRAY_SIZE ((GF_PORT_MAX + 7) / 8) +#define GF_LOCK_TIMER 180 +#define GF_MINUTE_IN_SECONDS 60 +#define GF_HOUR_IN_SECONDS (60 * 60) +#define GF_DAY_IN_SECONDS (24 * 60 * 60) +#define GF_WEEK_IN_SECONDS (7 * 24 * 60 * 60) + +/* Default timeout for both barrier and changelog translator */ +#define BARRIER_TIMEOUT "120" + +/* Default value of signing waiting time to sign a file for bitrot */ +#define SIGNING_TIMEOUT "120" + +/* xxhash */ +#define GF_XXH64_DIGEST_LENGTH 8 +#define GF_XXHSUM64_DEFAULT_SEED 0 + +/* Shard */ +#define GF_XATTR_SHARD_FILE_SIZE "trusted.glusterfs.shard.file-size" +#define SHARD_ROOT_GFID "be318638-e8a0-4c6d-977d-7a937aa84806" +#define DOT_SHARD_REMOVE_ME_GFID "77dd5a45-dbf5-4592-b31b-b440382302e9" + +/* Lease: buffer length for stringified lease id + * Format: 4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum-4hexnum + * Eg:6c69-6431-2d63-6c6e-7431-0000-0000-0000 + */ +#define GF_LEASE_ID_BUF_SIZE ((LEASE_ID_SIZE * 2) + (LEASE_ID_SIZE / 2)) + +#define GF_PERCENTAGE(val, total) (((val)*100) / (total)) + +/* pthread related */ +/* as per the man page, thread-name should be at max 16 bytes */ +/* with prefix of 'glfs_' (5), we are left with 11 more bytes */ +#define GF_THREAD_NAMEMAX 11 +#define GF_THREAD_NAME_PREFIX "glfs_" +#define GF_THREAD_NAME_PREFIX_LEN 5 + +#include <stdbool.h> +#define gf_boolean_t bool +#define _gf_false false +#define _gf_true true + +/* + * we could have initialized these as +ve values and treated + * them as negative while comparing etc.. (which would have + * saved us with the pain of assigning values), but since we + * only have a few clients that use this feature, it's okay. + */ +enum _gf_special_pid { + GF_CLIENT_PID_MAX = 0, + GF_CLIENT_PID_GSYNCD = -1, + GF_CLIENT_PID_HADOOP = -2, + GF_CLIENT_PID_DEFRAG = -3, + GF_CLIENT_PID_NO_ROOT_SQUASH = -4, + GF_CLIENT_PID_QUOTA_MOUNT = -5, + GF_CLIENT_PID_SELF_HEALD = -6, + GF_CLIENT_PID_GLFS_HEAL = -7, + GF_CLIENT_PID_BITD = -8, + GF_CLIENT_PID_SCRUB = -9, + GF_CLIENT_PID_TIER_DEFRAG = -10, + GF_SERVER_PID_TRASH = -11 +}; + +enum _gf_xlator_ipc_targets { + GF_IPC_TARGET_CHANGELOG = 0, + GF_IPC_TARGET_CTR = 1, + GF_IPC_TARGET_UPCALL = 2 +}; + +typedef enum _gf_special_pid gf_special_pid_t; +typedef enum _gf_xlator_ipc_targets _gf_xlator_ipc_targets_t; + +/* The DHT file rename operation is not a straightforward rename. + * It involves creating linkto and linkfiles, and can unlink or rename the + * source file depending on the hashed and cached subvols for the source + * and target files. this makes it difficult for geo-rep to figure out that + * a rename operation has taken place. + * + * We now send a special key and the values of the source and target pargfids + * and basenames to indicate to changelog that the operation in question + * should be treated as a rename. We are explicitly filling and sending this + * as a binary value in the dictionary as the unlink op will not have the + * source file information. The lengths of the src and target basenames + * are used to calculate where to start reading the names in the structure. + * XFS allows a max of 255 chars for filenames but other file systems might + * not have such restrictions + */ +typedef struct dht_changelog_rename_info { + uuid_t old_pargfid; + uuid_t new_pargfid; + int32_t oldname_len; + int32_t newname_len; + char buffer[1]; +} dht_changelog_rename_info_t; + +typedef int (*gf_cmp)(void *, void *); + +struct _dict; + +struct dnscache { + struct _dict *cache_dict; + time_t ttl; +}; + +struct dnscache_entry { + char *ip; + char *fqdn; + time_t timestamp; +}; + +struct dnscache6 { + struct addrinfo *first; + struct addrinfo *next; +}; + +struct list_node { + void *ptr; + struct list_head list; +}; + +extern char *vol_type_str[]; + +struct list_node * +list_node_add(void *ptr, struct list_head *list); +struct list_node * +list_node_add_order(void *ptr, struct list_head *list, + int (*compare)(struct list_head *, struct list_head *)); +void +list_node_del(struct list_node *node); + +struct dnscache * +gf_dnscache_init(time_t ttl); +struct dnscache_entry * +gf_dnscache_entry_init(void); +void +gf_dnscache_entry_deinit(struct dnscache_entry *entry); +char * +gf_rev_dns_lookup_cached(const char *ip, struct dnscache *dnscache); + +char * +gf_resolve_path_parent(const char *path); + +void +gf_global_variable_init(void); + +int32_t +gf_resolve_ip6(const char *hostname, uint16_t port, int family, void **dnscache, + struct addrinfo **addr_info); + +void +gf_log_dump_graph(FILE *specfp, glusterfs_graph_t *graph); +void +gf_print_trace(int32_t signal, glusterfs_ctx_t *ctx); +int +gf_set_log_file_path(cmd_args_t *cmd_args, glusterfs_ctx_t *ctx); +int +gf_set_log_ident(cmd_args_t *cmd_args); + +int +gf_process_getspec_servers_list(cmd_args_t *cmd_args, const char *servers_list); +int +gf_set_volfile_server_common(cmd_args_t *cmd_args, const char *host, + const char *transport, int port); + +static inline void +BIT_SET(unsigned char *array, unsigned int index) +{ + unsigned int offset = index / 8; + unsigned int shift = index % 8; + + array[offset] |= (1 << shift); +} + +static inline void +BIT_CLEAR(unsigned char *array, unsigned int index) +{ + unsigned int offset = index / 8; + unsigned int shift = index % 8; + + array[offset] &= ~(1 << shift); +} + +static inline unsigned int +BIT_VALUE(unsigned char *array, unsigned int index) +{ + unsigned int offset = index / 8; + unsigned int shift = index % 8; + + return (array[offset] >> shift) & 0x1; +} + +#define VECTORSIZE(count) (count * (sizeof(struct iovec))) + +#define STRLEN_0(str) (strlen(str) + 1) + +#define VALIDATE_OR_GOTO(arg, label) \ + do { \ + if (!arg) { \ + errno = EINVAL; \ + gf_msg_callingfn((this ? (this->name) : "(Govinda! Govinda!)"), \ + GF_LOG_WARNING, EINVAL, LG_MSG_INVALID_ARG, \ + "invalid argument: " #arg); \ + goto label; \ + } \ + } while (0) + +#define GF_VALIDATE_OR_GOTO(name, arg, label) \ + do { \ + if (!arg) { \ + errno = EINVAL; \ + gf_msg_callingfn(name, GF_LOG_ERROR, errno, LG_MSG_INVALID_ARG, \ + "invalid argument: " #arg); \ + goto label; \ + } \ + } while (0) + +#define GF_VALIDATE_OR_GOTO_WITH_ERROR(name, arg, label, errno, error) \ + do { \ + if (!arg) { \ + errno = error; \ + gf_msg_callingfn(name, GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, \ + "invalid argument: " #arg); \ + goto label; \ + } \ + } while (0) + +#define GF_CHECK_ALLOC(arg, retval, label) \ + do { \ + if (!(arg)) { \ + retval = -ENOMEM; \ + goto label; \ + } \ + } while (0) + +#define GF_CHECK_ALLOC_AND_LOG(name, item, retval, msg, errlabel) \ + do { \ + if (!(item)) { \ + (retval) = -ENOMEM; \ + gf_msg(name, GF_LOG_CRITICAL, ENOMEM, LG_MSG_NO_MEMORY, (msg)); \ + goto errlabel; \ + } \ + } while (0) + +#define GF_ASSERT_AND_GOTO_WITH_ERROR(name, arg, label, errno, error) \ + do { \ + if (!arg) { \ + GF_ASSERT(0); \ + errno = error; \ + goto label; \ + } \ + } while (0) + +#define GF_VALIDATE_ABSOLUTE_PATH_OR_GOTO(name, arg, label) \ + do { \ + GF_VALIDATE_OR_GOTO(name, arg, label); \ + if ((arg[0]) != '/') { \ + errno = EINVAL; \ + gf_msg_callingfn(name, GF_LOG_ERROR, EINVAL, LG_MSG_INVALID_ARG, \ + "invalid argument: " #arg); \ + goto label; \ + } \ + } while (0) + +#define GF_REMOVE_SLASH_FROM_PATH(path, string) \ + do { \ + int i = 0; \ + for (i = 1; i < strlen(path); i++) { \ + string[i - 1] = path[i]; \ + if (string[i - 1] == '/') \ + string[i - 1] = '-'; \ + } \ + } while (0) + +#define GF_REMOVE_INTERNAL_XATTR(pattern, dict) \ + do { \ + if (!dict) { \ + gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_DICT_NULL, \ + "dict is null"); \ + break; \ + } \ + dict_foreach_fnmatch(dict, pattern, dict_remove_foreach_fn, NULL); \ + } while (0) + +#define GF_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \ + do { \ + if (!dict) { \ + gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_DICT_NULL, \ + "setxattr dict is null"); \ + goto label; \ + } \ + if (dict_foreach_fnmatch(dict, pattern, dict_null_foreach_fn, NULL) > \ + 0) { \ + op_errno = EPERM; \ + gf_msg(this->name, GF_LOG_ERROR, op_errno, LG_MSG_NO_PERM, \ + "attempt to set internal" \ + " xattr: %s", \ + pattern); \ + goto label; \ + } \ + } while (0) + +#define GF_IF_NATIVE_XATTR_GOTO(pattern, key, op_errno, label) \ + do { \ + if (!key) { \ + gf_msg(this->name, GF_LOG_ERROR, 0, LG_MSG_NO_KEY, \ + "no key for removexattr"); \ + goto label; \ + } \ + if (!fnmatch(pattern, key, 0)) { \ + op_errno = EPERM; \ + gf_msg(this->name, GF_LOG_ERROR, op_errno, LG_MSG_NO_PERM, \ + "attempt to remove internal " \ + "xattr: %s", \ + key); \ + goto label; \ + } \ + } while (0) + +#define GF_FILE_CONTENT_REQUESTED(_xattr_req, _content_limit) \ + (dict_get_uint64(_xattr_req, "glusterfs.content", _content_limit) == 0) + +#ifdef DEBUG +#define GF_ASSERT(x) assert(x); +#else +#define GF_ASSERT(x) \ + do { \ + if (!(x)) { \ + gf_msg_callingfn("", GF_LOG_ERROR, 0, LG_MSG_ASSERTION_FAILED, \ + "Assertion failed: " #x); \ + } \ + } while (0) +#endif + +#define GF_ABORT(msg) \ + do { \ + gf_msg_callingfn("", GF_LOG_CRITICAL, 0, LG_MSG_ASSERTION_FAILED, \ + "Assertion failed: " msg); \ + abort(); \ + } while (0) + +#define GF_UUID_ASSERT(u) \ + if (gf_uuid_is_null(u)) \ + GF_ASSERT(!"uuid null"); + +#define GF_IGNORE_IF_GSYNCD_SAFE_ERROR(frame, op_errno) \ + (((frame->root->pid == GF_CLIENT_PID_GSYNCD) && \ + (op_errno == EEXIST || op_errno == ENOENT)) \ + ? 0 \ + : 1) + +union gf_sock_union { + struct sockaddr_storage storage; + struct sockaddr_in6 sin6; + struct sockaddr_in sin; + struct sockaddr sa; +}; + +#define GF_HIDDEN_PATH ".glusterfs" +#define GF_UNLINK_PATH GF_HIDDEN_PATH "/unlink" +#define GF_LANDFILL_PATH GF_HIDDEN_PATH "/landfill" + +#define IOV_MIN(n) min(IOV_MAX, n) + +#define GF_SKIP_IRRELEVANT_ENTRIES(entry, dir, scr) \ + do { \ + entry = NULL; \ + if (dir) { \ + entry = sys_readdir(dir, scr); \ + while (entry && (!strcmp(entry->d_name, ".") || \ + !fnmatch("*.tmp", entry->d_name, 0) || \ + !strcmp(entry->d_name, ".."))) { \ + entry = sys_readdir(dir, scr); \ + } \ + } \ + } while (0) + +static inline void +iov_free(struct iovec *vector, int count) +{ + int i; + + for (i = 0; i < count; i++) + FREE(vector[i].iov_base); + + GF_FREE(vector); +} + +static inline int +iov_length(const struct iovec *vector, int count) +{ + int i = 0; + size_t size = 0; + + for (i = 0; i < count; i++) + size += vector[i].iov_len; + + return size; +} + +static inline struct iovec * +iov_dup(const struct iovec *vector, int count) +{ + int bytecount = 0; + int i; + struct iovec *newvec = NULL; + + bytecount = (count * sizeof(struct iovec)); + newvec = GF_MALLOC(bytecount, gf_common_mt_iovec); + if (!newvec) + return NULL; + + for (i = 0; i < count; i++) { + newvec[i].iov_len = vector[i].iov_len; + newvec[i].iov_base = vector[i].iov_base; + } + + return newvec; +} + +static inline int +iov_subset(struct iovec *orig, int orig_count, off_t src_offset, + off_t dst_offset, struct iovec *new) +{ + int new_count = 0; + int i; + off_t offset = 0; + size_t start_offset = 0; + size_t end_offset = 0, origin_iov_len = 0; + + for (i = 0; i < orig_count; i++) { + origin_iov_len = orig[i].iov_len; + + if ((offset + orig[i].iov_len < src_offset) || (offset > dst_offset)) { + goto not_subset; + } + + if (!new) { + goto count_only; + } + + start_offset = 0; + end_offset = orig[i].iov_len; + + if (src_offset >= offset) { + start_offset = (src_offset - offset); + } + + if (dst_offset <= (offset + orig[i].iov_len)) { + end_offset = (dst_offset - offset); + } + + new[new_count].iov_base = orig[i].iov_base + start_offset; + new[new_count].iov_len = end_offset - start_offset; + + count_only: + new_count++; + + not_subset: + offset += origin_iov_len; + } + + return new_count; +} + +static inline void +iov_unload(char *buf, const struct iovec *vector, int count) +{ + int i; + int copied = 0; + + for (i = 0; i < count; i++) { + memcpy(buf + copied, vector[i].iov_base, vector[i].iov_len); + copied += vector[i].iov_len; + } +} + +static inline size_t +iov_load(const struct iovec *vector, int count, char *buf, int size) +{ + size_t left = size; + size_t cp = 0; + int ret = 0; + int i = 0; + + while (left && i < count) { + cp = min(vector[i].iov_len, left); + if (vector[i].iov_base != buf + (size - left)) + memcpy(vector[i].iov_base, buf + (size - left), cp); + ret += cp; + left -= cp; + if (left) + i++; + } + + return ret; +} + +static inline size_t +iov_copy(const struct iovec *dst, int dcnt, const struct iovec *src, int scnt) +{ + size_t ret = 0; + size_t left = 0; + size_t min_i = 0; + int s_i = 0, s_ii = 0; + int d_i = 0, d_ii = 0; + + ret = min(iov_length(dst, dcnt), iov_length(src, scnt)); + left = ret; + + while (left) { + min_i = min(dst[d_i].iov_len - d_ii, src[s_i].iov_len - s_ii); + memcpy(dst[d_i].iov_base + d_ii, src[s_i].iov_base + s_ii, min_i); + + d_ii += min_i; + if (d_ii == dst[d_i].iov_len) { + d_ii = 0; + d_i++; + } + + s_ii += min_i; + if (s_ii == src[s_i].iov_len) { + s_ii = 0; + s_i++; + } + + left -= min_i; + } + + return ret; +} + +/* based on the amusing discussion @ https://rusty.ozlabs.org/?p=560 */ +static bool +memeqzero(const void *data, size_t length) +{ + const unsigned char *p = data; + size_t len; + + /* Check first 16 bytes manually */ + for (len = 0; len < 16; len++) { + if (!length) + return true; + if (*p) + return false; + p++; + length--; + } + + /* Now we know that's zero, memcmp with self. */ + return memcmp(data, p, length) == 0; +} + +static inline int +mem_0filled(const char *buf, size_t size) +{ + return !memeqzero(buf, size); +} + +static inline int +iov_0filled(struct iovec *vector, int count) +{ + int i = 0; + int ret = 0; + + for (i = 0; i < count; i++) { + ret = mem_0filled(vector[i].iov_base, vector[i].iov_len); + if (ret) + break; + } + + return ret; +} + +static inline void * +memdup(const void *ptr, size_t size) +{ + void *newptr = NULL; + + newptr = GF_MALLOC(size, gf_common_mt_memdup); + if (!newptr) + return NULL; + + memcpy(newptr, ptr, size); + return newptr; +} + +typedef enum { + gf_timefmt_default = 0, + gf_timefmt_FT = 0, /* YYYY-MM-DD hh:mm:ss */ + gf_timefmt_Ymd_T, /* YYYY/MM-DD-hh:mm:ss */ + gf_timefmt_bdT, /* MMM DD hh:mm:ss */ + gf_timefmt_F_HMS, /* YYYY-MM-DD hhmmss */ + gf_timefmt_dirent, + gf_timefmt_s, + gf_timefmt_last +} gf_timefmts; + +static inline char * +gf_time_fmt(char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +{ + extern void _gf_timestuff(const char ***, const char ***); + static gf_timefmts timefmt_last = (gf_timefmts)-1; + static const char **fmts; + static const char **zeros; + struct tm tm, *res; + int localtime = 0; + + if (timefmt_last == ((gf_timefmts)-1)) { + _gf_timestuff(&fmts, &zeros); + timefmt_last = gf_timefmt_last; + } + if (timefmt_last <= fmt) { + fmt = gf_timefmt_default; + } + localtime = gf_log_get_localtime(); + res = localtime ? localtime_r(&utime, &tm) : gmtime_r(&utime, &tm); + if (utime && (res != NULL)) { + strftime(dst, sz_dst, fmts[fmt], &tm); + } else { + strncpy(dst, "N/A", sz_dst); + } + return dst; +} + +/* This function helps us use gfid (unique identity) to generate inode's unique + * number in glusterfs. + */ +ino_t +gfid_to_ino(uuid_t gfid); + +int +mkdir_p(char *path, mode_t mode, gf_boolean_t allow_symlinks); +/* + * rounds up nr to power of two. If nr is already a power of two, just returns + * nr + */ + +int +gf_lstat_dir(const char *path, struct stat *stbuf_in); + +int32_t +gf_roundup_power_of_two(int32_t nr); + +/* + * rounds up nr to next power of two. If nr is already a power of two, next + * power of two is returned. + */ + +int32_t +gf_roundup_next_power_of_two(int32_t nr); + +char * +gf_trim(char *string); +int +gf_volume_name_validate(const char *volume_name); + +int +gf_string2long(const char *str, long *n); +int +gf_string2ulong(const char *str, unsigned long *n); +int +gf_string2int(const char *str, int *n); +int +gf_string2uint(const char *str, unsigned int *n); +int +gf_string2double(const char *str, double *n); +int +gf_string2longlong(const char *str, long long *n); +int +gf_string2ulonglong(const char *str, unsigned long long *n); + +int +gf_string2int8(const char *str, int8_t *n); +int +gf_string2int16(const char *str, int16_t *n); +int +gf_string2int32(const char *str, int32_t *n); +int +gf_string2int64(const char *str, int64_t *n); +int +gf_string2uint8(const char *str, uint8_t *n); +int +gf_string2uint16(const char *str, uint16_t *n); +int +gf_string2uint32(const char *str, uint32_t *n); +int +gf_string2uint64(const char *str, uint64_t *n); + +int +gf_strstr(const char *str, const char *delim, const char *match); + +int +gf_string2ulong_base10(const char *str, unsigned long *n); +int +gf_string2uint_base10(const char *str, unsigned int *n); +int +gf_string2uint8_base10(const char *str, uint8_t *n); +int +gf_string2uint16_base10(const char *str, uint16_t *n); +int +gf_string2uint32_base10(const char *str, uint32_t *n); +int +gf_string2uint64_base10(const char *str, uint64_t *n); +int +gf_string2bytesize_uint64(const char *str, uint64_t *n); +int +gf_string2bytesize_int64(const char *str, int64_t *n); +int +gf_string2percent_or_bytesize(const char *str, double *n, + gf_boolean_t *is_percent); + +int +gf_string2boolean(const char *str, gf_boolean_t *b); +int +gf_string2percent(const char *str, double *n); +int +gf_string2time(const char *str, uint32_t *n); + +int +gf_lockfd(int fd); +int +gf_unlockfd(int fd); + +int +get_checksum_for_file(int fd, uint32_t *checksum); +int +log_base2(unsigned long x); + +int +get_checksum_for_path(char *path, uint32_t *checksum); +int +get_file_mtime(const char *path, time_t *stamp); +char * +gf_resolve_path_parent(const char *path); + +char * +strtail(char *str, const char *pattern); +void +skipwhite(char **s); +char * +nwstrtail(char *str, char *pattern); +/* returns a new string with nth word of given string. n>=1 */ + +typedef struct token_iter { + char *end; + char sep; +} token_iter_t; +char * +token_iter_init(char *str, char sep, token_iter_t *tit); +gf_boolean_t +next_token(char **tokenp, token_iter_t *tit); +void +drop_token(char *token, token_iter_t *tit); + +gf_boolean_t +mask_match(const uint32_t a, const uint32_t b, const uint32_t m); +gf_boolean_t +gf_is_ip_in_net(const char *network, const char *ip_str); +char +valid_host_name(char *address, int length); +char +valid_ipv4_address(char *address, int length, gf_boolean_t wildcard_acc); +char +valid_ipv6_address(char *address, int length, gf_boolean_t wildcard_acc); +char +valid_internet_address(char *address, gf_boolean_t wildcard_acc); +gf_boolean_t +valid_mount_auth_address(char *address); +gf_boolean_t +valid_ipv4_subnetwork(const char *address); +gf_boolean_t +gf_sock_union_equal_addr(union gf_sock_union *a, union gf_sock_union *b); +char * +gf_rev_dns_lookup(const char *ip); + +char * +uuid_utoa(uuid_t uuid); +char * +uuid_utoa_r(uuid_t uuid, char *dst); +char * +lkowner_utoa(gf_lkowner_t *lkowner); +char * +lkowner_utoa_r(gf_lkowner_t *lkowner, char *dst, int len); +char * +leaseid_utoa(const char *lease_id); +gf_boolean_t +is_valid_lease_id(const char *lease_id); +char * +gf_leaseid_get(void); +char * +gf_existing_leaseid(void); + +void +gf_array_insertionsort(void *a, int l, int r, size_t elem_size, gf_cmp cmp); +int +gf_is_str_int(const char *value); + +char *gf_uint64_2human_readable(uint64_t); +int +get_vol_type(int type, int dist_count, int brick_count); +int +validate_brick_name(char *brick); +char * +get_host_name(char *word, char **host); +char * +get_path_name(char *word, char **path); +void +gf_path_strip_trailing_slashes(char *path); +uint64_t +get_mem_size(void); +int +gf_strip_whitespace(char *str, int len); +int +gf_canonicalize_path(char *path); +char * +generate_glusterfs_ctx_id(void); +char * +gf_get_reserved_ports(void); +int +gf_process_reserved_ports(unsigned char *ports, uint32_t ceiling); +gf_boolean_t +gf_ports_reserved(char *blocked_port, unsigned char *ports, uint32_t ceiling); +int +gf_get_hostname_from_ip(char *client_ip, char **hostname); +gf_boolean_t +gf_is_local_addr(char *hostname); +gf_boolean_t +gf_is_same_address(char *host1, char *host2); +void +gf_xxh64_wrapper(const unsigned char *data, size_t const len, + unsigned long long const seed, char *xxh64); +int +gf_gfid_generate_from_xxh64(uuid_t gfid, char *key); + +int +gf_set_timestamp(const char *src, const char *dest); + +int +gf_thread_create(pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg, const char *name); +int +gf_thread_create_detached(pthread_t *thread, void *(*start_routine)(void *), + void *arg, const char *name); +gf_boolean_t +gf_is_pid_running(int pid); +gf_boolean_t +gf_is_service_running(char *pidfile, int *pid); +gf_boolean_t +gf_valid_pid(const char *pid, int length); +int +gf_skip_header_section(int fd, int header_len); + +struct iatt; +struct _dict; + +gf_boolean_t +dht_is_linkfile(struct iatt *buf, struct _dict *dict); + +int +gf_check_log_format(const char *value); + +int +gf_check_logger(const char *value); + +gf_boolean_t +gf_compare_sockaddr(const struct sockaddr *addr1, const struct sockaddr *addr2); + +char * +gf_backtrace_save(char *buf); + +void +gf_backtrace_done(char *buf); + +gf_loglevel_t +fop_log_level(glusterfs_fop_t fop, int op_errno); + +int32_t +gf_build_absolute_path(char *current_path, char *relative_path, char **path); + +int +recursive_rmdir(const char *delete_path); + +int +gf_get_index_by_elem(char **array, char *elem); + +int +glusterfs_is_local_pathinfo(char *pathinfo, gf_boolean_t *local); + +int +gf_thread_cleanup_xint(pthread_t thread); + +ssize_t +gf_nread(int fd, void *buf, size_t count); + +ssize_t +gf_nwrite(int fd, const void *buf, size_t count); + +void +_mask_cancellation(void); +void +_unmask_cancellation(void); + +gf_boolean_t +gf_is_zero_filled_stat(struct iatt *buf); + +void +gf_zero_fill_stat(struct iatt *buf); + +gf_boolean_t +gf_is_valid_xattr_namespace(char *k); + +const char * +gf_inode_type_to_str(ia_type_t type); + +int32_t +gf_bits_count(uint64_t n); + +int32_t +gf_bits_index(uint64_t n); + +const char * +gf_fop_string(glusterfs_fop_t fop); + +int +gf_fop_int(char *fop); + +char * +get_ip_from_addrinfo(struct addrinfo *addr, char **ip); + +int +close_fds_except(int *fdv, size_t count); + +int +gf_getgrouplist(const char *user, gid_t group, gid_t **groups); + +int +glusterfs_compute_sha256(const unsigned char *content, size_t size, + char *sha256_hash); +char * +get_struct_variable(int mem_num, gf_gsync_status_t *sts_val); + +char * +gf_strncpy(char *dest, const char *src, const size_t dest_size); + +void +gf_strTrim(char **s); + +int +gf_replace_old_iatt_in_dict(struct _dict *); + +int +gf_replace_new_iatt_in_dict(struct _dict *); + +#endif /* _COMMON_UTILS_H */ |