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:
		@ -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)
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user