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:
Markus Mäkelä
2017-10-11 11:30:58 +03:00
parent e94dc2aade
commit eac6d239fc
2 changed files with 29 additions and 93 deletions

View File

@ -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";

View File

@ -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,6 +1285,9 @@ 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);
if (monitor->created_online)
{
dprintf(file, "type=monitor\n");
dprintf(file, "module=%s\n", monitor->module_name);
dprintf(file, "user=%s\n", monitor->user);
@ -1339,48 +1296,27 @@ static bool create_monitor_config(const MXS_MONITOR *monitor, const char *filena
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;