MXS-2314 Prevent removal of servers from clustered services

If the servers of a service are defined by a monitor, then it must
not be possible to dynamically add or remove servers from the
service.
This commit is contained in:
Johan Wikman 2019-02-06 16:26:04 +02:00
parent b4eb87dfcc
commit 0e3ec06c5b
2 changed files with 39 additions and 11 deletions

View File

@ -141,16 +141,26 @@ bool runtime_link_server(Server* server, const char* target)
if (service)
{
if (serviceAddBackend(service, server))
if (!service->uses_cluster())
{
service_serialize(service);
rval = true;
if (serviceAddBackend(service, server))
{
service_serialize(service);
rval = true;
}
else
{
config_runtime_error("Service '%s' already uses server '%s'",
service->name,
server->name());
}
}
else
{
config_runtime_error("Service '%s' already uses server '%s'",
config_runtime_error("The servers of the service '%s' are defined by the monitor '%s'. "
"Servers cannot explicitly be added to the service.",
service->name,
server->name());
service->m_monitor->m_name);
}
}
else if (monitor)
@ -185,21 +195,34 @@ bool runtime_unlink_server(Server* server, const char* target)
if (service || monitor)
{
rval = true;
if (service)
{
serviceRemoveBackend(service, server);
service_serialize(service);
if (!service->uses_cluster())
{
serviceRemoveBackend(service, server);
service_serialize(service);
rval = true;
}
else
{
config_runtime_error("The servers of the service '%s' are defined by the monitor '%s'. "
"Servers cannot explicitly be removed from the service.",
service->name,
service->m_monitor->m_name);
}
}
else if (monitor)
{
monitor_remove_server(monitor, server);
monitor_serialize(monitor);
rval = true;
}
const char* type = service ? "service" : "monitor";
MXS_NOTICE("Removed server '%s' from %s '%s'", server->name(), type, target);
if (rval)
{
const char* type = service ? "service" : "monitor";
MXS_NOTICE("Removed server '%s' from %s '%s'", server->name(), type, target);
}
}
return rval;

View File

@ -108,6 +108,11 @@ public:
// TODO: Make this private.
Monitor* m_monitor { nullptr }; /**< A possibly associated monitor */
bool uses_cluster() const
{
return m_monitor != nullptr;
}
private:
FilterList m_filters; /**< Ordered list of filters */
std::string m_name; /**< Name of the service */