From 35d295939531b020a7e1e8f6b3d846bbffac98e9 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 9 Nov 2016 05:59:10 +0200 Subject: [PATCH] Enable online modification of servers The address, port, monuser and monpw parameters of an existing server can be changed at runtime. The support for enabling SSL will come in a later commit. Allowing servers to be modified could also be done by destroying and recreating them. Since the servers are never actually destroyed, it is better to allow the alteration of the existing ones. --- include/maxscale/server.h | 12 +++-- server/core/config.c | 3 +- server/core/server.c | 51 +++++++++------------ server/modules/monitor/mysqlmon/mysql_mon.c | 7 +-- server/modules/routing/debugcli/debugcmd.c | 51 +++++++++++++++++++++ 5 files changed, 83 insertions(+), 41 deletions(-) diff --git a/include/maxscale/server.h b/include/maxscale/server.h index 45be5cd39..a67199fe2 100644 --- a/include/maxscale/server.h +++ b/include/maxscale/server.h @@ -48,6 +48,8 @@ MXS_BEGIN_DECLS #define MAX_SERVER_NAME_LEN 1024 +#define MAX_SERVER_MONUSER_LEN 512 +#define MAX_SERVER_MONPW_LEN 512 #define MAX_NUM_SLAVES 128 /**< Maximum number of slaves under a single server*/ /** @@ -86,7 +88,7 @@ typedef struct server #endif SPINLOCK lock; /**< Common access lock */ char *unique_name; /**< Unique name for the server */ - char *name; /**< Server name/IP address*/ + char name[MAX_SERVER_NAME_LEN]; /**< Server name/IP address*/ unsigned short port; /**< Port to listen on */ char *protocol; /**< Protocol module to use */ char *authenticator; /**< Authenticator module name */ @@ -94,8 +96,8 @@ typedef struct server char *auth_options; /**< Authenticator options */ SSL_LISTENER *server_ssl; /**< SSL data structure for server, if any */ unsigned int status; /**< Status flag bitmap for the server */ - char *monuser; /**< User name to use to monitor the db */ - char *monpw; /**< Password to use to monitor the db */ + char monuser[MAX_SERVER_MONUSER_LEN]; /**< User name to use to monitor the db */ + char monpw[MAX_SERVER_MONPW_LEN]; /**< Password to use to monitor the db */ SERVER_STATS stats; /**< The server statistics */ struct server *next; /**< Next server */ struct server *nextdb; /**< Next server in list attached to a service */ @@ -217,7 +219,7 @@ 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(SERVER *, char *, char *, char *); +extern void server_update_credentials(SERVER *, char *, char *); extern void server_set_unique_name(SERVER *, char *); extern DCB *server_get_persistent(SERVER *, char *, const char *); extern void server_update_address(SERVER *, char *); @@ -225,6 +227,8 @@ extern void server_update_port(SERVER *, unsigned short); extern RESULTSET *serverGetList(); extern unsigned int server_map_status(char *str); extern bool server_set_version_string(SERVER* server, const char* string); +extern bool server_is_ssl_parameter(const char *key); +extern void server_update_ssl(SERVER *server, const char *key, const char *value); /** * @brief Serialize a server to a file diff --git a/server/core/config.c b/server/core/config.c index 31c550b9a..fed157b28 100644 --- a/server/core/config.c +++ b/server/core/config.c @@ -1800,10 +1800,9 @@ process_config_update(CONFIG_CONTEXT *context) if (address && port && (server = server_find(address, atoi(port))) != NULL) { - char *protocol = config_get_value(obj->parameters, "protocol"); char *monuser = config_get_value(obj->parameters, "monuser"); char *monpw = config_get_value(obj->parameters, "monpw"); - server_update(server, protocol, monuser, monpw); + server_update_credentials(server, monuser, monpw); obj->element = server; } else diff --git a/server/core/server.c b/server/core/server.c index 1350bec49..749bc49d3 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -95,12 +95,11 @@ server_alloc(char *servname, char *protocol, unsigned short port, char *authenti return NULL; } - servname = MXS_STRNDUP(servname, MAX_SERVER_NAME_LEN); protocol = MXS_STRDUP(protocol); SERVER *server = (SERVER *)MXS_CALLOC(1, sizeof(SERVER)); - if (!servname || !protocol || !server || !authenticator) + if (!protocol || !server || !authenticator) { MXS_FREE(servname); MXS_FREE(protocol); @@ -113,7 +112,7 @@ server_alloc(char *servname, char *protocol, unsigned short port, char *authenti server->server_chk_top = CHK_NUM_SERVER; server->server_chk_tail = CHK_NUM_SERVER; #endif - server->name = servname; + snprintf(server->name, sizeof(server->name), "%s", servname); server->protocol = protocol; server->authenticator = authenticator; server->auth_instance = auth_instance; @@ -131,6 +130,8 @@ server_alloc(char *servname, char *protocol, unsigned short port, char *authenti server->persistmax = 0; server->persistmaxtime = 0; server->persistpoolmax = 0; + server->monuser[0] = '\0'; + server->monpw[0] = '\0'; spinlock_init(&server->persistlock); spinlock_acquire(&server_spin); @@ -785,8 +786,8 @@ server_transfer_status(SERVER *dest_server, SERVER *source_server) void serverAddMonUser(SERVER *server, char *user, char *passwd) { - server->monuser = MXS_STRDUP_A(user); - server->monpw = MXS_STRDUP_A(passwd); + snprintf(server->monuser, sizeof(server->monuser), "%s", user); + snprintf(server->monpw, sizeof(server->monpw), "%s", passwd); } /** @@ -803,28 +804,13 @@ serverAddMonUser(SERVER *server, char *user, char *passwd) * @param passwd The password to use for the monitor user */ void -server_update(SERVER *server, char *protocol, char *user, char *passwd) +server_update_credentials(SERVER *server, char *user, char *passwd) { - if (!strcmp(server->protocol, protocol)) - { - MXS_NOTICE("Update server protocol for server %s to protocol %s.", - server->name, - protocol); - MXS_FREE(server->protocol); - server->protocol = MXS_STRDUP_A(protocol); - } - if (user != NULL && passwd != NULL) { - if (strcmp(server->monuser, user) == 0 || - strcmp(server->monpw, passwd) == 0) - { - MXS_NOTICE("Update server monitor credentials for server %s", - server->name); - MXS_FREE(server->monuser); - MXS_FREE(server->monpw); - serverAddMonUser(server, user, passwd); - } + snprintf(server->monuser, sizeof(server->monuser), "%s", user); + snprintf(server->monpw, sizeof(server->monpw), "%s", passwd); + MXS_NOTICE("Updated monitor credentials for server '%s'", server->name); } } @@ -989,11 +975,7 @@ server_update_address(SERVER *server, char *address) spinlock_acquire(&server_spin); if (server && address) { - if (server->name) - { - MXS_FREE(server->name); - } - server->name = MXS_STRDUP_A(address); + strcpy(server->name, address); } spinlock_release(&server_spin); } @@ -1180,3 +1162,14 @@ bool server_serialize(SERVER *server, const char *filename) return true; } + +bool server_is_ssl_parameter(const char *key) +{ + // TODO: Implement this + return false; +} + +void server_update_ssl(SERVER *server, const char *key, const char *value) +{ + // TODO: Implement this +} diff --git a/server/modules/monitor/mysqlmon/mysql_mon.c b/server/modules/monitor/mysqlmon/mysql_mon.c index cc2b425df..5eb0e72b1 100644 --- a/server/modules/monitor/mysqlmon/mysql_mon.c +++ b/server/modules/monitor/mysqlmon/mysql_mon.c @@ -692,12 +692,7 @@ monitorDatabase(MONITOR *mon, MONITOR_SERVERS *database) unsigned long int server_version = 0; char *server_string; - if (database->server->monuser != NULL) - { - uname = database->server->monuser; - } - - if (uname == NULL) + if (!database->server->monuser[0]) { return; } diff --git a/server/modules/routing/debugcli/debugcmd.c b/server/modules/routing/debugcli/debugcmd.c index 973b72258..61a36ceb1 100644 --- a/server/modules/routing/debugcli/debugcmd.c +++ b/server/modules/routing/debugcli/debugcmd.c @@ -1063,6 +1063,56 @@ struct subcommand destroyoptions[] = } }; +static void alterServer(DCB *dcb, SERVER *server, char *key, char *value) +{ + bool unknown = false; + + if (strcmp(key, "address") == 0) + { + server_update_address(server, value); + } + else if (strcmp(key, "port") == 0) + { + server_update_port(server, atoi(value)); + } + else if (strcmp(key, "monuser") == 0) + { + server_update_credentials(server, value, server->monpw); + } + else if (strcmp(key, "monpw") == 0) + { + server_update_credentials(server, server->monuser, value); + } + else if (server_is_ssl_parameter(key)) + { + server_update_ssl(server, key, value); + } + else + { + unknown = true; + } + + if (unknown) + { + dcb_printf(dcb, "Unknown parameter '%s'", key); + } +} + +struct subcommand alteroptions[] = +{ + { + "server", 3, 3, alterServer, + "Alter server parameters", + "Usage: alter server NAME KEY VALUE\n" + "This will alter an existing parameter of a server. The accepted values\n" + "for KEY are: 'address', 'port', 'monuser', 'monpw'", + {ARG_TYPE_SERVER, ARG_TYPE_STRING, ARG_TYPE_STRING} + }, + { + EMPTY_OPTION + } +}; + /** * The debug command table */ @@ -1076,6 +1126,7 @@ static struct { "remove", removeoptions }, { "create", createoptions }, { "destroy", destroyoptions }, + { "alter", alteroptions }, { "set", setoptions }, { "clear", clearoptions }, { "disable", disableoptions },