MXS-1929: Factor out parameter validation

The parameter validation for all module types follows roughly the same
path: first check whether it's a known parameter and then whether the
value is valid. This can be moved into common functions that removes
duplicated code.
This commit is contained in:
Markus Mäkelä 2018-08-18 18:11:25 +03:00
parent 20994351ef
commit 0a0623003e
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19

View File

@ -397,6 +397,29 @@ static inline bool is_valid_integer(const char* value)
return strtol(value, &endptr, 10) >= 0 && *value && *endptr == '\0';
}
bool param_is_known(const MXS_MODULE_PARAM* basic, const MXS_MODULE_PARAM* module,
const char* key)
{
std::unordered_set<std::string> names;
for (auto param : {basic, module})
{
for (int i = 0; param[i].name; i++)
{
names.insert(param[i].name);
}
}
return names.count(key);
}
bool param_is_valid(const MXS_MODULE_PARAM* basic, const MXS_MODULE_PARAM* module,
const char* key, const char* value)
{
return config_param_is_valid(basic, key, value, NULL) ||
config_param_is_valid(module, key, value, NULL);
}
bool runtime_alter_server(SERVER *server, const char *key, const char *value)
{
if (!value[0])
@ -405,6 +428,16 @@ bool runtime_alter_server(SERVER *server, const char *key, const char *value)
return false;
}
const MXS_MODULE* mod = get_module(server->protocol, MODULE_PROTOCOL);
// As servers allow unknown parameters, we must only validate known parameters
if (param_is_known(config_server_params, mod->parameters, key) &&
!param_is_valid(config_server_params, mod->parameters, key, value))
{
config_runtime_error("Invalid value for parameter '%s': %s", key, value);
return false;
}
mxs::SpinLockGuard guard(crt_lock);
server_update_parameter(server, key, value);
@ -456,19 +489,37 @@ bool runtime_alter_server(SERVER *server, const char *key, const char *value)
return true;
}
bool runtime_alter_monitor(MXS_MONITOR *monitor, const char *key, const char *value)
bool validate_param(const MXS_MODULE_PARAM* basic, const MXS_MODULE_PARAM* module,
const char* key, const char* value)
{
const MXS_MODULE *mod = get_module(monitor->module_name, MODULE_MONITOR);
bool rval = false;
if (!config_param_is_valid(config_monitor_params, key, value, NULL) &&
!config_param_is_valid(mod->parameters, key, value, NULL))
if (!param_is_known(basic, module, key))
{
config_runtime_error("Invalid monitor parameter: %s", key);
return false;
config_runtime_error("Unknown parameter: %s", key);
}
else if (!value[0])
{
config_runtime_error("Empty value for parameter: %s", key);
}
else if (!param_is_valid(basic, module, key, value))
{
config_runtime_error("Invalid parameter value for '%s': %s", key, value);
}
else
{
rval = true;
}
return rval;
}
bool runtime_alter_monitor(MXS_MONITOR *monitor, const char *key, const char *value)
{
const MXS_MODULE *mod = get_module(monitor->module_name, MODULE_MONITOR);
if (!validate_param(config_monitor_params, mod->parameters, key, value))
{
return false;
}
@ -553,17 +604,9 @@ bool runtime_alter_monitor(MXS_MONITOR *monitor, const char *key, const char *va
bool runtime_alter_service(Service *service, const char* zKey, const char* zValue)
{
const MXS_MODULE* mod = get_module(service->routerModule, MODULE_ROUTER);
ss_dassert(mod);
if (!config_param_is_valid(config_service_params, zKey, zValue, NULL) &&
!config_param_is_valid(mod->parameters, zKey, zValue, NULL))
if (!validate_param(config_service_params, mod->parameters, zKey, zValue))
{
config_runtime_error("Invalid service parameter: %s", zKey);
return false;
}
else if (!zValue[0])
{
config_runtime_error("Empty value for parameter: %s", zKey);
return false;
}