From f807c21242917caf16c780e2eaa28ff54ca69e0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 10 Jul 2018 18:28:01 +0300 Subject: [PATCH] Treat service parameters as module parameters The same mechanism that is used for modules can be used for the configuration of the core objects. This removes the need for the redundant code that validates various values that is already present in the code that modules use. --- include/maxscale/config.h | 1 + server/core/config.cc | 351 ++++++------------ server/core/config_runtime.cc | 6 +- server/core/internal/config.h | 16 +- server/core/internal/service.h | 5 +- server/core/service.cc | 82 ++-- server/core/test/test_config.cc | 6 +- server/core/test/test_service.cc | 4 +- .../routing/binlogrouter/test/testbinlog.cc | 2 +- 9 files changed, 186 insertions(+), 287 deletions(-) diff --git a/include/maxscale/config.h b/include/maxscale/config.h index 3c1868e95..06490ef64 100644 --- a/include/maxscale/config.h +++ b/include/maxscale/config.h @@ -164,6 +164,7 @@ extern const char CN_SERVER[]; extern const char CN_SERVICES[]; extern const char CN_SERVICE[]; extern const char CN_SESSIONS[]; +extern const char CN_SESSION_TRACK_TRX_STATE[]; extern const char CN_SKIP_PERMISSION_CHECKS[]; extern const char CN_SOCKET[]; extern const char CN_STATE[]; diff --git a/server/core/config.cc b/server/core/config.cc index 8f20633bf..98a8f8fee 100644 --- a/server/core/config.cc +++ b/server/core/config.cc @@ -139,6 +139,7 @@ const char CN_SERVER[] = "server"; const char CN_SERVICES[] = "services"; const char CN_SERVICE[] = "service"; const char CN_SESSIONS[] = "sessions"; +const char CN_SESSION_TRACK_TRX_STATE[] = "session_track_trx_state"; const char CN_SKIP_PERMISSION_CHECKS[] = "skip_permission_checks"; const char CN_SOCKET[] = "socket"; const char CN_SQL_MODE[] = "sql_mode"; @@ -162,7 +163,6 @@ const char CN_USERS[] = "users"; const char CN_USERS_REFRESH_TIME[] = "users_refresh_time"; const char CN_VERSION_STRING[] = "version_string"; const char CN_WEIGHTBY[] = "weightby"; -const char CN_SESSION_TRACK_TRX_STATE[] = "session_track_trx_state"; const char CN_WRITEQ_HIGH_WATER[] = "writeq_high_water"; const char CN_WRITEQ_LOW_WATER[] = "writeq_low_water"; @@ -224,103 +224,98 @@ char *version_string = NULL; static bool is_persisted_config = false; /**< True if a persisted configuration file is being parsed */ static CONFIG_CONTEXT config_context; -const char *config_service_params[] = +const MXS_MODULE_PARAM config_service_params[] = { - CN_TYPE, - CN_ROUTER, - CN_ROUTER_OPTIONS, - CN_SERVERS, - CN_MONITOR, - CN_USER, - "passwd", // DEPRECATE: See config_get_password. - CN_PASSWORD, - CN_ENABLE_ROOT_USER, - CN_MAX_RETRY_INTERVAL, - CN_MAX_CONNECTIONS, - "max_queued_connections", //TODO: Fix this - "queued_connection_timeout", // TODO: Fix this - CN_CONNECTION_TIMEOUT, - CN_AUTH_ALL_SERVERS, - CN_STRIP_DB_ESC, - CN_LOCALHOST_MATCH_WILDCARD_HOST, - CN_VERSION_STRING, - CN_FILTERS, - CN_WEIGHTBY, - CN_LOG_AUTH_WARNINGS, - CN_RETRY_ON_FAILURE, - CN_SESSION_TRACK_TRX_STATE, - NULL + {CN_TYPE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_ROUTER, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_ROUTER_OPTIONS, MXS_MODULE_PARAM_STRING}, + {CN_SERVERS, MXS_MODULE_PARAM_STRING}, + {CN_USER, MXS_MODULE_PARAM_STRING}, // Not mandatory due to RCAP_TYPE_NO_AUTH + {CN_PASSWORD, MXS_MODULE_PARAM_STRING}, // Not mandatory due to RCAP_TYPE_NO_AUTH + {CN_ENABLE_ROOT_USER, MXS_MODULE_PARAM_BOOL, "false"}, + {CN_MAX_RETRY_INTERVAL, MXS_MODULE_PARAM_COUNT, "3600"}, + {CN_MAX_CONNECTIONS, MXS_MODULE_PARAM_COUNT, "0"}, + {CN_CONNECTION_TIMEOUT, MXS_MODULE_PARAM_COUNT, "0"}, + {CN_AUTH_ALL_SERVERS, MXS_MODULE_PARAM_BOOL, "false"}, + {CN_STRIP_DB_ESC, MXS_MODULE_PARAM_BOOL, "true"}, + {CN_LOCALHOST_MATCH_WILDCARD_HOST, MXS_MODULE_PARAM_BOOL, "true"}, + {CN_VERSION_STRING, MXS_MODULE_PARAM_STRING}, + {CN_FILTERS, MXS_MODULE_PARAM_STRING}, + {CN_WEIGHTBY, MXS_MODULE_PARAM_STRING}, + {CN_LOG_AUTH_WARNINGS, MXS_MODULE_PARAM_BOOL, "true"}, + {CN_RETRY_ON_FAILURE, MXS_MODULE_PARAM_BOOL, "true"}, + {CN_SESSION_TRACK_TRX_STATE, MXS_MODULE_PARAM_BOOL, "false"}, + {NULL} }; -const char *config_listener_params[] = +const MXS_MODULE_PARAM config_listener_params[] = { - CN_AUTHENTICATOR_OPTIONS, - CN_TYPE, - CN_SERVICE, - CN_PROTOCOL, - CN_PORT, - CN_ADDRESS, - CN_SOCKET, - CN_AUTHENTICATOR, - CN_SSL_CERT, - CN_SSL_CA_CERT, - CN_SSL, - CN_SSL_KEY, - CN_SSL_VERSION, - CN_SSL_CERT_VERIFY_DEPTH, - CN_SSL_VERIFY_PEER_CERTIFICATE, - NULL + {CN_TYPE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_SERVICE, MXS_MODULE_PARAM_SERVICE, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_PORT, MXS_MODULE_PARAM_COUNT}, // Either port or socket, checked when created + {CN_SOCKET, MXS_MODULE_PARAM_STRING}, + {CN_AUTHENTICATOR_OPTIONS, MXS_MODULE_PARAM_STRING}, + {CN_PROTOCOL, MXS_MODULE_PARAM_STRING, "MariaDBClient"}, + {CN_ADDRESS, MXS_MODULE_PARAM_STRING, "::"}, + {CN_AUTHENTICATOR, MXS_MODULE_PARAM_STRING, "MySQLAuth"}, + {CN_SSL, MXS_MODULE_PARAM_STRING}, + {CN_SSL_CERT, MXS_MODULE_PARAM_STRING}, + {CN_SSL_KEY, MXS_MODULE_PARAM_STRING}, + {CN_SSL_CA_CERT, MXS_MODULE_PARAM_STRING}, + {CN_SSL_VERSION, MXS_MODULE_PARAM_STRING}, + {CN_SSL_CERT_VERIFY_DEPTH, MXS_MODULE_PARAM_STRING}, + {CN_SSL_VERIFY_PEER_CERTIFICATE, MXS_MODULE_PARAM_STRING}, + {NULL} }; -const char *config_monitor_params[] = +const MXS_MODULE_PARAM config_monitor_params[] = { - CN_TYPE, - CN_MODULE, - CN_SERVERS, - CN_USER, - "passwd", // DEPRECATE: See config_get_password. - CN_PASSWORD, - CN_SCRIPT, - CN_EVENTS, - CN_MONITOR_INTERVAL, - CN_JOURNAL_MAX_AGE, - CN_SCRIPT_TIMEOUT, - CN_BACKEND_CONNECT_TIMEOUT, - CN_BACKEND_READ_TIMEOUT, - CN_BACKEND_WRITE_TIMEOUT, - CN_BACKEND_CONNECT_ATTEMPTS, - CN_DISK_SPACE_THRESHOLD, - CN_DISK_SPACE_CHECK_INTERVAL, - NULL + {CN_TYPE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_MODULE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_USER, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_PASSWORD, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_SERVERS, MXS_MODULE_PARAM_STRING}, + {CN_SCRIPT, MXS_MODULE_PARAM_STRING}, + {CN_EVENTS, MXS_MODULE_PARAM_STRING}, + {CN_MONITOR_INTERVAL, MXS_MODULE_PARAM_COUNT, "2000"}, + {CN_JOURNAL_MAX_AGE, MXS_MODULE_PARAM_COUNT, "28800"}, + {CN_SCRIPT_TIMEOUT, MXS_MODULE_PARAM_COUNT, "90"}, + {CN_BACKEND_CONNECT_TIMEOUT, MXS_MODULE_PARAM_COUNT, "3"}, + {CN_BACKEND_READ_TIMEOUT, MXS_MODULE_PARAM_COUNT, "1"}, + {CN_BACKEND_WRITE_TIMEOUT, MXS_MODULE_PARAM_COUNT, "2"}, + {CN_BACKEND_CONNECT_ATTEMPTS, MXS_MODULE_PARAM_COUNT, "1"}, + {CN_DISK_SPACE_THRESHOLD, MXS_MODULE_PARAM_STRING}, + {CN_DISK_SPACE_CHECK_INTERVAL, MXS_MODULE_PARAM_COUNT}, + {NULL} }; -const char *config_filter_params[] = +const MXS_MODULE_PARAM config_filter_params[] = { - CN_TYPE, - CN_MODULE, - NULL + {CN_TYPE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_MODULE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {NULL} }; -const char *server_params[] = +const MXS_MODULE_PARAM server_params[] = { - CN_TYPE, - CN_PROTOCOL, - CN_PORT, - CN_ADDRESS, - CN_AUTHENTICATOR, - CN_MONITORUSER, - CN_MONITORPW, - CN_PERSISTPOOLMAX, - CN_PERSISTMAXTIME, - CN_SSL_CERT, - CN_SSL_CA_CERT, - CN_SSL, - CN_SSL_KEY, - CN_SSL_VERSION, - CN_SSL_CERT_VERIFY_DEPTH, - CN_SSL_VERIFY_PEER_CERTIFICATE, - CN_PROXY_PROTOCOL, - NULL + {CN_TYPE, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_ADDRESS, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED}, + {CN_PROTOCOL, MXS_MODULE_PARAM_STRING, "MariaDBBackend"}, + {CN_PORT, MXS_MODULE_PARAM_COUNT, "3306"}, + {CN_AUTHENTICATOR, MXS_MODULE_PARAM_STRING, "MySQLBackendAuth"}, + {CN_MONITORUSER, MXS_MODULE_PARAM_STRING}, + {CN_MONITORPW, MXS_MODULE_PARAM_STRING}, + {CN_PERSISTPOOLMAX, MXS_MODULE_PARAM_COUNT, "0"}, + {CN_PERSISTMAXTIME, MXS_MODULE_PARAM_COUNT, "0"}, + {CN_PROXY_PROTOCOL, MXS_MODULE_PARAM_BOOL, "false"}, + {CN_SSL, MXS_MODULE_PARAM_STRING}, + {CN_SSL_CERT, MXS_MODULE_PARAM_PATH}, + {CN_SSL_KEY, MXS_MODULE_PARAM_PATH}, + {CN_SSL_CA_CERT, MXS_MODULE_PARAM_PATH}, + {CN_SSL_VERSION, MXS_MODULE_PARAM_STRING}, + {CN_SSL_CERT_VERIFY_DEPTH, MXS_MODULE_PARAM_COUNT}, + {CN_SSL_VERIFY_PEER_CERTIFICATE, MXS_MODULE_PARAM_BOOL}, + {NULL} }; /* @@ -2328,7 +2323,8 @@ void config_set_global_defaults() * @return True if at least one of the required parameters is missing */ static bool missing_required_parameters(const MXS_MODULE_PARAM *mod_params, - MXS_CONFIG_PARAMETER *params) + MXS_CONFIG_PARAMETER *params, + const char* name) { bool rval = false; @@ -2339,7 +2335,8 @@ static bool missing_required_parameters(const MXS_MODULE_PARAM *mod_params, if ((mod_params[i].options & MXS_MODULE_OPT_REQUIRED) && config_get_param(params, mod_params[i].name) == NULL) { - MXS_ERROR("Mandatory parameter '%s' is not defined.", mod_params[i].name); + MXS_ERROR("Mandatory parameter '%s' is not defined for '%s'.", + mod_params[i].name, name); rval = true; } } @@ -2424,7 +2421,7 @@ check_config_objects(CONFIG_CONTEXT *context) continue; } - const char **param_set = NULL; + const MXS_MODULE_PARAM* param_set = NULL; const char *module = NULL; const char *type; const char *module_type = NULL; @@ -2464,16 +2461,9 @@ check_config_objects(CONFIG_CONTEXT *context) MXS_CONFIG_PARAMETER *params = obj->parameters; while (params) { - int found = 0; - for (int i = 0; param_set[i]; i++) - { - if (!strcmp(params->name, param_set[i])) - { - found = 1; - } - } + bool ok = config_param_is_valid(param_set, params->name, params->value, context); - if (found == 0) + if (!ok) { if (mod == NULL || !config_param_is_valid(mod->parameters, params->name, params->value, context)) @@ -2505,9 +2495,14 @@ check_config_objects(CONFIG_CONTEXT *context) { config_remove_param(obj, it->c_str()); } + + if (missing_required_parameters(param_set, obj->parameters, obj->object)) + { + rval = false; + } } - if (mod && missing_required_parameters(mod->parameters, obj->parameters)) + if (mod && missing_required_parameters(mod->parameters, obj->parameters, obj->object)) { rval = false; } @@ -2985,13 +2980,13 @@ static json_t* param_value_json(const MXS_CONFIG_PARAMETER* param, } void config_add_module_params_json(const MXS_MODULE* mod, MXS_CONFIG_PARAMETER* parameters, - const char** type_params, json_t* output) + const MXS_MODULE_PARAM* type_params, json_t* output) { set param_set; - for (int i = 0; type_params[i]; i++) + for (int i = 0; type_params[i].name; i++) { - param_set.insert(type_params[i]); + param_set.insert(type_params[i].name); } for (MXS_CONFIG_PARAMETER* p = parameters; p; p = p->next) @@ -3010,149 +3005,39 @@ void config_add_module_params_json(const MXS_MODULE* mod, MXS_CONFIG_PARAMETER* */ int create_new_service(CONFIG_CONTEXT *obj) { - char *router = config_get_value(obj->parameters, CN_ROUTER); - if (router == NULL) - { - obj->element = NULL; - MXS_ERROR("No router defined for service '%s'.", obj->object); - return 1; - } - else if ((obj->element = service_alloc(obj->object, router)) == NULL) - { - MXS_ERROR("Service creation failed."); - return 1; - } - - SERVICE* service = (SERVICE*) obj->element; - int error_count = 0; - MXS_CONFIG_PARAMETER* param; - - char *retry = config_get_value(obj->parameters, CN_RETRY_ON_FAILURE); - if (retry) - { - serviceSetRetryOnFailure(service, retry); - } - - char *enable_root_user = config_get_value(obj->parameters, CN_ENABLE_ROOT_USER); - if (enable_root_user) - { - serviceEnableRootUser(service, config_truth_value(enable_root_user)); - } - - char *max_retry_interval = config_get_value(obj->parameters, CN_MAX_RETRY_INTERVAL); - - if (max_retry_interval) - { - char *endptr; - long val = strtol(max_retry_interval, &endptr, 10); - - if (val && *endptr == '\0') - { - service_set_retry_interval(service, val); - } - else - { - MXS_ERROR("Invalid value for 'max_retry_interval': %s", max_retry_interval); - error_count++; - } - } - - char *connection_timeout = config_get_value(obj->parameters, CN_CONNECTION_TIMEOUT); - if (connection_timeout) - { - serviceSetTimeout(service, atoi(connection_timeout)); - } - - const char *max_connections = config_get_value_string(obj->parameters, CN_MAX_CONNECTIONS); - const char *max_queued_connections = config_get_value_string(obj->parameters, "max_queued_connections"); - const char *queued_connection_timeout = config_get_value_string(obj->parameters, "queued_connection_timeout"); - if (strlen(max_connections)) - { - serviceSetConnectionLimits(service, atoi(max_connections), - atoi(max_queued_connections), atoi(queued_connection_timeout)); - } - - char *auth_all_servers = config_get_value(obj->parameters, CN_AUTH_ALL_SERVERS); - if (auth_all_servers) - { - serviceAuthAllServers(service, config_truth_value(auth_all_servers)); - } - - char *strip_db_esc = config_get_value(obj->parameters, CN_STRIP_DB_ESC); - if (strip_db_esc) - { - serviceStripDbEsc(service, config_truth_value(strip_db_esc)); - } - - char *weightby = config_get_value(obj->parameters, CN_WEIGHTBY); - if (weightby) - { - serviceWeightBy(service, weightby); - } - - char *wildcard = config_get_value(obj->parameters, CN_LOCALHOST_MATCH_WILDCARD_HOST); - if (wildcard) - { - serviceEnableLocalhostMatchWildcardHost(service, config_truth_value(wildcard)); - } + const char *router = config_get_string(obj->parameters, CN_ROUTER); + ss_dassert(*router); char *user = config_get_value(obj->parameters, CN_USER); - char *auth = config_get_password(obj->parameters); + char *auth = config_get_value(obj->parameters, CN_PASSWORD); + const MXS_MODULE* module = get_module(router, MODULE_ROUTER); + ss_dassert(module); - if (user && auth) + if ((!user || !auth) && + !rcap_type_required(module->module_capabilities, RCAP_TYPE_NO_AUTH)) { - serviceSetUser(service, user, auth); - } - else if (!rcap_type_required(service_get_capabilities(service), RCAP_TYPE_NO_AUTH)) - { - error_count++; - MXS_ERROR("Service '%s' is missing %s%s%s.", - obj->object, + MXS_ERROR("Service '%s' is missing %s%s%s.", obj->object, user ? "" : "the 'user' parameter", !user && !auth ? " and " : "", - auth ? "" : "the 'password' or 'passwd' parameter"); + auth ? "" : "the 'password' parameter"); + return 1; } - char *log_auth_warnings = config_get_value(obj->parameters, CN_LOG_AUTH_WARNINGS); - if (log_auth_warnings) + config_add_defaults(obj, config_service_params); + config_add_defaults(obj, module->parameters); + + SERVICE* service = service_alloc(obj->object, router, obj->parameters); + + if (service) { - int truthval = config_truth_value(log_auth_warnings); - if (truthval != -1) - { - service->log_auth_warnings = (bool) truthval; - } - else - { - MXS_ERROR("Invalid value for 'log_auth_warnings': %s", log_auth_warnings); - } + obj->element = service; } - - char *version_string = config_get_value(obj->parameters, CN_VERSION_STRING); - if (version_string) + else { - /** Add the 5.5.5- string to the start of the version string if - * the version string starts with "10.". - * This mimics MariaDB 10.0 replication which adds 5.5.5- for backwards compatibility. */ - if (version_string[0] != '5') - { - size_t len = strlen(version_string) + strlen("5.5.5-") + 1; - char ver[len]; - snprintf(ver, sizeof(ver), "5.5.5-%s", version_string); - serviceSetVersionString(service, ver); - } - else - { - serviceSetVersionString(service, version_string); - } - } - else if (gateway.version_string) - { - serviceSetVersionString(service, gateway.version_string); + MXS_ERROR("Service creation failed."); } - service->session_track_trx_state = config_get_bool(obj->parameters, CN_SESSION_TRACK_TRX_STATE); - - return error_count; + return service ? 0 : 1; } /** @@ -3162,9 +3047,9 @@ int create_new_service(CONFIG_CONTEXT *obj) */ bool is_normal_server_parameter(const char *param) { - for (int i = 0; server_params[i]; i++) + for (int i = 0; server_params[i].name; i++) { - if (strcmp(param, server_params[i]) == 0) + if (strcmp(param, server_params[i].name) == 0) { return true; } diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index fe43999fd..63f033ec7 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -1808,11 +1808,11 @@ bool runtime_alter_service_from_json(SERVICE* service, json_t* new_json) { /** Create a set of accepted service parameters */ StringSet paramset; - for (int i = 0; config_service_params[i]; i++) + for (int i = 0; config_service_params[i].name; i++) { - if (is_dynamic_param(config_service_params[i])) + if (is_dynamic_param(config_service_params[i].name)) { - paramset.insert(config_service_params[i]); + paramset.insert(config_service_params[i].name); } } diff --git a/server/core/internal/config.h b/server/core/internal/config.h index 7060f38ec..26d3e5b12 100644 --- a/server/core/internal/config.h +++ b/server/core/internal/config.h @@ -39,13 +39,13 @@ enum MAX_PARAM_LEN = 256 }; -/** Object type specific parameter name lists */ -extern const char *config_service_params[]; -extern const char *config_listener_params[]; -extern const char *config_monitor_params[]; -extern const char *config_filter_params[]; -extern const char *config_server_params[]; -extern const char *config_pre_parse_global_params[]; +/** Object type specific parameter lists */ +extern const MXS_MODULE_PARAM config_service_params[]; +extern const MXS_MODULE_PARAM config_listener_params[]; +extern const MXS_MODULE_PARAM config_monitor_params[]; +extern const MXS_MODULE_PARAM config_filter_params[]; +extern const MXS_MODULE_PARAM config_server_params[]; +extern const char* config_pre_parse_global_params[]; /** * Initialize the configuration subsystem @@ -167,7 +167,7 @@ bool config_have_required_ssl_params(CONFIG_CONTEXT *obj); */ void config_add_module_params_json(const MXS_MODULE* mod, MXS_CONFIG_PARAMETER* parameters, - const char** type_params, + const MXS_MODULE_PARAM* type_params, json_t* output); /** diff --git a/server/core/internal/service.h b/server/core/internal/service.h index 7b436e0fa..d9fddff18 100644 --- a/server/core/internal/service.h +++ b/server/core/internal/service.h @@ -29,12 +29,13 @@ MXS_BEGIN_DECLS /** * @brief Allocate a new service * - * @param name The service name + * @param name The service name * @param router The router module this service uses + * @param params Service parameters * * @return The newly created service or NULL if an error occurred */ -SERVICE* service_alloc(const char *name, const char *router); +SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETER* params); /** * @brief Shut all services down diff --git a/server/core/service.cc b/server/core/service.cc index eda5b94bd..dd6d0fb75 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -75,8 +75,16 @@ static SERVICE *allServices = NULL; static bool service_internal_restart(void *data); static void service_calculate_weights(SERVICE *service); -SERVICE* service_alloc(const char *name, const char *router) +SERVICE* service_alloc(const char *name, const char *router, MXS_CONFIG_PARAMETER* params) { + MXS_ROUTER_OBJECT* router_api = (MXS_ROUTER_OBJECT*)load_module(router, MODULE_ROUTER); + + if (router_api == NULL) + { + MXS_ERROR("Unable to load router module '%s'", router); + return NULL; + } + char *my_name = MXS_STRDUP(name); char *my_router = MXS_STRDUP(router); SERVICE *service = (SERVICE *)MXS_CALLOC(1, sizeof(*service)); @@ -91,59 +99,63 @@ SERVICE* service_alloc(const char *name, const char *router) return NULL; } - if ((service->router = (MXS_ROUTER_OBJECT*)load_module(my_router, MODULE_ROUTER)) == NULL) - { - char* home = get_libdir(); - char* ldpath = getenv("LD_LIBRARY_PATH"); - - MXS_ERROR("Unable to load %s module \"%s\".\n\t\t\t" - " Ensure that lib%s.so exists in one of the " - "following directories :\n\t\t\t " - "- %s\n%s%s", - MODULE_ROUTER, - my_router, - my_router, - home, - ldpath ? "\t\t\t - " : "", - ldpath ? ldpath : ""); - MXS_FREE(my_name); - MXS_FREE(my_router); - MXS_FREE(service); - MXS_FREE(rate_limits); - return NULL; - } - const MXS_MODULE* module = get_module(my_router, MODULE_ROUTER); ss_dassert(module); + service->router = router_api; service->capabilities = module->module_capabilities; - service->max_retry_interval = SERVICE_MAX_RETRY_INTERVAL; service->client_count = 0; service->n_dbref = 0; service->name = my_name; service->routerModule = my_router; - service->users_from_all = false; - service->localhost_match_wildcard_host = SERVICE_PARAM_UNINIT; - service->retry_start = true; - service->conn_idle_timeout = SERVICE_NO_SESSION_TIMEOUT; service->svc_config_param = NULL; - service->log_auth_warnings = true; - service->strip_db_esc = true; service->rate_limits = rate_limits; service->stats.started = time(0); service->stats.n_failed_starts = 0; service->state = SERVICE_STATE_ALLOC; spinlock_init(&service->spin); - // Load router default parameters - for (int i = 0; module->parameters[i].name; i++) + service->max_retry_interval = config_get_integer(params, CN_MAX_RETRY_INTERVAL); + service->users_from_all = config_get_bool(params, CN_AUTH_ALL_SERVERS); + service->localhost_match_wildcard_host = config_get_bool(params, CN_LOCALHOST_MATCH_WILDCARD_HOST); + service->retry_start = config_get_bool(params, CN_RETRY_ON_FAILURE); + service->enable_root = config_get_bool(params, CN_ENABLE_ROOT_USER); + service->conn_idle_timeout = config_get_integer(params, CN_CONNECTION_TIMEOUT); + service->max_connections = config_get_integer(params, CN_MAX_CONNECTIONS); + service->log_auth_warnings = config_get_bool(params, CN_LOG_AUTH_WARNINGS); + service->strip_db_esc = config_get_bool(params, CN_STRIP_DB_ESC); + service->session_track_trx_state = config_get_bool(params, CN_SESSION_TRACK_TRX_STATE); + + serviceWeightBy(service, config_get_string(params, CN_WEIGHTBY)); + serviceSetUser(service, config_get_string(params, CN_USER), + config_get_string(params, CN_PASSWORD)); + + std::string version_string = config_get_string(params, CN_VERSION_STRING); + + if (!version_string.empty()) { - if (module->parameters[i].default_value) + /** Add the 5.5.5- string to the start of the version string if + * the version string starts with "10.". + * This mimics MariaDB 10.0 replication which adds 5.5.5- for backwards compatibility. */ + if (version_string[0] != '5') { - service_add_parameter(service, module->parameters[i].name, - module->parameters[i].default_value); + version_string = "5.5.5-" + version_string; } + + serviceSetVersionString(service, version_string.c_str()); } + else if (config_get_global_options()->version_string) + { + serviceSetVersionString(service, config_get_global_options()->version_string); + } + + if (service->conn_idle_timeout) + { + dcb_enable_session_timeouts(); + } + + // Store parameters in the service + service_add_parameters(service, params); spinlock_acquire(&service_spin); service->next = allServices; diff --git a/server/core/test/test_config.cc b/server/core/test/test_config.cc index 1ab57fc50..c6585eee5 100644 --- a/server/core/test/test_config.cc +++ b/server/core/test/test_config.cc @@ -202,9 +202,9 @@ int test_required_parameters() CONFIG_CONTEXT ctx = {}; ctx.object = (char*)""; - TEST(missing_required_parameters(params, ctx.parameters)); + TEST(missing_required_parameters(params, ctx.parameters, "test")); config_add_defaults(&ctx, params); - TEST(!missing_required_parameters(params, ctx.parameters)); + TEST(!missing_required_parameters(params, ctx.parameters, "test")); config_parameter_free(ctx.parameters); ctx.parameters = NULL; @@ -212,7 +212,7 @@ int test_required_parameters() config_add_param(&ctx, "p1", "1"); config_add_param(&ctx, "p2", "1"); config_add_param(&ctx, "p3", "1"); - TEST(!missing_required_parameters(params, ctx.parameters)); + TEST(!missing_required_parameters(params, ctx.parameters, "test")); config_parameter_free(ctx.parameters); return 0; } diff --git a/server/core/test/test_service.cc b/server/core/test/test_service.cc index 0043fe7dc..eee959fc9 100644 --- a/server/core/test/test_service.cc +++ b/server/core/test/test_service.cc @@ -58,12 +58,12 @@ test1() /* Service tests */ ss_dfprintf(stderr, "testservice : creating service called MyService with router nonexistent"); - service = service_alloc("MyService", "non-existent"); + service = service_alloc("MyService", "non-existent", NULL); ss_info_dassert(NULL == service, "New service with invalid router should be null"); ss_info_dassert(0 == service_isvalid(service), "Service must not be valid after incorrect creation"); ss_dfprintf(stderr, "\t..done\nValid service creation, router testroute."); set_libdir(MXS_STRDUP_A("../../modules/routing/readconnroute/")); - service = service_alloc("MyService", "readconnroute"); + service = service_alloc("MyService", "readconnroute", NULL); ss_info_dassert(NULL != service, "New service with valid router must not be null"); ss_info_dassert(0 != service_isvalid(service), "Service must be valid after creation"); diff --git a/server/modules/routing/binlogrouter/test/testbinlog.cc b/server/modules/routing/binlogrouter/test/testbinlog.cc index f9262ecf3..7e00bb81c 100644 --- a/server/modules/routing/binlogrouter/test/testbinlog.cc +++ b/server/modules/routing/binlogrouter/test/testbinlog.cc @@ -107,7 +107,7 @@ int main(int argc, char **argv) set_libdir(MXS_STRDUP_A("../../../authenticator/MySQLBackendAuth/")); load_module("MySQLBackendAuth", MODULE_AUTHENTICATOR); - if ((service = service_alloc("test_service", "binlogrouter")) == NULL) + if ((service = service_alloc("test_service", "binlogrouter", NULL)) == NULL) { printf("Failed to allocate 'service' object\n"); return 1;