From eac6d239fc63256833c03f4f6a069fbff4b9d2a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 11 Oct 2017 11:30:58 +0300 Subject: [PATCH] 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. --- server/core/config_runtime.c | 4 +- server/core/monitor.c | 118 ++++++++--------------------------- 2 files changed, 29 insertions(+), 93 deletions(-) diff --git a/server/core/config_runtime.c b/server/core/config_runtime.c index 6aacc7522..0a963f887 100644 --- a/server/core/config_runtime.c +++ b/server/core/config_runtime.c @@ -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"; diff --git a/server/core/monitor.c b/server/core/monitor.c index 2c71d8f58..975fae18f 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -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;