Improve persisted configuration handling

When a persisted configuration file is read, the values in it are
considered to be more up-to-date than the ones in the main configuration
file. This allows all objects to be persisted in a more complete form
making it easier to change configuration values at runtime.

This change is intended to help make runtime alterations to services
possible.
This commit is contained in:
Markus Mäkelä
2017-04-25 15:51:55 +03:00
parent b736776c8f
commit f7fefad2e6
7 changed files with 116 additions and 117 deletions

View File

@ -1273,51 +1273,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)
{
MXS_ERROR("Failed to open file '%s' when serializing monitor '%s': %d, %s",
filename, monitor->name, errno, mxs_strerror(errno));
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, "%s=", CN_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);
@ -1346,46 +1301,25 @@ static bool create_monitor_config(const MXS_MONITOR *monitor, const char *filena
dprintf(file, "%s=%d\n", CN_BACKEND_READ_TIMEOUT, monitor->read_timeout);
dprintf(file, "%s=%d\n", CN_BACKEND_CONNECT_ATTEMPTS, monitor->connect_attempts);
if (monitor->databases)
{
dprintf(file, "%s=", CN_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)
{
MXS_ERROR("Failed to remove temporary monitor configuration at '%s': %d, %s",
filename, errno, mxs_strerror(errno));
}
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
{
MXS_ERROR("Failed to rename temporary monitor configuration at '%s': %d, %s",
filename, errno, mxs_strerror(errno));
}
}
return rval;
}
bool monitor_serialize(const MXS_MONITOR *monitor)
{
bool rval = false;