1
0
mirror of https://github.com/gluster/gluster-block.git synced 2026-02-06 15:45:56 +01:00
Files
gluster-block/utils/utils.h
Prasanna Kumar Kalever 149c72ca06 socket: switch to MT-safe get host addr info
This was fixed in an attempt to clean the sockfd leaks

Change-Id: Icd82635134050c83167a48b451b347f5c2b9bf39
Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com>
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
2017-09-19 11:20:32 +05:30

517 lines
22 KiB
C

/*
Copyright (c) 2016 Red Hat, Inc. <http://www.redhat.com>
This file is part of gluster-block.
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 _UTILS_H
# define _UTILS_H 1
# define _GNU_SOURCE /* See feature_test_macros(7) */
# include <stdio.h>
# include <stdlib.h>
# include <stddef.h>
# include <stdbool.h>
# include <string.h>
# include <unistd.h>
# include <errno.h>
# include <time.h>
# include <limits.h>
# include <sys/time.h>
# define GB_LOGDIR DATADIR "/log/gluster-block"
# define GB_INFODIR DATADIR "/run"
# define GB_LOCK_FILE GB_INFODIR "/gluster-blockd.lock"
# define GB_UNIX_ADDRESS GB_INFODIR "/gluster-blockd.socket"
# define GB_TCP_PORT 24010
# define GB_TCP_PORT_STR "24010"
# define GFAPI_LOG_LEVEL 7
# define DEVNULLPATH "/dev/null"
# define GB_METADIR "/block-meta"
# define GB_STOREDIR "/block-store"
# define GB_TXLOCKFILE "meta.lock"
# define GB_MAX_LOGFILENAME 64 /* max strlen of file name */
# define SUN_PATH_MAX (sizeof(struct sockaddr_un) - sizeof(unsigned short int)) /*sun_family*/
# define GB_TIME_STRING_BUFLEN \
(4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 6 + 1 + 5)
/* Yr Mon Day Hour Min Sec Ms NULL Round-off(32)
2017 - 06 - 01 ' ' 18 : 58 : 29 . 695147 '\0' Power^2
2017-06-01 18:58:29.695147 */
/* Target Create */
# define FAILED_CREATE "failed in create"
# define FAILED_REMOTE_CREATE "failed in remote create"
# define FAILED_REMOTE_AYNC_CREATE "failed in remote async create"
# define FAILED_CREATING_FILE "failed while creating block file in gluster volume"
# define FAILED_CREATING_META "failed while creating block meta file from volume"
/* Target List */
# define FAILED_LIST "failed in list"
/* Target Info */
# define FAILED_INFO "failed in info"
/* Target Modify */
# define FAILED_MODIFY "failed in modify"
# define FAILED_REMOTE_MODIFY "failed in remote modify"
# define FAILED_REMOTE_AYNC_MODIFY "failed in remote async modify"
/* Target Delete */
# define FAILED_DELETE "failed in delete"
# define FAILED_REMOTE_DELETE "failed in remote delete"
# define FAILED_REMOTE_AYNC_DELETE "failed in remote async delete"
# define FAILED_DELETING_FILE "failed while deleting block file from gluster volume"
# define FAILED_DELETING_META "failed while deleting block meta file from volume"
# define FAILED_DEPENDENCY "failed dependency, check if you have targetcli and tcmu-runner installed"
# define FMT_WARN(fmt...) do { if (0) printf (fmt); } while (0)
# define GB_ASPRINTF(ptr, fmt...) ({FMT_WARN (fmt); \
int __ret=asprintf(ptr, ##fmt);__ret;})
# define LOCK(x) \
do { \
pthread_mutex_lock(&x); \
} while (0)
# define UNLOCK(x) \
do { \
pthread_mutex_unlock(&x); \
} while (0)
# define ERROR(fmt, ...) \
do { \
fprintf(stderr, "Error: " fmt " [at %s+%d :<%s>]\n", \
__VA_ARGS__, __FILE__, __LINE__, __FUNCTION__); \
} while (0)
# define MSG(fmt, ...) \
do { \
fprintf(stdout, fmt, __VA_ARGS__); \
} while (0)
struct gbConf {
int logLevel;
char logDir[PATH_MAX];
char daemonLogFile[PATH_MAX];
char cliLogFile[PATH_MAX];
char gfapiLogFile[PATH_MAX];
char configShellLogFile[PATH_MAX];
};
extern struct gbConf gbConf;
# define LOG(str, level, fmt, ...) \
do { \
FILE *fd; \
char timestamp[GB_TIME_STRING_BUFLEN] = {0}; \
if (level <= gbConf.logLevel) { \
if (!strcmp(str, "mgmt")) \
fd = fopen (gbConf.daemonLogFile, "a"); \
else if (!strcmp(str, "cli")) \
fd = fopen (gbConf.cliLogFile, "a"); \
else if (!strcmp(str, "gfapi")) \
fd = fopen (gbConf.gfapiLogFile, "a"); \
else \
fd = stderr; \
if (fd == NULL) { \
fprintf(stderr, "Error opening log file: %s\n" \
"Logging to stderr.\n", \
strerror(errno)); \
fd = stderr; \
} \
logTimeNow(timestamp, GB_TIME_STRING_BUFLEN); \
fprintf(fd, "[%s] %s: " fmt " [at %s+%d :<%s>]\n", \
timestamp, LogLevelLookup[level], \
__VA_ARGS__, __FILE__, __LINE__, __FUNCTION__); \
if (fd != stderr) \
fclose(fd); \
} \
} while (0)
# define GB_METALOCK_OR_GOTO(lkfd, volume, errCode, errMsg, label) \
do { \
struct flock lock = {0, }; \
lock.l_type = F_WRLCK; \
if (glfs_posix_lock (lkfd, F_SETLKW, &lock)) { \
LOG("mgmt", GB_LOG_ERROR, "glfs_posix_lock() on " \
"volume %s failed[%s]", volume, strerror(errno)); \
errCode = errno; \
if (!errMsg) { \
GB_ASPRINTF (&errMsg, "Not able to acquire " \
"lock on %s[%s]", volume, strerror(errCode));\
} \
goto label; \
} \
} while (0)
# define GB_METAUPDATE_OR_GOTO(lock, glfs, fname, \
volume, ret, errMsg, label,...) \
do { \
char *write; \
struct glfs_fd *tgmfd; \
LOCK(lock); \
ret = glfs_chdir (glfs, GB_METADIR); \
if (ret) { \
GB_ASPRINTF(&errMsg, "Failed to update transaction log " \
"for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("gfapi", GB_LOG_ERROR, "glfs_chdir(%s) on " \
"volume %s failed[%s]", GB_METADIR, volume, \
strerror(errno)); \
UNLOCK(lock); \
ret = -1; \
goto label; \
} \
tgmfd = glfs_creat(glfs, fname, \
O_WRONLY | O_APPEND | O_SYNC, \
S_IRUSR | S_IWUSR); \
if (!tgmfd) { \
GB_ASPRINTF(&errMsg, "Failed to update transaction log " \
"for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("mgmt", GB_LOG_ERROR, "glfs_creat(%s): on " \
"volume %s failed[%s]", fname, volume, \
strerror(errno)); \
UNLOCK(lock); \
ret = -1; \
goto label; \
} \
if (GB_ASPRINTF(&write, __VA_ARGS__) < 0) { \
ret = -1; \
} \
if (!ret) { \
if(glfs_write (tgmfd, write, strlen(write), 0) < 0) { \
GB_ASPRINTF(&errMsg, "Failed to update transaction log "\
"for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("mgmt", GB_LOG_ERROR, "glfs_write(%s): on " \
"volume %s failed[%s]", fname, volume, \
strerror(errno)); \
ret = -1; \
} \
GB_FREE(write); \
} \
if (tgmfd && glfs_close(tgmfd) != 0) { \
GB_ASPRINTF(&errMsg, "Failed to update transaction log " \
"for %s/%s[%s]", volume, fname, strerror(errno)); \
LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on " \
"volume %s failed[%s]", fname, volume, \
strerror(errno)); \
UNLOCK(lock); \
ret = -1; \
goto label; \
} \
UNLOCK(lock); \
if (ret) { \
goto label; \
} \
} while (0)
# define GB_METAUNLOCK(lkfd, volume, ret, errMsg) \
do { \
struct flock lock = {0, }; \
lock.l_type = F_UNLCK; \
if (glfs_posix_lock(lkfd, F_SETLK, &lock)) { \
if (!errMsg) { \
GB_ASPRINTF (&errMsg, "Not able to acquire " \
"lock on %s[%s]", volume, strerror(errno)); \
} \
LOG("mgmt", GB_LOG_ERROR, "glfs_posix_lock() on " \
"volume %s failed[%s]", volume, strerror(errno)); \
ret = -1; \
} \
} while (0)
# define GB_CMD_EXEC_AND_VALIDATE(cmd, sr, blk, vol, opt) \
do { \
FILE *fp; \
char tmp[1024]; \
LOG("mgmt", GB_LOG_DEBUG, "command, %s", cmd); \
fp = popen(cmd, "r"); \
snprintf(tmp, 1024, "%s/%s", vol?vol:"", blk->block_name); \
if (fp) { \
size_t newLen = fread(sr->out, sizeof(char), 8192, fp); \
if (ferror( fp ) != 0) \
LOG("mgmt", GB_LOG_ERROR, \
"reading command %s output for %s failed(%s)", tmp,\
cmd, strerror(errno)); \
else \
sr->out[newLen++] = '\0'; \
sr->exit = blockValidateCommandOutput(sr->out, opt, \
(void*)blk); \
pclose(fp); \
} else { \
LOG("mgmt", GB_LOG_ERROR, \
"popen(): for %s executing command %s failed(%s)", \
tmp, cmd, strerror(errno)); \
} \
LOG("mgmt", GB_LOG_DEBUG, "raw output, %s", sr->out); \
LOG("mgmt", GB_LOG_INFO, "command exit code, %d", \
sr->exit); \
} while (0)
# define GB_OUT_VALIDATE_OR_GOTO(out, label, errStr, blk, vol, ...) \
do { \
char *tmp; \
char vol_blk[1024]; \
snprintf(vol_blk, 1024, "%s/%s", vol?vol:"", \
blk->block_name); \
if (GB_ASPRINTF(&tmp, __VA_ARGS__) == -1) \
goto label; \
if (!strstr(out, tmp)) { \
GB_FREE(tmp); \
LOG("mgmt", GB_LOG_ERROR, errStr, vol_blk); \
goto label; \
} \
GB_FREE(tmp); \
} while (0)
# define GB_RPC_CALL(op, blk, reply, rqstp, ret) \
do { \
blockResponse *resp = block_##op##_1_svc_st(blk, rqstp); \
if (resp) { \
memcpy(reply, resp, sizeof(*reply)); \
GB_FREE(resp); \
ret = true; \
} else { \
ret = false; \
} \
} while (0)
# define CALLOC(x) \
calloc(1, x)
# define GB_ALLOC(ptr) \
gbAlloc(&(ptr), sizeof(*(ptr)), \
__FILE__, __FUNCTION__, __LINE__)
# define GB_ALLOC_N(ptr, count) \
gbAllocN(&(ptr), sizeof(*(ptr)), (count), \
__FILE__, __FUNCTION__, __LINE__) \
# define xalloc_oversized(n, s) \
((size_t) (sizeof(ptrdiff_t) <= sizeof(size_t) ? -1 : -2) / (s) < (n))
# define GB_REALLOC_N(ptr, count) \
gbReallocN(&(ptr), sizeof(*(ptr)), (count), \
__FILE__, __FUNCTION__, __LINE__)
# define GB_STRDUP(dst, src) \
gbStrdup(&(dst), src, \
__FILE__, __FUNCTION__, __LINE__)
# define GB_FREE(ptr) \
gbFree(1 ? (void *) &(ptr) : (ptr))
typedef enum gbCliCmdlineOption {
GB_CLI_UNKNOWN = 0,
GB_CLI_CREATE = 1,
GB_CLI_LIST = 2,
GB_CLI_INFO = 3,
GB_CLI_DELETE = 4,
GB_CLI_MODIFY = 5,
GB_CLI_HELP = 6,
GB_CLI_HYPHEN_HELP = 7,
GB_CLI_VERSION = 8,
GB_CLI_HYPHEN_VERSION = 9,
GB_CLI_USAGE = 10,
GB_CLI_HYPHEN_USAGE = 11,
GB_CLI_OPT_MAX
} gbCliCmdlineOption;
static const char *const gbCliCmdlineOptLookup[] = {
[GB_CLI_UNKNOWN] = "NONE",
[GB_CLI_CREATE] = "create",
[GB_CLI_LIST] = "list",
[GB_CLI_INFO] = "info",
[GB_CLI_DELETE] = "delete",
[GB_CLI_MODIFY] = "modify",
[GB_CLI_HELP] = "help",
[GB_CLI_HYPHEN_HELP] = "--help",
[GB_CLI_VERSION] = "version",
[GB_CLI_HYPHEN_VERSION] = "--version",
[GB_CLI_USAGE] = "usage",
[GB_CLI_HYPHEN_USAGE] = "--usage",
[GB_CLI_OPT_MAX] = NULL,
};
typedef enum gbDaemonCmdlineOption {
GB_DAEMON_UNKNOWN = 0,
GB_DAEMON_HELP = 1,
GB_DAEMON_VERSION = 2,
GB_DAEMON_USAGE = 3,
GB_DAEMON_GLFS_LRU_COUNT = 4,
GB_DAEMON_LOG_LEVEL = 5,
GB_DAEMON_OPT_MAX
} gbDaemonCmdlineOption;
static const char *const gbDaemonCmdlineOptLookup[] = {
[GB_DAEMON_UNKNOWN] = "NONE",
[GB_DAEMON_HELP] = "help",
[GB_DAEMON_VERSION] = "version",
[GB_DAEMON_USAGE] = "usage",
[GB_DAEMON_GLFS_LRU_COUNT] = "glfs-lru-count",
[GB_DAEMON_LOG_LEVEL] = "log-level",
[GB_DAEMON_OPT_MAX] = NULL,
};
typedef enum LogLevel {
GB_LOG_NONE = 0,
GB_LOG_ERROR = 1,
GB_LOG_WARNING = 2,
GB_LOG_INFO = 3,
GB_LOG_DEBUG = 4,
GB_LOG_TRACE = 5,
GB_LOG_MAX
} LogLevel;
static const char *const LogLevelLookup[] = {
[GB_LOG_NONE] = "NONE",
[GB_LOG_ERROR] = "ERROR",
[GB_LOG_WARNING] = "WARNING",
[GB_LOG_INFO] = "INFO",
[GB_LOG_DEBUG] = "DEBUG",
[GB_LOG_TRACE] = "TRACE",
[GB_LOG_MAX] = NULL,
};
typedef enum Metakey {
GB_META_VOLUME = 0,
GB_META_GBID = 1,
GB_META_SIZE = 2,
GB_META_HA = 3,
GB_META_ENTRYCREATE = 4,
GB_META_ENTRYDELETE = 5,
GB_META_PASSWD = 6,
GB_METAKEY_MAX
} Metakey;
static const char *const MetakeyLookup[] = {
[GB_META_VOLUME] = "VOLUME",
[GB_META_GBID] = "GBID",
[GB_META_SIZE] = "SIZE",
[GB_META_HA] = "HA",
[GB_META_ENTRYCREATE] = "ENTRYCREATE",
[GB_META_ENTRYDELETE] = "ENTRYDELETE",
[GB_META_PASSWD] = "PASSWORD",
[GB_METAKEY_MAX] = NULL
};
typedef enum MetaStatus {
GB_CONFIG_SUCCESS = 0,
GB_CONFIG_FAIL = 1,
GB_CONFIG_INPROGRESS = 2,
GB_AUTH_ENFORCEING = 3,
GB_AUTH_ENFORCED = 4,
GB_AUTH_ENFORCE_FAIL = 5,
GB_AUTH_CLEAR_ENFORCEING = 6,
GB_AUTH_CLEAR_ENFORCED = 7,
GB_AUTH_CLEAR_ENFORCE_FAIL = 8,
GB_CLEANUP_SUCCESS = 9,
GB_CLEANUP_FAIL = 10,
GB_CLEANUP_INPROGRESS = 11,
GB_METASTATUS_MAX
} MetaStatus;
static const char *const MetaStatusLookup[] = {
[GB_CONFIG_SUCCESS] = "CONFIGSUCCESS",
[GB_CONFIG_FAIL] = "CONFIGFAIL",
[GB_CONFIG_INPROGRESS] = "CONFIGINPROGRESS",
[GB_AUTH_ENFORCEING] = "AUTHENFORCEING",
[GB_AUTH_ENFORCED] = "AUTHENFORCED",
[GB_AUTH_ENFORCE_FAIL] = "AUTHENFORCEFAIL",
[GB_AUTH_CLEAR_ENFORCEING] = "AUTHCLEARENFORCEING",
[GB_AUTH_CLEAR_ENFORCED] = "AUTHCLEARENFORCED",
[GB_AUTH_CLEAR_ENFORCE_FAIL] = "AUTHCLEARENFORCEFAIL",
[GB_CLEANUP_INPROGRESS] = "CLEANUPINPROGRESS",
[GB_CLEANUP_SUCCESS] = "CLEANUPSUCCESS",
[GB_CLEANUP_FAIL] = "CLEANUPFAIL",
[GB_METASTATUS_MAX] = NULL,
};
typedef enum RemoteCreateResp {
GB_BACKEND_RESP = 0,
GB_IQN_RESP = 1,
GB_TPG_NO_RESP = 2,
GB_LUN_NO_RESP = 3,
GB_IP_PORT_RESP = 4,
GB_PORTAL_RESP = 5,
GB_FAILED_RESP = 6,
GB_REMOTE_CREATE_RESP_MAX
} RemoteCreateResp;
static const char *const RemoteCreateRespLookup[] = {
[GB_BACKEND_RESP] = "Created user-backed storage object ",
[GB_IQN_RESP] = "Created target ",
[GB_TPG_NO_RESP] = "Created TPG ",
[GB_LUN_NO_RESP] = "Created LUN ",
[GB_IP_PORT_RESP] = "Using default IP port ",
[GB_PORTAL_RESP] = "Created network portal ",
[GB_FAILED_RESP] = "failed to configure on ",
[GB_REMOTE_CREATE_RESP_MAX] = NULL,
};
int glusterBlockCLIOptEnumParse(const char *opt);
int glusterBlockDaemonOptEnumParse(const char *opt);
int blockLogLevelEnumParse(const char *opt);
int blockMetaKeyEnumParse(const char *opt);
int blockMetaStatusEnumParse(const char *opt);
int blockRemoteCreateRespEnumParse(const char *opt);
void logTimeNow(char* buf, size_t bufSize);
int initLogging(void);
int gbRunnerExitStatus(int exitStatus);
int gbRunner(char *cmd);
int gbAlloc(void *ptrptr, size_t size,
const char *filename, const char *funcname, size_t linenr);
int gbAllocN(void *ptrptr, size_t size, size_t count,
const char *filename, const char *funcname, size_t linenr);
int gbReallocN(void *ptrptr, size_t size, size_t count,
const char *filename, const char *funcname, size_t linenr);
int gbStrdup(char **dest, const char *src,
const char *filename, const char *funcname, size_t linenr);
void gbFree(void *ptrptr);
#endif /* _UTILS_H */