MXS-1847: Make server parameter updates atomic

The updates to server parameters are now performed in an atomic manner.
This commit is contained in:
Markus Mäkelä
2018-05-02 23:19:07 +03:00
parent 612b4e1a32
commit 42c468ff16
3 changed files with 64 additions and 20 deletions

View File

@ -311,6 +311,15 @@ void server_add_parameter(SERVER *server, const char *name, const char *value);
*/ */
bool server_remove_parameter(SERVER *server, const char *name); bool server_remove_parameter(SERVER *server, const char *name);
/**
* @brief Update server parameter
*
* @param server Server to update
* @param name Parameter to update
* @param value New value of parameter
*/
void server_update_parameter(SERVER *server, const char *name, const char *value);
/** /**
* @brief Check if a server points to a local MaxScale service * @brief Check if a server points to a local MaxScale service
* *

View File

@ -385,14 +385,14 @@ bool runtime_alter_server(SERVER *server, const char *key, const char *value)
} }
else else
{ {
if (!server_remove_parameter(server, key) && !value[0]) if (!value[0] && !server_remove_parameter(server, key))
{ {
// Not a valid parameter // Not a valid parameter
} }
else if (value[0]) else if (value[0])
{ {
valid = true; valid = true;
server_add_parameter(server, key, value); server_update_parameter(server, key, value);
/** /**
* It's likely that this parameter is used as a weighting parameter. * It's likely that this parameter is used as a weighting parameter.

View File

@ -848,6 +848,27 @@ server_update_credentials(SERVER *server, const char *user, const char *passwd)
} }
} }
static SERVER_PARAM* allocate_parameter(const char* name, const char* value)
{
char *my_name = MXS_STRDUP(name);
char *my_value = MXS_STRDUP(value);
SERVER_PARAM *param = (SERVER_PARAM *)MXS_MALLOC(sizeof(SERVER_PARAM));
if (!my_name || !my_value || !param)
{
MXS_FREE(my_name);
MXS_FREE(my_value);
MXS_FREE(param);
return NULL;
}
param->active = true;
param->name = my_name;
param->value = my_value;
return param;
}
/** /**
* Add a server parameter to a server. * Add a server parameter to a server.
@ -861,27 +882,15 @@ server_update_credentials(SERVER *server, const char *user, const char *passwd)
*/ */
void server_add_parameter(SERVER *server, const char *name, const char *value) void server_add_parameter(SERVER *server, const char *name, const char *value)
{ {
char *my_name = MXS_STRDUP(name); SERVER_PARAM* param = allocate_parameter(name, value);
char *my_value = MXS_STRDUP(value);
SERVER_PARAM *param = (SERVER_PARAM *)MXS_MALLOC(sizeof(SERVER_PARAM)); if (param)
if (!my_name || !my_value || !param)
{ {
MXS_FREE(my_name);
MXS_FREE(my_value);
MXS_FREE(param);
return;
}
param->active = true;
param->name = my_name;
param->value = my_value;
spinlock_acquire(&server->lock); spinlock_acquire(&server->lock);
param->next = server->parameters; param->next = server->parameters;
server->parameters = param; server->parameters = param;
spinlock_release(&server->lock); spinlock_release(&server->lock);
}
} }
bool server_remove_parameter(SERVER *server, const char *name) bool server_remove_parameter(SERVER *server, const char *name)
@ -903,6 +912,32 @@ bool server_remove_parameter(SERVER *server, const char *name)
return rval; return rval;
} }
void server_update_parameter(SERVER *server, const char *name, const char *value)
{
SERVER_PARAM* param = allocate_parameter(name, value);
if (param)
{
spinlock_acquire(&server->lock);
// Insert new value
param->next = server->parameters;
server->parameters = param;
// Mark old value, if found, as inactive
for (SERVER_PARAM *p = server->parameters->next; p; p = p->next)
{
if (strcmp(p->name, name) == 0 && p->active)
{
p->active = false;
break;
}
}
spinlock_release(&server->lock);
}
}
/** /**
* Free a list of server parameters * Free a list of server parameters
* @param tofree Parameter list to free * @param tofree Parameter list to free