Destroy monitor only if it's not used

If a service uses a monitor as the source of its servers, it must not be
destroyed before the monitor is removed from all services that use it.
This commit is contained in:
Markus Mäkelä 2019-04-01 10:46:33 +03:00
parent 84bf241dd1
commit 1417292f0d
No known key found for this signature in database
GPG Key ID: 72D48FCE664F7B19
3 changed files with 43 additions and 10 deletions

View File

@ -1457,21 +1457,30 @@ bool runtime_destroy_service(Service* service)
bool runtime_destroy_monitor(Monitor* monitor)
{
bool rval = false;
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s/%s.cnf", get_config_persistdir(), monitor->m_name);
std::lock_guard<std::mutex> guard(crt_lock);
if (unlink(filename) == -1 && errno != ENOENT)
if (Service* s = service_uses_monitor(monitor))
{
MXS_ERROR("Failed to remove persisted monitor configuration '%s': %d, %s",
filename,
errno,
mxs_strerror(errno));
config_runtime_error("Monitor '%s' cannot be destroyed as it is used by service '%s'",
monitor->m_name, s->name());
}
else
{
rval = true;
char filename[PATH_MAX];
snprintf(filename, sizeof(filename), "%s/%s.cnf", get_config_persistdir(), monitor->m_name);
std::lock_guard<std::mutex> guard(crt_lock);
if (unlink(filename) == -1 && errno != ENOENT)
{
MXS_ERROR("Failed to remove persisted monitor configuration '%s': %d, %s",
filename,
errno,
mxs_strerror(errno));
}
else
{
rval = true;
}
}
if (rval)

View File

@ -347,6 +347,15 @@ bool service_port_is_used(int port);
*/
bool service_has_named_listener(Service* service, const char* name);
/**
* See if a monitor is used by any service
*
* @param monitor Monitor to look for
*
* @return The first service that uses the monitor or nullptr if no service uses it
*/
Service* service_uses_monitor(mxs::Monitor* monitor);
// Required by MaxAdmin
int service_enable_root(Service* service, int action);

View File

@ -840,6 +840,21 @@ Service* service_internal_find(const char* name)
return nullptr;
}
Service* service_uses_monitor(mxs::Monitor* monitor)
{
LockGuard guard(this_unit.lock);
for (Service* s : this_unit.services)
{
if (s->m_monitor == monitor)
{
return s;
}
}
return nullptr;
}
/**
* Return a named service
*