|
Packit |
b2c0d9 |
/*
|
|
Packit |
b2c0d9 |
Copyright (c) 2008-2012 Red Hat, Inc. <http://www.redhat.com>
|
|
Packit |
b2c0d9 |
This file is part of GlusterFS.
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
This file is licensed to you under your choice of the GNU Lesser
|
|
Packit |
b2c0d9 |
General Public License, version 3 or any later version (LGPLv3 or
|
|
Packit |
b2c0d9 |
later), or the GNU General Public License, version 2 (GPLv2), in all
|
|
Packit |
b2c0d9 |
cases as published by the Free Software Foundation.
|
|
Packit |
b2c0d9 |
*/
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
#include <fnmatch.h>
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
#include "glusterfs/xlator.h"
|
|
Packit |
b2c0d9 |
#include "glusterfs/defaults.h"
|
|
Packit |
b2c0d9 |
#include "glusterfs/libglusterfs-messages.h"
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
#define GF_OPTION_LIST_EMPTY(_opt) (_opt->value[0] == NULL)
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_path(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (strstr(value, "../")) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid path given '%s'", value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Make sure the given path is valid */
|
|
Packit |
b2c0d9 |
if (value[0] != '/') {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"option %s %s: '%s' is not an "
|
|
Packit |
b2c0d9 |
"absolute path name",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_int(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
long long inputll = 0;
|
|
Packit |
b2c0d9 |
unsigned long long uinputll = 0;
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check the range */
|
|
Packit |
b2c0d9 |
if (gf_string2longlong(value, &inputll) != 0) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Handle '-0' */
|
|
Packit |
b2c0d9 |
if ((inputll == 0) && (gf_string2ulonglong(value, &uinputll) != 0)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((opt->min == 0) && (opt->max == 0) &&
|
|
Packit |
b2c0d9 |
(opt->validate == GF_OPT_VALIDATE_BOTH)) {
|
|
Packit |
b2c0d9 |
gf_msg_trace(xl->name, 0,
|
|
Packit |
b2c0d9 |
"no range check required for "
|
|
Packit |
b2c0d9 |
"'option %s %s'",
|
|
Packit |
b2c0d9 |
key, value);
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (opt->validate == GF_OPT_VALIDATE_MIN) {
|
|
Packit |
b2c0d9 |
if (inputll < opt->min) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%lld' in 'option %s %s' is smaller than "
|
|
Packit |
b2c0d9 |
"minimum value '%.0f'",
|
|
Packit |
b2c0d9 |
inputll, key, value, opt->min);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
} else if (opt->validate == GF_OPT_VALIDATE_MAX) {
|
|
Packit |
b2c0d9 |
if (inputll > opt->max) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%lld' in 'option %s %s' is greater than "
|
|
Packit |
b2c0d9 |
"maximum value '%.0f'",
|
|
Packit |
b2c0d9 |
inputll, key, value, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
} else if ((inputll < opt->min) || (inputll > opt->max)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%lld' in 'option %s %s' is out of range "
|
|
Packit |
b2c0d9 |
"[%.0f - %.0f]",
|
|
Packit |
b2c0d9 |
inputll, key, value, opt->min, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_sizet(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
uint64_t size = 0;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check the range */
|
|
Packit |
b2c0d9 |
if (gf_string2bytesize_uint64(value, &size) != 0) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((opt->min == 0) && (opt->max == 0)) {
|
|
Packit |
b2c0d9 |
gf_msg_trace(xl->name, 0,
|
|
Packit |
b2c0d9 |
"no range check required for "
|
|
Packit |
b2c0d9 |
"'option %s %s'",
|
|
Packit |
b2c0d9 |
key, value);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((size < opt->min) || (size > opt->max)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%" PRIu64
|
|
Packit |
b2c0d9 |
"' in 'option %s %s' is out of range [%.0f - %.0f]",
|
|
Packit |
b2c0d9 |
size, key, value, opt->min, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr);
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_bool(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
gf_boolean_t is_valid;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check if the value is one of
|
|
Packit |
b2c0d9 |
'0|1|on|off|no|yes|true|false|enable|disable' */
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (gf_string2boolean(value, &is_valid) != 0) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "option %s %s: '%s' is not a valid boolean value",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_xlator(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
xlator_t *xlopt = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check if the value is one of the xlators */
|
|
Packit |
b2c0d9 |
xlopt = xl;
|
|
Packit |
b2c0d9 |
while (xlopt->prev)
|
|
Packit |
b2c0d9 |
xlopt = xlopt->prev;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
while (xlopt) {
|
|
Packit |
b2c0d9 |
if (strcmp(value, xlopt->name) == 0) {
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
break;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
xlopt = xlopt->next;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (!xlopt) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "option %s %s: '%s' is not a valid volume name",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
void
|
|
Packit |
b2c0d9 |
set_error_str(char *errstr, size_t len, volume_option_t *opt, const char *key,
|
|
Packit |
b2c0d9 |
const char *value)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int i = 0;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = snprintf(errstr, len,
|
|
Packit |
b2c0d9 |
"option %s %s: '%s' is not valid "
|
|
Packit |
b2c0d9 |
"(possible options are ",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i];) {
|
|
Packit |
b2c0d9 |
ret += snprintf(errstr + ret, len - ret, "%s", opt->value[i]);
|
|
Packit |
b2c0d9 |
if (((++i) < ZR_OPTION_MAX_ARRAY_SIZE) && (opt->value[i]))
|
|
Packit |
b2c0d9 |
ret += snprintf(errstr + ret, len - ret, ", ");
|
|
Packit |
b2c0d9 |
else
|
|
Packit |
b2c0d9 |
ret += snprintf(errstr + ret, len - ret, ".)");
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
return;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
is_all_whitespaces(const char *value)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int i = 0;
|
|
Packit |
b2c0d9 |
size_t len = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (value == NULL)
|
|
Packit |
b2c0d9 |
return -1;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
len = strlen(value);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
for (i = 0; i < len; i++) {
|
|
Packit |
b2c0d9 |
if (value[i] == ' ')
|
|
Packit |
b2c0d9 |
continue;
|
|
Packit |
b2c0d9 |
else
|
|
Packit |
b2c0d9 |
return 0;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return 1;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_str(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
int i = 0;
|
|
Packit |
b2c0d9 |
char errstr[4096] = {
|
|
Packit |
b2c0d9 |
0,
|
|
Packit |
b2c0d9 |
};
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check if the '*str' is valid */
|
|
Packit |
b2c0d9 |
if (GF_OPTION_LIST_EMPTY(opt)) {
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (is_all_whitespaces(value) == 1)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
for (i = 0; (i < ZR_OPTION_MAX_ARRAY_SIZE) && opt->value[i]; i++) {
|
|
Packit |
b2c0d9 |
#ifdef GF_DARWIN_HOST_OS
|
|
Packit |
b2c0d9 |
if (fnmatch(opt->value[i], value, 0) == 0) {
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
break;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
#else
|
|
Packit |
b2c0d9 |
if (fnmatch(opt->value[i], value, FNM_EXTMATCH) == 0) {
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
break;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
#endif
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((i == ZR_OPTION_MAX_ARRAY_SIZE) || (!opt->value[i]))
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
/* enter here only if
|
|
Packit |
b2c0d9 |
* 1. reached end of opt->value array and haven't
|
|
Packit |
b2c0d9 |
* validated input
|
|
Packit |
b2c0d9 |
* OR
|
|
Packit |
b2c0d9 |
* 2. valid input list is less than
|
|
Packit |
b2c0d9 |
* ZR_OPTION_MAX_ARRAY_SIZE and input has not
|
|
Packit |
b2c0d9 |
* matched all possible input values.
|
|
Packit |
b2c0d9 |
*/
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
set_error_str(errstr, sizeof(errstr), opt, key, value);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
if (op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_percent(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
double percent = 0;
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check if the value is valid percentage */
|
|
Packit |
b2c0d9 |
if (gf_string2percent(value, &percent) != 0) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid percent format \"%s\" in \"option %s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((percent < 0.0) || (percent > 100.0)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%lf' in 'option %s %s' is out of range [0 - 100]", percent,
|
|
Packit |
b2c0d9 |
key, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_fractional_value(const char *value)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
const char *s = NULL;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
s = strchr(value, '.');
|
|
Packit |
b2c0d9 |
if (s) {
|
|
Packit |
b2c0d9 |
for (s = s + 1; *s != '\0'; s++) {
|
|
Packit |
b2c0d9 |
if (*s != '0') {
|
|
Packit |
b2c0d9 |
return -1;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_percent_or_sizet(xlator_t *xl, const char *key,
|
|
Packit |
b2c0d9 |
const char *value, volume_option_t *opt,
|
|
Packit |
b2c0d9 |
char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
double size = 0;
|
|
Packit |
b2c0d9 |
gf_boolean_t is_percent = _gf_false;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (gf_string2percent_or_bytesize(value, &size, &is_percent) == 0) {
|
|
Packit |
b2c0d9 |
if (is_percent) {
|
|
Packit |
b2c0d9 |
if ((size < 0.0) || (size > 100.0)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, sizeof(errstr),
|
|
Packit |
b2c0d9 |
"'%lf' in 'option %s %s' is out"
|
|
Packit |
b2c0d9 |
" of range [0 - 100]",
|
|
Packit |
b2c0d9 |
size, key, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/*Input value of size(in byte) should not be fractional*/
|
|
Packit |
b2c0d9 |
ret = xlator_option_validate_fractional_value(value);
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, sizeof(errstr),
|
|
Packit |
b2c0d9 |
"'%lf' in 'option %s"
|
|
Packit |
b2c0d9 |
" %s' should not be fractional value. Use "
|
|
Packit |
b2c0d9 |
"valid unsigned integer value.",
|
|
Packit |
b2c0d9 |
size, key, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check the range */
|
|
Packit |
b2c0d9 |
if ((opt->min == 0) && (opt->max == 0)) {
|
|
Packit |
b2c0d9 |
gf_msg_trace(xl->name, 0,
|
|
Packit |
b2c0d9 |
"no range check required "
|
|
Packit |
b2c0d9 |
"for 'option %s %s'",
|
|
Packit |
b2c0d9 |
key, value);
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
if ((size < opt->min) || (size > opt->max)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%lf' in 'option %s %s'"
|
|
Packit |
b2c0d9 |
" is out of range [%.0f - %.0f]",
|
|
Packit |
b2c0d9 |
size, key, value, opt->min, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* If control reaches here, invalid argument */
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid number format \"%s\" in \"option %s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_time(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
uint32_t input_time = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check if the value is valid time */
|
|
Packit |
b2c0d9 |
if (gf_string2time(value, &input_time) != 0) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"invalid time format \"%s\" in "
|
|
Packit |
b2c0d9 |
"\"option %s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((opt->min == 0) && (opt->max == 0)) {
|
|
Packit |
b2c0d9 |
gf_msg_trace(xl->name, 0,
|
|
Packit |
b2c0d9 |
"no range check required for "
|
|
Packit |
b2c0d9 |
"'option %s %s'",
|
|
Packit |
b2c0d9 |
key, value);
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((input_time < opt->min) || (input_time > opt->max)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%" PRIu32
|
|
Packit |
b2c0d9 |
"' in 'option %s %s' is "
|
|
Packit |
b2c0d9 |
"out of range [%.0f - %.0f]",
|
|
Packit |
b2c0d9 |
input_time, key, value, opt->min, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_double(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
double input = 0.0;
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Check the range */
|
|
Packit |
b2c0d9 |
if (gf_string2double(value, &input) != 0) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "invalid number format \"%s\" in option \"%s\"",
|
|
Packit |
b2c0d9 |
value, key);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if ((opt->min == 0) && (opt->max == 0) &&
|
|
Packit |
b2c0d9 |
(opt->validate == GF_OPT_VALIDATE_BOTH)) {
|
|
Packit |
b2c0d9 |
gf_msg_trace(xl->name, 0,
|
|
Packit |
b2c0d9 |
"no range check required for "
|
|
Packit |
b2c0d9 |
"'option %s %s'",
|
|
Packit |
b2c0d9 |
key, value);
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (opt->validate == GF_OPT_VALIDATE_MIN) {
|
|
Packit |
b2c0d9 |
if (input < opt->min) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%f' in 'option %s %s' is smaller than "
|
|
Packit |
b2c0d9 |
"minimum value '%f'",
|
|
Packit |
b2c0d9 |
input, key, value, opt->min);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
} else if (opt->validate == GF_OPT_VALIDATE_MAX) {
|
|
Packit |
b2c0d9 |
if (input > opt->max) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%f' in 'option %s %s' is greater than "
|
|
Packit |
b2c0d9 |
"maximum value '%f'",
|
|
Packit |
b2c0d9 |
input, key, value, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s",
|
|
Packit |
b2c0d9 |
errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
} else if ((input < opt->min) || (input > opt->max)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256,
|
|
Packit |
b2c0d9 |
"'%f' in 'option %s %s' is out of range "
|
|
Packit |
b2c0d9 |
"[%f - %f]",
|
|
Packit |
b2c0d9 |
input, key, value, opt->min, opt->max);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_OUT_OF_RANGE, "%s", errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret && op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_addr(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char errstr[256];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (!valid_internet_address((char *)value, _gf_false, _gf_false)) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 256, "option %s %s: Can not parse %s address", key,
|
|
Packit |
b2c0d9 |
value, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
if (op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_option_validate_addr_list(xlator_t *xl, const char *key,
|
|
Packit |
b2c0d9 |
const char *value, volume_option_t *opt,
|
|
Packit |
b2c0d9 |
char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char *dup_val = NULL;
|
|
Packit |
b2c0d9 |
char *addr_tok = NULL;
|
|
Packit |
b2c0d9 |
char *save_ptr = NULL;
|
|
Packit |
b2c0d9 |
char *entry = NULL;
|
|
Packit |
b2c0d9 |
char *entry_ptr = NULL;
|
|
Packit |
b2c0d9 |
char *dir_and_addr = NULL;
|
|
Packit |
b2c0d9 |
char *addr_ptr = NULL;
|
|
Packit |
b2c0d9 |
char *addr_list = NULL;
|
|
Packit |
b2c0d9 |
char *addr = NULL;
|
|
Packit |
b2c0d9 |
char *dir = NULL;
|
|
Packit |
b2c0d9 |
char errstr[4096] = {
|
|
Packit |
b2c0d9 |
0,
|
|
Packit |
b2c0d9 |
};
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
dup_val = gf_strdup(value);
|
|
Packit |
b2c0d9 |
if (!dup_val)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (dup_val[0] != '/' && !strchr(dup_val, '(')) {
|
|
Packit |
b2c0d9 |
/* Possible old format, handle it for back-ward compatibility */
|
|
Packit |
b2c0d9 |
addr_tok = strtok_r(dup_val, ",", &save_ptr);
|
|
Packit |
b2c0d9 |
while (addr_tok) {
|
|
Packit |
b2c0d9 |
if (!valid_internet_address(addr_tok, _gf_true, _gf_true))
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
addr_tok = strtok_r(NULL, ",", &save_ptr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Lets handle the value with new format */
|
|
Packit |
b2c0d9 |
entry = strtok_r(dup_val, ",", &entry_ptr);
|
|
Packit |
b2c0d9 |
while (entry) {
|
|
Packit |
b2c0d9 |
dir_and_addr = gf_strdup(entry);
|
|
Packit |
b2c0d9 |
if (!dir_and_addr)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
dir = strtok_r(dir_and_addr, "(", &addr_ptr);
|
|
Packit |
b2c0d9 |
if (dir[0] != '/') {
|
|
Packit |
b2c0d9 |
/* Valid format should be starting from '/' */
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
/* dir = strtok_r (NULL, " =", &addr_tmp); */
|
|
Packit |
b2c0d9 |
addr = strtok_r(NULL, ")", &addr_ptr);
|
|
Packit |
b2c0d9 |
if (!addr)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
addr_list = gf_strdup(addr);
|
|
Packit |
b2c0d9 |
if (!addr_list)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* This format be separated by '|' */
|
|
Packit |
b2c0d9 |
addr_tok = strtok_r(addr_list, "|", &save_ptr);
|
|
Packit |
b2c0d9 |
if (addr_tok == NULL)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
while (addr_tok) {
|
|
Packit |
b2c0d9 |
if (!valid_internet_address(addr_tok, _gf_true, _gf_true))
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
addr_tok = strtok_r(NULL, "|", &save_ptr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
entry = strtok_r(NULL, ",", &entry_ptr);
|
|
Packit |
b2c0d9 |
GF_FREE(dir_and_addr);
|
|
Packit |
b2c0d9 |
GF_FREE(addr_list);
|
|
Packit |
b2c0d9 |
addr_list = NULL;
|
|
Packit |
b2c0d9 |
dir_and_addr = NULL;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, sizeof(errstr),
|
|
Packit |
b2c0d9 |
"option %s %s: '%s' is not "
|
|
Packit |
b2c0d9 |
"a valid internet-address-list",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
if (op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
GF_FREE(dup_val);
|
|
Packit |
b2c0d9 |
GF_FREE(dir_and_addr);
|
|
Packit |
b2c0d9 |
GF_FREE(addr_list);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_mntauth(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
char *dup_val = NULL;
|
|
Packit |
b2c0d9 |
char *addr_tok = NULL;
|
|
Packit |
b2c0d9 |
char *save_ptr = NULL;
|
|
Packit |
b2c0d9 |
char errstr[4096] = {
|
|
Packit |
b2c0d9 |
0,
|
|
Packit |
b2c0d9 |
};
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
dup_val = gf_strdup(value);
|
|
Packit |
b2c0d9 |
if (!dup_val)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
addr_tok = strtok_r(dup_val, ",", &save_ptr);
|
|
Packit |
b2c0d9 |
if (addr_tok == NULL)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
while (addr_tok) {
|
|
Packit |
b2c0d9 |
if (!valid_mount_auth_address(addr_tok))
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
addr_tok = strtok_r(NULL, ",", &save_ptr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, sizeof(errstr),
|
|
Packit |
b2c0d9 |
"option %s %s: '%s' is not "
|
|
Packit |
b2c0d9 |
"a valid mount-auth-address",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
|
|
Packit |
b2c0d9 |
if (op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
GF_FREE(dup_val);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/*XXX: the rules to validate are as per block-size required for stripe xlator */
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
gf_validate_size(const char *sizestr, volume_option_t *opt)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
uint64_t value = 0;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_ASSERT(opt);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (gf_string2bytesize_uint64(sizestr, &value) != 0 || value < opt->min ||
|
|
Packit |
b2c0d9 |
value % 512) {
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
gf_msg_debug(THIS->name, 0, "Returning %d", ret);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
gf_validate_number(const char *numstr, volume_option_t *opt)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int32_t value;
|
|
Packit |
b2c0d9 |
return gf_string2int32(numstr, &value);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Parses the string to be of the form <key1>:<value1>,<key2>:<value2>... *
|
|
Packit |
b2c0d9 |
* takes two optional validaters key_validator and value_validator */
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
validate_list_elements(const char *string, volume_option_t *opt,
|
|
Packit |
b2c0d9 |
int(key_validator)(const char *),
|
|
Packit |
b2c0d9 |
int(value_validator)(const char *, volume_option_t *))
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
char *dup_string = NULL;
|
|
Packit |
b2c0d9 |
char *str_sav = NULL;
|
|
Packit |
b2c0d9 |
char *substr_sav = NULL;
|
|
Packit |
b2c0d9 |
char *str_ptr = NULL;
|
|
Packit |
b2c0d9 |
char *key = NULL;
|
|
Packit |
b2c0d9 |
char *value = NULL;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_ASSERT(string);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
dup_string = gf_strdup(string);
|
|
Packit |
b2c0d9 |
if (NULL == dup_string)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
str_ptr = strtok_r(dup_string, ",", &str_sav);
|
|
Packit |
b2c0d9 |
if (str_ptr == NULL) {
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
while (str_ptr) {
|
|
Packit |
b2c0d9 |
key = strtok_r(str_ptr, ":", &substr_sav);
|
|
Packit |
b2c0d9 |
if (!key || (key_validator && key_validator(key))) {
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY,
|
|
Packit |
b2c0d9 |
"invalid list '%s', key "
|
|
Packit |
b2c0d9 |
"'%s' not valid.",
|
|
Packit |
b2c0d9 |
string, key);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
value = strtok_r(NULL, ":", &substr_sav);
|
|
Packit |
b2c0d9 |
if (!value || (value_validator && value_validator(value, opt))) {
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
gf_msg(THIS->name, GF_LOG_WARNING, 0, LG_MSG_INVALID_ENTRY,
|
|
Packit |
b2c0d9 |
"invalid list '%s', "
|
|
Packit |
b2c0d9 |
"value '%s' not valid.",
|
|
Packit |
b2c0d9 |
string, key);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
str_ptr = strtok_r(NULL, ",", &str_sav);
|
|
Packit |
b2c0d9 |
substr_sav = NULL;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
GF_FREE(dup_string);
|
|
Packit |
b2c0d9 |
gf_msg_debug(THIS->name, 0, "Returning %d", ret);
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_priority_list(xlator_t *xl, const char *key,
|
|
Packit |
b2c0d9 |
const char *value, volume_option_t *opt,
|
|
Packit |
b2c0d9 |
char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
char errstr[1024] = {
|
|
Packit |
b2c0d9 |
0,
|
|
Packit |
b2c0d9 |
};
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_ASSERT(value);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = validate_list_elements(value, opt, NULL, &gf_validate_number);
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 1024,
|
|
Packit |
b2c0d9 |
"option %s %s: '%s' is not a valid "
|
|
Packit |
b2c0d9 |
"priority-list",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_size_list(xlator_t *xl, const char *key,
|
|
Packit |
b2c0d9 |
const char *value, volume_option_t *opt,
|
|
Packit |
b2c0d9 |
char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
char errstr[1024] = {
|
|
Packit |
b2c0d9 |
0,
|
|
Packit |
b2c0d9 |
};
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_ASSERT(value);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = gf_validate_size(value, opt);
|
|
Packit |
b2c0d9 |
if (ret)
|
|
Packit |
b2c0d9 |
ret = validate_list_elements(value, opt, NULL, &gf_validate_size);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
snprintf(errstr, 1024,
|
|
Packit |
b2c0d9 |
"option %s %s: '%s' is not a valid "
|
|
Packit |
b2c0d9 |
"size-list",
|
|
Packit |
b2c0d9 |
key, value, value);
|
|
Packit |
b2c0d9 |
*op_errstr = gf_strdup(errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_option_validate_any(xlator_t *xl, const char *key, const char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
return 0;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
typedef int(xlator_option_validator_t)(xlator_t *xl, const char *key,
|
|
Packit |
b2c0d9 |
const char *value, volume_option_t *opt,
|
|
Packit |
b2c0d9 |
char **operrstr);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_option_validate(xlator_t *xl, char *key, char *value,
|
|
Packit |
b2c0d9 |
volume_option_t *opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
xlator_option_validator_t *validate;
|
|
Packit |
b2c0d9 |
xlator_option_validator_t *validators[] = {
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_PATH] = xlator_option_validate_path,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_INT] = xlator_option_validate_int,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_SIZET] = xlator_option_validate_sizet,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_BOOL] = xlator_option_validate_bool,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_XLATOR] = xlator_option_validate_xlator,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_STR] = xlator_option_validate_str,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_PERCENT] = xlator_option_validate_percent,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_PERCENT_OR_SIZET] =
|
|
Packit |
b2c0d9 |
xlator_option_validate_percent_or_sizet,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_TIME] = xlator_option_validate_time,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_DOUBLE] = xlator_option_validate_double,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_INTERNET_ADDRESS] = xlator_option_validate_addr,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_INTERNET_ADDRESS_LIST] =
|
|
Packit |
b2c0d9 |
xlator_option_validate_addr_list,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_PRIORITY_LIST] = xlator_option_validate_priority_list,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_SIZE_LIST] = xlator_option_validate_size_list,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_ANY] = xlator_option_validate_any,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_CLIENT_AUTH_ADDR] = xlator_option_validate_mntauth,
|
|
Packit |
b2c0d9 |
[GF_OPTION_TYPE_MAX] = NULL,
|
|
Packit |
b2c0d9 |
};
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (opt->type > GF_OPTION_TYPE_MAX) {
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY,
|
|
Packit |
b2c0d9 |
"unknown option type '%d'", opt->type);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
validate = validators[opt->type];
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = validate(xl, key, value, opt, op_errstr);
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
volume_option_t *
|
|
Packit |
b2c0d9 |
xlator_volume_option_get_list(volume_opt_list_t *vol_list, const char *key)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
volume_option_t *opt = NULL;
|
|
Packit |
b2c0d9 |
volume_opt_list_t *opt_list = NULL;
|
|
Packit |
b2c0d9 |
volume_option_t *found = NULL;
|
|
Packit |
b2c0d9 |
int index = 0;
|
|
Packit |
b2c0d9 |
int i = 0;
|
|
Packit |
b2c0d9 |
char *cmp_key = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (!vol_list->given_opt) {
|
|
Packit |
b2c0d9 |
opt_list = list_entry(vol_list->list.next, volume_opt_list_t, list);
|
|
Packit |
b2c0d9 |
opt = opt_list->given_opt;
|
|
Packit |
b2c0d9 |
} else
|
|
Packit |
b2c0d9 |
opt = vol_list->given_opt;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
for (index = 0; opt[index].key[0]; index++) {
|
|
Packit |
b2c0d9 |
for (i = 0; i < ZR_VOLUME_MAX_NUM_KEY; i++) {
|
|
Packit |
b2c0d9 |
cmp_key = opt[index].key[i];
|
|
Packit |
b2c0d9 |
if (!cmp_key)
|
|
Packit |
b2c0d9 |
break;
|
|
Packit |
b2c0d9 |
if (fnmatch(cmp_key, key, FNM_NOESCAPE) == 0) {
|
|
Packit |
b2c0d9 |
found = &opt[index];
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
return found;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
volume_option_t *
|
|
Packit |
b2c0d9 |
xlator_volume_option_get(xlator_t *xl, const char *key)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
volume_opt_list_t *vol_list = NULL;
|
|
Packit |
b2c0d9 |
volume_option_t *found = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
list_for_each_entry(vol_list, &xl->volume_options, list)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
found = xlator_volume_option_get_list(vol_list, key);
|
|
Packit |
b2c0d9 |
if (found)
|
|
Packit |
b2c0d9 |
break;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return found;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xl_opt_validate(dict_t *dict, char *key, data_t *value, void *data)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
xlator_t *xl = NULL;
|
|
Packit |
b2c0d9 |
volume_opt_list_t *vol_opt = NULL;
|
|
Packit |
b2c0d9 |
volume_option_t *opt = NULL;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
char *errstr = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
struct {
|
|
Packit |
b2c0d9 |
xlator_t *this;
|
|
Packit |
b2c0d9 |
volume_opt_list_t *vol_opt;
|
|
Packit |
b2c0d9 |
char *errstr;
|
|
Packit |
b2c0d9 |
} * stub;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
stub = data;
|
|
Packit |
b2c0d9 |
xl = stub->this;
|
|
Packit |
b2c0d9 |
vol_opt = stub->vol_opt;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
opt = xlator_volume_option_get_list(vol_opt, key);
|
|
Packit |
b2c0d9 |
if (!opt)
|
|
Packit |
b2c0d9 |
return 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = xlator_option_validate(xl, key, value->data, opt, &errstr);
|
|
Packit |
b2c0d9 |
if (ret)
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_WARNING, 0, LG_MSG_VALIDATE_RETURNS,
|
|
Packit |
b2c0d9 |
"validate of %s returned %d", key, ret);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (errstr)
|
|
Packit |
b2c0d9 |
/* possible small leak of previously set stub->errstr */
|
|
Packit |
b2c0d9 |
stub->errstr = errstr;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (fnmatch(opt->key[0], key, FNM_NOESCAPE) != 0) {
|
|
Packit |
b2c0d9 |
gf_msg(xl->name, GF_LOG_DEBUG, 0, LG_MSG_INVALID_ENTRY,
|
|
Packit |
b2c0d9 |
"option '%s' is deprecated, preferred is '%s', "
|
|
Packit |
b2c0d9 |
"continuing with correction",
|
|
Packit |
b2c0d9 |
key, opt->key[0]);
|
|
Packit |
b2c0d9 |
dict_set(dict, opt->key[0], value);
|
|
Packit |
b2c0d9 |
dict_del(dict, key);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
return 0;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_options_validate_list(xlator_t *xl, dict_t *options,
|
|
Packit |
b2c0d9 |
volume_opt_list_t *vol_opt, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
struct {
|
|
Packit |
b2c0d9 |
xlator_t *this;
|
|
Packit |
b2c0d9 |
volume_opt_list_t *vol_opt;
|
|
Packit |
b2c0d9 |
char *errstr;
|
|
Packit |
b2c0d9 |
} stub;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
stub.this = xl;
|
|
Packit |
b2c0d9 |
stub.vol_opt = vol_opt;
|
|
Packit |
b2c0d9 |
stub.errstr = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
dict_foreach(options, xl_opt_validate, &stub);
|
|
Packit |
b2c0d9 |
if (stub.errstr) {
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
if (op_errstr)
|
|
Packit |
b2c0d9 |
*op_errstr = stub.errstr;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_options_validate(xlator_t *xl, dict_t *options, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
volume_opt_list_t *vol_opt = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (!xl) {
|
|
Packit |
b2c0d9 |
gf_msg_debug(THIS->name, 0, "'this' not a valid ptr");
|
|
Packit |
b2c0d9 |
ret = -1;
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (list_empty(&xl->volume_options))
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
list_for_each_entry(vol_opt, &xl->volume_options, list)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
ret = xlator_options_validate_list(xl, options, vol_opt, op_errstr);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_validate_rec(xlator_t *xlator, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
xlator_list_t *trav = NULL;
|
|
Packit |
b2c0d9 |
xlator_t *old_THIS = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_VALIDATE_OR_GOTO("xlator", xlator, out);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
trav = xlator->children;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
while (trav) {
|
|
Packit |
b2c0d9 |
if (xlator_validate_rec(trav->xlator, op_errstr)) {
|
|
Packit |
b2c0d9 |
gf_msg("xlator", GF_LOG_WARNING, 0, LG_MSG_VALIDATE_REC_FAILED,
|
|
Packit |
b2c0d9 |
"validate_rec "
|
|
Packit |
b2c0d9 |
"failed");
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
trav = trav->next;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (xlator_dynload(xlator))
|
|
Packit |
b2c0d9 |
gf_msg_debug(xlator->name, 0, "Did not load the symbols");
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
old_THIS = THIS;
|
|
Packit |
b2c0d9 |
THIS = xlator;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
/* Need this here, as this graph has not yet called init() */
|
|
Packit |
b2c0d9 |
if (!xlator->mem_acct) {
|
|
Packit |
b2c0d9 |
if (!xlator->mem_acct_init)
|
|
Packit |
b2c0d9 |
xlator->mem_acct_init = default_mem_acct_init;
|
|
Packit |
b2c0d9 |
xlator->mem_acct_init(xlator);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = xlator_options_validate(xlator, xlator->options, op_errstr);
|
|
Packit |
b2c0d9 |
THIS = old_THIS;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (ret) {
|
|
Packit |
b2c0d9 |
gf_msg(xlator->name, GF_LOG_INFO, 0, LG_MSG_INVALID_ENTRY, "%s",
|
|
Packit |
b2c0d9 |
*op_errstr);
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
gf_msg_debug(xlator->name, 0, "Validated options");
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
graph_reconf_validateopt(glusterfs_graph_t *graph, char **op_errstr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
xlator_t *xlator = NULL;
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_ASSERT(graph);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
xlator = graph->first;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = xlator_validate_rec(xlator, op_errstr);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xlator_reconfigure_rec(xlator_t *old_xl, xlator_t *new_xl)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
xlator_list_t *trav1 = NULL;
|
|
Packit |
b2c0d9 |
xlator_list_t *trav2 = NULL;
|
|
Packit |
b2c0d9 |
int32_t ret = -1;
|
|
Packit |
b2c0d9 |
xlator_t *old_THIS = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_VALIDATE_OR_GOTO("xlator", old_xl, out);
|
|
Packit |
b2c0d9 |
GF_VALIDATE_OR_GOTO("xlator", new_xl, out);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
trav1 = old_xl->children;
|
|
Packit |
b2c0d9 |
trav2 = new_xl->children;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
while (trav1 && trav2) {
|
|
Packit |
b2c0d9 |
ret = xlator_reconfigure_rec(trav1->xlator, trav2->xlator);
|
|
Packit |
b2c0d9 |
if (ret)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
gf_msg_debug(trav1->xlator->name, 0, "reconfigured");
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
trav1 = trav1->next;
|
|
Packit |
b2c0d9 |
trav2 = trav2->next;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (old_xl->reconfigure) {
|
|
Packit |
b2c0d9 |
old_THIS = THIS;
|
|
Packit |
b2c0d9 |
THIS = old_xl;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
xlator_init_lock();
|
|
Packit |
b2c0d9 |
handle_default_options(old_xl, new_xl->options);
|
|
Packit |
b2c0d9 |
ret = old_xl->reconfigure(old_xl, new_xl->options);
|
|
Packit |
b2c0d9 |
xlator_init_unlock();
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
THIS = old_THIS;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (ret)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
} else {
|
|
Packit |
b2c0d9 |
gf_msg_debug(old_xl->name, 0, "No reconfigure() found");
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_tree_reconfigure(xlator_t *old_xl, xlator_t *new_xl)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
xlator_t *new_top = NULL;
|
|
Packit |
b2c0d9 |
xlator_t *old_top = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
GF_ASSERT(old_xl);
|
|
Packit |
b2c0d9 |
GF_ASSERT(new_xl);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
old_top = old_xl;
|
|
Packit |
b2c0d9 |
new_top = new_xl;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
return xlator_reconfigure_rec(old_top, new_top);
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
int
|
|
Packit |
b2c0d9 |
xlator_option_info_list(volume_opt_list_t *list, char *key, char **def_val,
|
|
Packit |
b2c0d9 |
char **descr)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
int ret = -1;
|
|
Packit |
b2c0d9 |
volume_option_t *opt = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
opt = xlator_volume_option_get_list(list, key);
|
|
Packit |
b2c0d9 |
if (!opt)
|
|
Packit |
b2c0d9 |
goto out;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (def_val)
|
|
Packit |
b2c0d9 |
*def_val = opt->default_value;
|
|
Packit |
b2c0d9 |
if (descr)
|
|
Packit |
b2c0d9 |
*descr = opt->description;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
ret = 0;
|
|
Packit |
b2c0d9 |
out:
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
pass(char *in, char **out)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
*out = in;
|
|
Packit |
b2c0d9 |
return 0;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
xl_by_name(char *in, xlator_t **out)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
xlator_t *xl = NULL;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
xl = xlator_search_by_name(THIS, in);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (!xl)
|
|
Packit |
b2c0d9 |
return -1;
|
|
Packit |
b2c0d9 |
*out = xl;
|
|
Packit |
b2c0d9 |
return 0;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
static int
|
|
Packit |
b2c0d9 |
pc_or_size(char *in, double *out)
|
|
Packit |
b2c0d9 |
{
|
|
Packit |
b2c0d9 |
double pc = 0;
|
|
Packit |
b2c0d9 |
int ret = 0;
|
|
Packit |
b2c0d9 |
uint64_t size = 0;
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
if (gf_string2percent(in, &pc) == 0) {
|
|
Packit |
b2c0d9 |
if (pc > 100.0) {
|
|
Packit |
b2c0d9 |
ret = gf_string2bytesize_uint64(in, &size);
|
|
Packit |
b2c0d9 |
if (!ret)
|
|
Packit |
b2c0d9 |
*out = size;
|
|
Packit |
b2c0d9 |
} else {
|
|
Packit |
b2c0d9 |
*out = pc;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
} else {
|
|
Packit |
b2c0d9 |
ret = gf_string2bytesize_uint64(in, &size);
|
|
Packit |
b2c0d9 |
if (!ret)
|
|
Packit |
b2c0d9 |
*out = size;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
return ret;
|
|
Packit |
b2c0d9 |
}
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(char *, str, pass);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(uint64_t, uint64, gf_string2uint64);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(int64_t, int64, gf_string2int64);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(uint32_t, uint32, gf_string2uint32);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(int32_t, int32, gf_string2int32);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(uint64_t, size, gf_string2bytesize_uint64);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(uint64_t, size_uint64, gf_string2bytesize_uint64);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(double, percent, gf_string2percent);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(double, percent_or_size, pc_or_size);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(gf_boolean_t, bool, gf_string2boolean);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(xlator_t *, xlator, xl_by_name);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(char *, path, pass);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(double, double, gf_string2double);
|
|
Packit |
b2c0d9 |
DEFINE_INIT_OPT(uint32_t, time, gf_string2time);
|
|
Packit |
b2c0d9 |
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(char *, str, pass);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(uint64_t, uint64, gf_string2uint64);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(int64_t, int64, gf_string2int64);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(uint32_t, uint32, gf_string2uint32);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(int32_t, int32, gf_string2int32);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(uint64_t, size, gf_string2bytesize_uint64);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(uint64_t, size_uint64, gf_string2bytesize_uint64);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(double, percent, gf_string2percent);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(double, percent_or_size, pc_or_size);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(gf_boolean_t, bool, gf_string2boolean);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(xlator_t *, xlator, xl_by_name);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(char *, path, pass);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(double, double, gf_string2double);
|
|
Packit |
b2c0d9 |
DEFINE_RECONF_OPT(uint32_t, time, gf_string2time);
|