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.
This commit is contained in:
Markus Makela 2016-11-09 05:59:10 +02:00
parent b51af51365
commit 35d2959395
5 changed files with 83 additions and 41 deletions

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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;
}

View File

@ -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 },