#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include "out.h"
#include "os.h"
#include "librpmem.h"
#include "rpmem_proto.h"
#include "rpmem_common.h"
#include "rpmem_util.h"
static struct rpmem_err_str_errno {
int err;
const char *str;
} rpmem_err_str_errno[MAX_RPMEM_ERR] = {
[RPMEM_SUCCESS] = {
.err = 0,
.str = "Success",
},
[RPMEM_ERR_BADPROTO] = {
.err = EPROTONOSUPPORT,
.str = "Protocol version number mismatch",
},
[RPMEM_ERR_BADNAME] = {
.err = EINVAL,
.str = "Invalid pool descriptor",
},
[RPMEM_ERR_BADSIZE] = {
.err = EFBIG,
.str = "Invalid pool size",
},
[RPMEM_ERR_BADNLANES] = {
.err = EINVAL,
.str = "Invalid number of lanes",
},
[RPMEM_ERR_BADPROVIDER] = {
.err = EINVAL,
.str = "Invalid provider",
},
[RPMEM_ERR_FATAL] = {
.err = EREMOTEIO,
.str = "Fatal error",
},
[RPMEM_ERR_FATAL_CONN] = {
.err = ECONNABORTED,
.str = "Fatal in-band connection error",
},
[RPMEM_ERR_BUSY] = {
.err = EBUSY,
.str = "Pool already in use",
},
[RPMEM_ERR_EXISTS] = {
.err = EEXIST,
.str = "Pool already exists",
},
[RPMEM_ERR_PROVNOSUP] = {
.err = EMEDIUMTYPE,
.str = "Provider not supported",
},
[RPMEM_ERR_NOEXIST] = {
.err = ENOENT,
.str = "Pool set or its part doesn't exist or it is "
"unavailable",
},
[RPMEM_ERR_NOACCESS] = {
.err = EACCES,
.str = "Pool set permission denied",
},
[RPMEM_ERR_POOL_CFG] = {
.err = EINVAL,
.str = "Invalid pool set configuration",
},
};
static char *Rpmem_cmds;
static char *Rpmem_current_cmd;
#define RPMEM_CMD_SEPARATOR '|'
const char *
rpmem_util_proto_errstr(enum rpmem_err err)
{
RPMEM_ASSERT(err < MAX_RPMEM_ERR);
const char *ret = rpmem_err_str_errno[err].str;
RPMEM_ASSERT(ret);
return ret;
}
int
rpmem_util_proto_errno(enum rpmem_err err)
{
RPMEM_ASSERT(err < MAX_RPMEM_ERR);
return rpmem_err_str_errno[err].err;
}
void
rpmem_util_cmds_init(void)
{
char *cmd = os_getenv(RPMEM_CMD_ENV);
if (!cmd)
cmd = RPMEM_DEF_CMD;
Rpmem_cmds = strdup(cmd);
if (!Rpmem_cmds)
RPMEM_FATAL("!strdup");
Rpmem_current_cmd = Rpmem_cmds;
}
void
rpmem_util_cmds_fini(void)
{
RPMEM_ASSERT(Rpmem_cmds);
free(Rpmem_cmds);
Rpmem_cmds = NULL;
Rpmem_current_cmd = NULL;
}
const char *
rpmem_util_cmd_get(void)
{
RPMEM_ASSERT(Rpmem_cmds);
RPMEM_ASSERT(Rpmem_current_cmd);
char *eol = strchr(Rpmem_current_cmd, RPMEM_CMD_SEPARATOR);
char *ret = Rpmem_current_cmd;
if (eol) {
*eol = '\0';
Rpmem_current_cmd = eol + 1;
}
return ret;
}
void
rpmem_util_get_env_max_nlanes(unsigned *max_nlanes)
{
char *env_nlanes = os_getenv(RPMEM_MAX_NLANES_ENV);
if (env_nlanes) {
int nlanes = atoi(env_nlanes);
if (nlanes <= 0) {
RPMEM_LOG(ERR, "%s variable must be a positive integer",
RPMEM_MAX_NLANES_ENV);
} else {
*max_nlanes = (unsigned)nlanes;
}
}
}