From cefc253e2c822dc75d93be9af9ba5173c1611b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 4 Jan 2017 10:37:46 +0200 Subject: [PATCH] Check configuration with declared parameters The declared parameters are now used to check whether the configuration is valid. As the filters and monitors don't use the new declarations, the code needs to be commented out. Once the parameter processing has been migrated to the new system, the code can be enabled. --- include/maxscale/config.h | 3 +- include/maxscale/modules.h | 3 +- server/core/config.c | 81 ++++++++++++++++++++++---------------- server/core/load_utils.c | 8 +++- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 928cbe619..33ddad35f 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -220,12 +220,13 @@ SSL_LISTENER *make_ssl_structure(CONFIG_CONTEXT *obj, bool require_cert, int *er * does preliminary type checking for various basic values as well as enumerations. * * @param module Module name + * @param type Module type * @param key Parameter key * @param value Parameter value * * @return True if the configuration parameter is valid */ -bool config_param_is_valid(const char *module, const char *key, const char *value); +bool config_param_is_valid(const char *module, const char *type, const char *key, const char *value); /** * @brief Get a boolean value diff --git a/include/maxscale/modules.h b/include/maxscale/modules.h index e919bec09..caab326a6 100644 --- a/include/maxscale/modules.h +++ b/include/maxscale/modules.h @@ -63,9 +63,10 @@ void *load_module(const char *module, const char *type); * @brief Get a module * * @param name Name of the module + * @param type The module type * @return The loaded module or NULL if the module is not loaded */ -const MXS_MODULE *get_module(const char *name); +const MXS_MODULE *get_module(const char *name, const char *type); /** * @brief Unload a module. diff --git a/server/core/config.c b/server/core/config.c index 45004a8a0..b72812b98 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -108,7 +108,7 @@ static FEEDBACK_CONF feedback; char *version_string = NULL; static bool is_persisted_config = false; /**< True if a persisted configuration file is being parsed */ -static char *service_params[] = +static const char *service_params[] = { "type", "router", @@ -140,7 +140,7 @@ static char *service_params[] = NULL }; -static char *listener_params[] = +static const char *listener_params[] = { "authenticator_options", "type", @@ -159,7 +159,7 @@ static char *listener_params[] = NULL }; -static char *monitor_params[] = +static const char *monitor_params[] = { "type", "module", @@ -169,25 +169,21 @@ static char *monitor_params[] = "password", "script", "events", - "mysql51_replication", "monitor_interval", - "detect_replication_lag", - "detect_stale_master", - "disable_master_failback", "backend_connect_timeout", "backend_read_timeout", "backend_write_timeout", - "available_when_donor", - "disable_master_role_setting", - "root_node_as_master", - "use_priority", - "multimaster", - "failover", - "failcount", NULL }; -static char *server_params[] = +static const char *filter_params[] = +{ + "type", + "module", + NULL +}; + +static const char *server_params[] = { "type", "protocol", @@ -1926,20 +1922,23 @@ process_config_update(CONFIG_CONTEXT *context) static bool check_config_objects(CONFIG_CONTEXT *context) { - CONFIG_CONTEXT *obj; - CONFIG_PARAMETER *params; - char *type, **param_set; - bool rval = true; + bool rval = true; + CONFIG_CONTEXT *obj = context; - obj = context; while (obj) { - param_set = NULL; + const char **param_set = NULL; + const char *module = NULL; + const char *type; + const char *module_type = NULL; + if (obj->parameters && (type = config_get_value(obj->parameters, "type"))) { if (!strcmp(type, "service")) { param_set = service_params; + module = config_get_value(obj->parameters, "router"); + module_type = MODULE_ROUTER; } else if (!strcmp(type, "listener")) { @@ -1947,13 +1946,23 @@ check_config_objects(CONFIG_CONTEXT *context) } else if (!strcmp(type, "monitor")) { - param_set = monitor_params; + // TODO: Declare monitor parameters + //param_set = monitor_params; + //module = config_get_value(obj->parameters, "module"); + //module_type = MODULE_MONITOR; + } + else if (!strcmp(type, "filter")) + { + // TODO: Declare filter parameters + //param_set = filter_params; + //module = config_get_value(obj->parameters, "module"); + //module_type = MODULE_FILTER; } } if (param_set != NULL) { - params = obj->parameters; + CONFIG_PARAMETER *params = obj->parameters; while (params) { int found = 0; @@ -1967,9 +1976,13 @@ check_config_objects(CONFIG_CONTEXT *context) if (found == 0) { - MXS_ERROR("Unexpected parameter '%s' for object '%s' of type '%s'.", - params->name, obj->object, type); - rval = false; + if (module == NULL || + !config_param_is_valid(module, module_type, params->name, params->value)) + { + MXS_ERROR("Unexpected parameter '%s' for object '%s' of type '%s'.", + params->name, obj->object, type); + rval = false; + } } params = params->next; } @@ -2608,15 +2621,15 @@ static int validate_ssl_parameters(CONFIG_CONTEXT* obj, char *ssl_cert, char *ss * @param ctx Configuration context where the default parameters are added * @param module Name of the module */ -static void config_add_defaults(CONFIG_CONTEXT *ctx, const char *module) +static void config_add_defaults(CONFIG_CONTEXT *ctx, const char *module, const char *type) { - const MXS_MODULE *mod = get_module(module); + const MXS_MODULE *mod = get_module(module, type); if (mod) { for (int i = 0; mod->parameters[i].name; i++) { - ss_dassert(config_param_is_valid(module, mod->parameters[i].name, + ss_dassert(config_param_is_valid(module, type, mod->parameters[i].name, mod->parameters[i].default_value)); bool rv = config_add_param(ctx, mod->parameters[i].name, @@ -2824,7 +2837,7 @@ int create_new_service(CONFIG_CONTEXT *obj) } /** Store the configuration parameters for the service */ - config_add_defaults(obj, router); + config_add_defaults(obj, router, MODULE_ROUTER); service_add_parameters(obj->element, obj->parameters); return error_count; @@ -3055,7 +3068,7 @@ int create_new_monitor(CONFIG_CONTEXT *context, CONFIG_CONTEXT *obj, HASHTABLE* if (error_count == 0) { - config_add_defaults(obj, module); + config_add_defaults(obj, module, MODULE_MONITOR); monitorAddParameters(obj->element, obj->parameters); char *interval_str = config_get_value(obj->parameters, "monitor_interval"); @@ -3268,7 +3281,7 @@ int create_new_filter(CONFIG_CONTEXT *obj) } } - config_add_defaults(obj, module); + config_add_defaults(obj, module, MODULE_FILTER); CONFIG_PARAMETER *params = obj->parameters; while (params) @@ -3331,10 +3344,10 @@ bool config_is_ssl_parameter(const char *key) return false; } -bool config_param_is_valid(const char *module, const char *key, const char *value) +bool config_param_is_valid(const char *module, const char *type, const char *key, const char *value) { bool valid = false; - const MXS_MODULE *mod = get_module(module); + const MXS_MODULE *mod = get_module(module, type); if (mod) { diff --git a/server/core/load_utils.c b/server/core/load_utils.c index 4c8597064..ccbdb18e1 100644 --- a/server/core/load_utils.c +++ b/server/core/load_utils.c @@ -838,8 +838,14 @@ cleanup: return ret_code; } -const MXS_MODULE *get_module(const char *name) +const MXS_MODULE *get_module(const char *name, const char *type) { LOADED_MODULE *mod = find_module(name); + + if (mod == NULL && load_module(name, type)) + { + mod = find_module(name); + } + return mod ? mod->info : NULL; }