From 261f5fdc36c36b7f3b938328830ac6d04d9a07bc Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 10 Nov 2016 13:47:41 +0200 Subject: [PATCH] Enable destruction of servers The servers can now be destroyed which removes them from the list of active servers. If the server was not created at runtime, a warning is logged. --- include/maxscale/monitor.h | 7 +++++++ include/maxscale/server.h | 9 +++++++++ include/maxscale/service.h | 7 +++++++ server/core/monitor.c | 26 ++++++++++++++++++++++++++ server/core/server.c | 35 +++++++++++++++++++++++++++++++++++ server/core/service.c | 26 ++++++++++++++++++++++++++ 6 files changed, 110 insertions(+) diff --git a/include/maxscale/monitor.h b/include/maxscale/monitor.h index d5ca21740..55e795922 100644 --- a/include/maxscale/monitor.h +++ b/include/maxscale/monitor.h @@ -233,4 +233,11 @@ connect_result_t mon_connect_to_db(MONITOR* mon, MONITOR_SERVERS *database); void mon_log_connect_error(MONITOR_SERVERS* database, connect_result_t rval); void mon_log_state_change(MONITOR_SERVERS *ptr); +/** + * Check if a monitor uses @c servers + * @param server Server that is queried + * @return True if server is used by at least one monitor + */ +bool monitor_server_in_use(const SERVER *server); + MXS_END_DECLS diff --git a/include/maxscale/server.h b/include/maxscale/server.h index b1ee105e3..7575ab127 100644 --- a/include/maxscale/server.h +++ b/include/maxscale/server.h @@ -243,4 +243,13 @@ extern void server_update_ssl(SERVER *server, const char *key, const char *value */ bool server_serialize(SERVER *server); +/** + * @brief Destroy a server + * + * This removes any created server configuration files and marks the server removed + * If the server is not in use. + * @param server Server to destroy + */ +void server_destroy(SERVER *server); + MXS_END_DECLS diff --git a/include/maxscale/service.h b/include/maxscale/service.h index b4bdfe637..9fce33362 100644 --- a/include/maxscale/service.h +++ b/include/maxscale/service.h @@ -257,4 +257,11 @@ static inline uint64_t service_get_capabilities(const SERVICE *service) return service->capabilities; } +/** + * Check if a service uses @c servers + * @param server Server that is queried + * @return True if server is used by at least one service + */ +bool service_server_in_use(const SERVER *server); + MXS_END_DECLS diff --git a/server/core/monitor.c b/server/core/monitor.c index 9df8401ff..978c45a70 100644 --- a/server/core/monitor.c +++ b/server/core/monitor.c @@ -1130,3 +1130,29 @@ void mon_log_state_change(MONITOR_SERVERS *ptr) MXS_FREE(prev); MXS_FREE(next); } + +bool monitor_server_in_use(const SERVER *server) +{ + bool rval = false; + + spinlock_acquire(&monLock); + + for (MONITOR *mon = allMonitors; mon && !rval; mon = mon->next) + { + spinlock_acquire(&mon->lock); + + for (MONITOR_SERVERS *db = mon->databases; db && !rval; db = db->next) + { + if (db->server == server) + { + rval = true; + } + } + + spinlock_release(&mon->lock); + } + + spinlock_release(&monLock); + + return rval; +} diff --git a/server/core/server.c b/server/core/server.c index cc3e878b9..baa5cf48f 100644 --- a/server/core/server.c +++ b/server/core/server.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include #include @@ -1240,6 +1242,39 @@ bool server_serialize(SERVER *server) return rval; } +void server_destroy(SERVER *server) +{ + if (service_server_in_use(server) || monitor_server_in_use(server)) + { + MXS_ERROR("Cannot destroy server '%s' as it is used by at least one " + "service or monitor", server->unique_name); + } + else + { + char filename[PATH_MAX]; + snprintf(filename, sizeof(filename), "%s/%s.cnf", get_config_persistdir(), + server->unique_name); + + if (unlink(filename) == -1) + { + if (errno != ENOENT) + { + char err[MXS_STRERROR_BUFLEN]; + MXS_ERROR("Failed to remove persisted server configuration '%s': %d, %s", + filename, errno, strerror_r(errno, err, sizeof(err))); + } + else + { + MXS_WARNING("Server '%s' was not created at runtime. Remove the " + "server manually from the correct configuration file.", + server->unique_name); + } + } + + server->is_active = false; + } +} + bool server_is_ssl_parameter(const char *key) { // TODO: Implement this diff --git a/server/core/service.c b/server/core/service.c index 942bc3e42..bd4e6dccf 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -2188,3 +2188,29 @@ static void service_calculate_weights(SERVICE *service) } } } + +bool service_server_in_use(const SERVER *server) +{ + bool rval = false; + + spinlock_acquire(&service_spin); + + for (SERVICE *service = allServices; service && !rval; service = service->next) + { + spinlock_acquire(&service->spin); + + for (SERVER_REF *ref = service->dbref; ref && !rval; ref = ref->next) + { + if (ref->server == server) + { + rval = true; + } + } + + spinlock_release(&service->spin); + } + + spinlock_release(&service_spin); + + return rval; +}