diff --git a/include/maxscale/server.h b/include/maxscale/server.h index 9a71f9209..4820ea9d1 100644 --- a/include/maxscale/server.h +++ b/include/maxscale/server.h @@ -60,6 +60,7 @@ typedef struct server_params { char *name; /**< Parameter name */ char *value; /**< Parameter value */ + bool active; /**< Whether the parameter is valid */ struct server_params *next; /**< Next Paramter in the linked list */ } SERVER_PARAM; @@ -254,6 +255,24 @@ SERVER* server_find_destroyed(const char *name, const char *protocol, */ bool server_serialize(const SERVER *server); +/** + * @brief Add a server parameter + * + * @param server Server where the parameter is added + * @param name Parameter name + * @param value Parameter value + */ +void serverAddParameter(SERVER *server, const char *name, const char *value); + +/** + * @brief Remove a server parameter + * + * @param server Server to remove the parameter from + * @param name The name of the parameter to remove + * @return True if a parameter was removed + */ +bool serverRemoveParameter(SERVER *server, const char *name); + extern int server_free(SERVER *); extern SERVER *server_find_by_unique_name(const char *name); extern SERVER *server_find(char *, unsigned short); @@ -270,7 +289,6 @@ extern void server_set_status_nolock(SERVER *, int); extern void server_clear_status_nolock(SERVER *, int); extern void server_transfer_status(SERVER *dest_server, SERVER *source_server); extern void serverAddMonUser(SERVER *, char *, char *); -extern void serverAddParameter(SERVER *, char *, char *); extern char *serverGetParameter(SERVER *, char *); extern void server_update_credentials(SERVER *, char *, char *); extern DCB *server_get_persistent(SERVER *, char *, const char *, int); diff --git a/server/core/config_runtime.c b/server/core/config_runtime.c index 17216a3a9..515c349ec 100644 --- a/server/core/config_runtime.c +++ b/server/core/config_runtime.c @@ -286,7 +286,20 @@ bool runtime_alter_server(SERVER *server, char *key, char *value) } else { - valid = false; + if (!serverRemoveParameter(server, key) && !value[0]) + { + valid = false; + } + else if (value[0]) + { + serverAddParameter(server, key, value); + + /** + * It's likely that this parameter is used as a weighting parameter. + * We need to update the weights of services that use this. + */ + service_update_weights(); + } } if (valid) diff --git a/server/core/maxscale/service.h b/server/core/maxscale/service.h index 71788c7b1..535efa24f 100644 --- a/server/core/maxscale/service.h +++ b/server/core/maxscale/service.h @@ -109,6 +109,9 @@ int service_isvalid(SERVICE *service); */ bool service_server_in_use(const SERVER *server); +/** Update the server weights used by services */ +void service_update_weights(); + /** * Alteration of the service configuration */ diff --git a/server/core/server.c b/server/core/server.c index 7565b583f..32e2faf67 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -545,7 +545,11 @@ dprintServer(DCB *dcb, SERVER *server) dcb_printf(dcb, "\tServer Parameters:\n"); while (param) { - dcb_printf(dcb, "\t %s\t%s\n", param->name, param->value); + if (param->active) + { + dcb_printf(dcb, "\t %s\t%s\n", + param->name, param->value); + } param = param->next; } } @@ -854,26 +858,48 @@ server_update_credentials(SERVER *server, char *user, char *passwd) * @param name The parameter name * @param value The parameter value */ -void -serverAddParameter(SERVER *server, char *name, char *value) +void serverAddParameter(SERVER *server, const char *name, const char *value) { - name = MXS_STRDUP(name); - value = MXS_STRDUP(value); + char *my_name = MXS_STRDUP(name); + char *my_value = MXS_STRDUP(value); SERVER_PARAM *param = (SERVER_PARAM *)MXS_MALLOC(sizeof(SERVER_PARAM)); - if (!name || !value || !param) + if (!my_name || !my_value || !param) { - MXS_FREE(name); - MXS_FREE(value); + MXS_FREE(my_name); + MXS_FREE(my_value); MXS_FREE(param); return; } - param->name = name; - param->value = value; + param->active = true; + param->name = my_name; + param->value = my_value; + + spinlock_acquire(&server->lock); param->next = server->parameters; server->parameters = param; + spinlock_release(&server->lock); +} + +bool serverRemoveParameter(SERVER *server, const char *name) +{ + bool rval = false; + spinlock_acquire(&server->lock); + + for (SERVER_PARAM *p = server->parameters; p; p = p->next) + { + if (strcmp(p->name, name) == 0 && p->active) + { + p->active = false; + rval = true; + break; + } + } + + spinlock_release(&server->lock); + return rval; } /** @@ -908,7 +934,7 @@ serverGetParameter(SERVER *server, char *name) while (param) { - if (strcmp(param->name, name) == 0) + if (strcmp(param->name, name) == 0 && param->active) { return param->value; } @@ -1142,6 +1168,14 @@ static bool create_server_config(const SERVER *server, const char *filename) dprintf(file, "persistmaxtime=%ld\n", server->persistmaxtime); } + for (SERVER_PARAM *p = server->parameters; p; p = p->next) + { + if (p->active) + { + dprintf(file, "%s=%s\n", p->name, p->value); + } + } + if (server->server_ssl) { dprintf(file, "ssl=required\n"); diff --git a/server/core/service.c b/server/core/service.c index 9ad99e101..4dafcb6f1 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -2271,7 +2271,7 @@ static void service_calculate_weights(SERVICE *service) if (perc == 0) { - MXS_ERROR("Weighting parameter '%s' with a value of %d for" + MXS_WARNING("Weighting parameter '%s' with a value of %d for" " server '%s' rounds down to zero with total weight" " of %d for service '%s'. No queries will be " "routed to this server as long as a server with" @@ -2300,6 +2300,18 @@ static void service_calculate_weights(SERVICE *service) } } +void service_update_weights() +{ + spinlock_acquire(&service_spin); + + for (SERVICE *service = allServices; service; service = service->next) + { + service_calculate_weights(service); + } + + spinlock_release(&service_spin); +} + bool service_server_in_use(const SERVER *server) { bool rval = false;