diff options
Diffstat (limited to 'libglusterfs/src/common-utils.h')
| -rw-r--r-- | libglusterfs/src/common-utils.h | 376 |
1 files changed, 314 insertions, 62 deletions
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 4371888d0..3c99a4212 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -1,20 +1,11 @@ /* - Copyright (c) 2006-2010 Gluster, Inc. <http://www.gluster.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/>. + 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 @@ -32,9 +23,10 @@ #include <string.h> #include <assert.h> #include <pthread.h> +#include <openssl/md5.h> #ifndef GF_BSD_HOST_OS #include <alloca.h> -#endif +#endif void trap (void); @@ -47,6 +39,8 @@ void trap (void); #include "glusterfs.h" #include "locking.h" #include "mem-pool.h" +#include "uuid.h" + #define min(a,b) ((a)<(b)?(a):(b)) @@ -67,77 +61,185 @@ void trap (void); #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 GF_SELINUX_XATTR_KEY "security.selinux" -enum _gf_boolean +#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")) + +/* 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 + +enum _gf_boolean { - _gf_false = 0, + _gf_false = 0, _gf_true = 1 }; +/* + * 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 couple of clients that use this feature, it's + * okay. + */ +enum _gf_client_pid +{ + GF_CLIENT_PID_MAX = 0, + GF_CLIENT_PID_GSYNCD = -1, + GF_CLIENT_PID_HADOOP = -2, + GF_CLIENT_PID_DEFRAG = -3, +}; + typedef enum _gf_boolean gf_boolean_t; +typedef enum _gf_client_pid gf_client_pid_t; +typedef int (*gf_cmp) (void *, void *); void gf_global_variable_init(void); in_addr_t gf_resolve_ip (const char *hostname, void **dnscache); -void gf_log_volume_file (FILE *specfp); -void gf_print_trace (int32_t signal); - -extern char *gf_fop_list[GF_FOP_MAXVALUE]; -extern char *gf_mgmt_list[GF_MGMT_MAXVALUE]; +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); #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_log ((this ? this->name : "(Govinda! Govinda!)"), \ - GF_LOG_ERROR, \ - "invalid argument: " #arg); \ + gf_log_callingfn ((this ? (this->name) : \ + "(Govinda! Govinda!)"), \ + GF_LOG_WARNING, \ + "invalid argument: " #arg); \ goto label; \ } \ - } while (0); + } while (0) -#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \ - if (!arg) { \ - errno = EINVAL; \ - gf_log (name, GF_LOG_ERROR, \ - "invalid argument: " #arg); \ - goto label; \ - } \ - } while (0); +#define GF_VALIDATE_OR_GOTO(name,arg,label) do { \ + if (!arg) { \ + errno = EINVAL; \ + gf_log_callingfn (name, GF_LOG_ERROR, \ + "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_log (name, GF_LOG_ERROR, \ - "invalid argument: " #arg); \ + gf_log_callingfn (name, GF_LOG_ERROR, \ + "invalid argument: " #arg); \ 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_log (name, GF_LOG_ERROR, \ - "invalid argument: " #arg); \ - goto label; \ - } \ - } while (0); + }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_log_callingfn (name, GF_LOG_ERROR, \ + "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_IF_INTERNAL_XATTR_GOTO(pattern, dict, op_errno, label) \ + do { \ + if (!dict) { \ + gf_log (this->name, GF_LOG_ERROR, \ + "setxattr dict is null"); \ + goto label; \ + } \ + if (dict_foreach_fnmatch (dict, pattern, \ + dict_null_foreach_fn, \ + NULL) > 0) { \ + op_errno = EPERM; \ + gf_log (this->name, GF_LOG_ERROR, \ + "attempt to set internal" \ + " xattr: %s: %s", pattern, \ + strerror (op_errno)); \ + goto label; \ + } \ + } while (0) + +#define GF_IF_NATIVE_XATTR_GOTO(pattern, key, op_errno, label) \ + do { \ + if (!key) { \ + gf_log (this->name, GF_LOG_ERROR, \ + "no key for removexattr"); \ + goto label; \ + } \ + if (!fnmatch (pattern, key, 0)) { \ + op_errno = EPERM; \ + gf_log (this->name, GF_LOG_ERROR, \ + "attempt to remove internal " \ + "xattr: %s: %s", key, \ + strerror (op_errno)); \ + goto label; \ + } \ + } while (0) + #define GF_FILE_CONTENT_REQUESTED(_xattr_req,_content_limit) \ (dict_get_uint64 (_xattr_req, "glusterfs.content", _content_limit) == 0) -#define GF_ASSERT(x) \ - do { \ - if (!(x)) { \ - gf_log_callingfn ("", GF_LOG_ERROR, \ - "Assertion failed: " #x); \ - } \ - } while (0); +#ifdef DEBUG +#define GF_ASSERT(x) assert (x); +#else +#define GF_ASSERT(x) \ + do { \ + if (!(x)) { \ + gf_log_callingfn ("", GF_LOG_ERROR, \ + "Assertion failed: " #x); \ + } \ + } while (0) +#endif + +#define GF_UUID_ASSERT(u) \ + if (uuid_is_null (u))\ + GF_ASSERT (!"uuid null"); + +union gf_sock_union { + struct sockaddr_storage storage; + struct sockaddr_in6 sin6; + struct sockaddr_in sin; + struct sockaddr sa; +}; + +#define GF_HIDDEN_PATH ".glusterfs" static inline void iov_free (struct iovec *vector, int count) @@ -165,7 +267,7 @@ iov_length (const struct iovec *vector, int count) static inline struct iovec * -iov_dup (struct iovec *vector, int count) +iov_dup (const struct iovec *vector, int count) { int bytecount = 0; int i; @@ -245,6 +347,65 @@ iov_unload (char *buf, const struct iovec *vector, int count) } +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; +} + + static inline int mem_0filled (const char *buf, size_t size) { @@ -290,9 +451,55 @@ memdup (const void *ptr, size_t 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, /* ddd DD hh:mm:ss */ + gf_timefmt_F_HMS, /* YYYY-MM-DD hhmmss */ + gf_timefmt_last +} gf_timefmts; + +static inline void +gf_time_fmt (char *dst, size_t sz_dst, time_t utime, unsigned int fmt) +{ + extern void _gf_timestuff (gf_timefmts *, const char ***, const char ***); + static gf_timefmts timefmt_last = (gf_timefmts) -1; + static const char **fmts; + static const char **zeros; + struct tm tm; + + if (timefmt_last == -1) + _gf_timestuff (&timefmt_last, &fmts, &zeros); + if (timefmt_last < fmt) fmt = gf_timefmt_default; + if (utime && gmtime_r (&utime, &tm) != NULL) { + strftime (dst, sz_dst, fmts[fmt], &tm); + } else { + strncpy (dst, "N/A", sz_dst); + } +} + +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_strsplit (const char *str, const char *delim, +int gf_strsplit (const char *str, const char *delim, char ***tokens, int *token_count); int gf_volume_name_validate (const char *volume_name); @@ -323,9 +530,11 @@ int gf_string2uint32_base10 (const char *str, uint32_t *n); int gf_string2uint64_base10 (const char *str, uint64_t *n); int gf_string2bytesize (const char *str, uint64_t *n); +int gf_string2percent_or_bytesize (const char *str, uint64_t *n, + gf_boolean_t *is_percent); int gf_string2boolean (const char *str, gf_boolean_t *b); -int gf_string2percent (const char *str, uint32_t *n); +int gf_string2percent (const char *str, double *n); int gf_string2time (const char *str, uint32_t *n); int gf_lockfd (int fd); @@ -334,9 +543,52 @@ int gf_unlockfd (int fd); int get_checksum_for_file (int fd, uint32_t *checksum); int log_base2 (unsigned long x); -int gf_system (const char *command); int get_checksum_for_path (char *path, uint32_t *checksum); char *strtail (char *str, const char *pattern); -#endif /* _COMMON_UTILS_H */ +void skipwhite (char **s); +char *nwstrtail (char *str, char *pattern); +void skip_word (char **str); +/* returns a new string with nth word of given string. n>=1 */ +char *get_nth_word (const char *str, int n); + +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); +char valid_ipv4_wildcard_check (char *address); +char valid_ipv6_wildcard_check (char *address); +char valid_wildcard_internet_address (char *address); +gf_boolean_t gf_sock_union_equal_addr (union gf_sock_union *a, + union gf_sock_union *b); + +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); + +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 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 (); +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(); +int gf_process_reserved_ports (gf_boolean_t ports[]); +gf_boolean_t gf_ports_reserved (char *blocked_port, gf_boolean_t *ports); +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 md5_wrapper(const unsigned char *data, size_t len, char *md5); + +int gf_thread_create (pthread_t *thread, const pthread_attr_t *attr, + void *(*start_routine)(void *), void *arg); +#endif /* _COMMON_UTILS_H */ |
