MXS-1468: Fix created monitor serialization
When servers were added to monitors that were created at runtime, the server list serialization overwrote the original persisted configuration of the monitor. To solve this problem, the serialization of the server list and the monitor parameters were combined.
This commit is contained in:
@ -45,7 +45,7 @@ bool runtime_link_server(SERVER *server, const char *target)
|
||||
{
|
||||
if (monitorAddServer(monitor, server))
|
||||
{
|
||||
monitor_serialize_servers(monitor);
|
||||
monitor_serialize(monitor);
|
||||
rval = true;
|
||||
}
|
||||
}
|
||||
@ -80,7 +80,7 @@ bool runtime_unlink_server(SERVER *server, const char *target)
|
||||
else if (monitor)
|
||||
{
|
||||
monitorRemoveServer(monitor, server);
|
||||
monitor_serialize_servers(monitor);
|
||||
monitor_serialize(monitor);
|
||||
}
|
||||
|
||||
const char *type = service ? "service" : "monitor";
|
||||
|
@ -1266,52 +1266,6 @@ MXS_MONITOR* monitor_server_in_use(const SERVER *server)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a monitor configuration at the location pointed by @c filename
|
||||
*
|
||||
* @param monitor Monitor to serialize into a configuration
|
||||
* @param filename Filename where configuration is written
|
||||
* @return True on success, false on error
|
||||
*/
|
||||
static bool create_monitor_server_config(const MXS_MONITOR *monitor, const char *filename)
|
||||
{
|
||||
int file = open(filename, O_EXCL | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
if (file == -1)
|
||||
{
|
||||
char errbuf[MXS_STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to open file '%s' when serializing monitor '%s': %d, %s",
|
||||
filename, monitor->name, errno, strerror_r(errno, errbuf, sizeof(errbuf)));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Only additional parameters are added to the configuration. This prevents
|
||||
* duplication or addition of parameters that don't support it.
|
||||
*
|
||||
* TODO: Check for return values on all of the dprintf calls
|
||||
*/
|
||||
dprintf(file, "[%s]\n", monitor->name);
|
||||
|
||||
if (monitor->databases)
|
||||
{
|
||||
dprintf(file, "servers=");
|
||||
for (MXS_MONITOR_SERVERS *db = monitor->databases; db; db = db->next)
|
||||
{
|
||||
if (db != monitor->databases)
|
||||
{
|
||||
dprintf(file, ",");
|
||||
}
|
||||
dprintf(file, "%s", db->server->unique_name);
|
||||
}
|
||||
dprintf(file, "\n");
|
||||
}
|
||||
|
||||
close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool create_monitor_config(const MXS_MONITOR *monitor, const char *filename)
|
||||
{
|
||||
int file = open(filename, O_EXCL | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
@ -1331,56 +1285,38 @@ static bool create_monitor_config(const MXS_MONITOR *monitor, const char *filena
|
||||
* TODO: Check for return values on all of the dprintf calls
|
||||
*/
|
||||
dprintf(file, "[%s]\n", monitor->name);
|
||||
dprintf(file, "type=monitor\n");
|
||||
dprintf(file, "module=%s\n", monitor->module_name);
|
||||
dprintf(file, "user=%s\n", monitor->user);
|
||||
dprintf(file, "password=%s\n", monitor->password);
|
||||
dprintf(file, "monitor_interval=%lu\n", monitor->interval);
|
||||
dprintf(file, "backend_connect_timeout=%d\n", monitor->connect_timeout);
|
||||
dprintf(file, "backend_write_timeout=%d\n", monitor->write_timeout);
|
||||
dprintf(file, "backend_read_timeout=%d\n", monitor->read_timeout);
|
||||
|
||||
if (monitor->created_online)
|
||||
{
|
||||
dprintf(file, "type=monitor\n");
|
||||
dprintf(file, "module=%s\n", monitor->module_name);
|
||||
dprintf(file, "user=%s\n", monitor->user);
|
||||
dprintf(file, "password=%s\n", monitor->password);
|
||||
dprintf(file, "monitor_interval=%lu\n", monitor->interval);
|
||||
dprintf(file, "backend_connect_timeout=%d\n", monitor->connect_timeout);
|
||||
dprintf(file, "backend_write_timeout=%d\n", monitor->write_timeout);
|
||||
dprintf(file, "backend_read_timeout=%d\n", monitor->read_timeout);
|
||||
}
|
||||
|
||||
if (monitor->databases)
|
||||
{
|
||||
dprintf(file, "servers=");
|
||||
for (MXS_MONITOR_SERVERS *db = monitor->databases; db; db = db->next)
|
||||
{
|
||||
if (db != monitor->databases)
|
||||
{
|
||||
dprintf(file, ",");
|
||||
}
|
||||
dprintf(file, "%s", db->server->unique_name);
|
||||
}
|
||||
dprintf(file, "\n");
|
||||
}
|
||||
|
||||
close(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool monitor_serialize_servers(const MXS_MONITOR *monitor)
|
||||
{
|
||||
bool rval = false;
|
||||
char filename[PATH_MAX];
|
||||
snprintf(filename, sizeof(filename), "%s/%s.cnf.tmp", get_config_persistdir(),
|
||||
monitor->name);
|
||||
|
||||
if (unlink(filename) == -1 && errno != ENOENT)
|
||||
{
|
||||
char err[MXS_STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to remove temporary monitor configuration at '%s': %d, %s",
|
||||
filename, errno, strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
else if (create_monitor_server_config(monitor, filename))
|
||||
{
|
||||
char final_filename[PATH_MAX];
|
||||
strcpy(final_filename, filename);
|
||||
|
||||
char *dot = strrchr(final_filename, '.');
|
||||
ss_dassert(dot);
|
||||
*dot = '\0';
|
||||
|
||||
if (rename(filename, final_filename) == 0)
|
||||
{
|
||||
rval = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
char err[MXS_STRERROR_BUFLEN];
|
||||
MXS_ERROR("Failed to rename temporary monitor configuration at '%s': %d, %s",
|
||||
filename, errno, strerror_r(errno, err, sizeof(err)));
|
||||
}
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
bool monitor_serialize(const MXS_MONITOR *monitor)
|
||||
{
|
||||
bool rval = false;
|
||||
|
Reference in New Issue
Block a user