From ae8c21929f4e47f9f80e988cd67726f849d68715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Mon, 19 Dec 2016 18:14:47 +0200 Subject: [PATCH] Serialize server weighting parameters The server weighting parameters couldn't be altered online and they weren't serialized to disk. Only servers that are created online will have their weighting parameters persisted to disk. --- include/maxscale/server.h | 20 +++++++++++- server/core/config_runtime.c | 15 ++++++++- server/core/maxscale/service.h | 3 ++ server/core/server.c | 56 +++++++++++++++++++++++++++------- server/core/service.c | 14 ++++++++- 5 files changed, 94 insertions(+), 14 deletions(-) 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;