Handle server repurposing under a lock

By moving the repurposing of the servers under the global server lock, the
repurposing of a server and allocation of a new server behave in the same
way.

Also fixed the wrong error message on server creation failure referring to
invalid server relationships.
This commit is contained in:
Markus Mäkelä
2017-08-04 11:24:54 +03:00
parent e133e758a6
commit 1743f4c1b7
3 changed files with 36 additions and 34 deletions

View File

@ -132,7 +132,6 @@ typedef struct server
int persistmax; /**< Maximum pool size actually achieved since startup */ int persistmax; /**< Maximum pool size actually achieved since startup */
uint8_t charset; /**< Default server character set */ uint8_t charset; /**< Default server character set */
bool is_active; /**< Server is active and has not been "destroyed" */ bool is_active; /**< Server is active and has not been "destroyed" */
bool created_online; /**< Whether this server was created after startup */
bool proxy_protocol; /**< Send proxy-protocol header to backend when connecting client sessions. */ bool proxy_protocol; /**< Send proxy-protocol header to backend when connecting client sessions. */
#if defined(SS_DEBUG) #if defined(SS_DEBUG)
skygw_chk_t server_chk_tail; skygw_chk_t server_chk_tail;
@ -258,12 +257,16 @@ extern SERVER* server_alloc(const char *name, const char *address, unsigned shor
* @param protocol Protocol used by the server * @param protocol Protocol used by the server
* @param authenticator The authenticator module of the server * @param authenticator The authenticator module of the server
* @param auth_options Options for the authenticator * @param auth_options Options for the authenticator
* @return Reusable SERVER or NULL if no servers matching the criteria were * @param address The network address of the new server
* @param port The port of the new server
*
* @return Repurposed SERVER or NULL if no servers matching the criteria were
* found * found
* @see runtime_create_server * @see runtime_create_server
*/ */
SERVER* server_find_destroyed(const char *name, const char *protocol, SERVER* server_repurpose_destroyed(const char *name, const char *protocol,
const char *authenticator, const char *auth_options); const char *authenticator, const char *auth_options,
const char *address, const char *port);
/** /**
* @brief Serialize a server to a file * @brief Serialize a server to a file
* *

View File

@ -161,36 +161,30 @@ bool runtime_create_server(const char *name, const char *address, const char *po
} }
/** First check if this service has been created before */ /** First check if this service has been created before */
SERVER *server = server_find_destroyed(name, protocol, authenticator, SERVER *server = server_repurpose_destroyed(name, protocol, authenticator,
authenticator_options); authenticator_options,
address, port);
if (server) if (server)
{ {
/** Found old server, replace network details with new ones and MXS_DEBUG("Reusing server '%s'", name);
* reactivate it */
snprintf(server->name, sizeof(server->name), "%s", address);
server->port = atoi(port);
server->is_active = true;
rval = true;
} }
else else
{ {
/** MXS_DEBUG("Creating server '%s'", name);
* server_alloc will add the server to the global list of
* servers so we don't need to manually add it.
*/
server = server_alloc(name, address, atoi(port), protocol, server = server_alloc(name, address, atoi(port), protocol,
authenticator, authenticator_options); authenticator, authenticator_options);
} }
if (server && server_serialize(server)) if (server && server_serialize(server))
{ {
/** Mark that the server was created after startup */ rval = true;
server->created_online = true;
MXS_NOTICE("Created server '%s' at %s:%u", server->unique_name, MXS_NOTICE("Created server '%s' at %s:%u", server->unique_name,
server->name, server->port); server->name, server->port);
rval = true; }
else
{
runtime_error("Failed to create server '%s', see error log for more details", name);
} }
} }
else else
@ -1160,8 +1154,9 @@ SERVER* runtime_create_server_from_json(json_t* json)
set<string> relations; set<string> relations;
if (extract_relations(json, relations, server_relation_types, server_relation_is_valid) && if (extract_relations(json, relations, server_relation_types, server_relation_is_valid))
runtime_create_server(name, address, port.c_str(), protocol, authenticator, authenticator_options)) {
if (runtime_create_server(name, address, port.c_str(), protocol, authenticator, authenticator_options))
{ {
rval = server_find_by_unique_name(name); rval = server_find_by_unique_name(name);
ss_dassert(rval); ss_dassert(rval);
@ -1172,6 +1167,7 @@ SERVER* runtime_create_server_from_json(json_t* json)
rval = NULL; rval = NULL;
} }
} }
}
else else
{ {
runtime_error("Invalid relationships in request JSON"); runtime_error("Invalid relationships in request JSON");

View File

@ -139,7 +139,6 @@ SERVER* server_alloc(const char *name, const char *address, unsigned short port,
server->monuser[0] = '\0'; server->monuser[0] = '\0';
server->monpw[0] = '\0'; server->monpw[0] = '\0';
server->is_active = true; server->is_active = true;
server->created_online = false;
server->charset = SERVER_DEFAULT_CHARSET; server->charset = SERVER_DEFAULT_CHARSET;
server->proxy_protocol = false; server->proxy_protocol = false;
@ -1281,8 +1280,9 @@ bool server_serialize(const SERVER *server)
return rval; return rval;
} }
SERVER* server_find_destroyed(const char *name, const char *protocol, SERVER* server_repurpose_destroyed(const char *name, const char *protocol,
const char *authenticator, const char *auth_options) const char *authenticator, const char *auth_options,
const char *address, const char *port)
{ {
spinlock_acquire(&server_spin); spinlock_acquire(&server_spin);
SERVER *server = allServers; SERVER *server = allServers;
@ -1297,6 +1297,9 @@ SERVER* server_find_destroyed(const char *name, const char *protocol,
(auth_options && server->auth_options && (auth_options && server->auth_options &&
strcmp(server->auth_options, auth_options) == 0)) strcmp(server->auth_options, auth_options) == 0))
{ {
snprintf(server->name, sizeof(server->name), "%s", address);
server->port = atoi(port);
server->is_active = true;
break; break;
} }
} }