From e39242d6e59fcae6bf4b72cdc26fec71c9e61434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Tue, 24 Jul 2018 08:12:45 +0300 Subject: [PATCH] MXS-1929: Add filter deletion entry points Added the code required to delete a filter via the REST API. The actual deleting of the filters is still to be implemented. --- server/core/config_runtime.cc | 20 ++++++++++++++++++++ server/core/filter.cc | 12 ++++++++++++ server/core/internal/config_runtime.h | 11 +++++++++++ server/core/internal/filter.h | 19 +++++++++++++++++++ server/core/internal/service.h | 9 +++++++++ server/core/resource.cc | 13 +++++++++++++ server/core/service.cc | 27 +++++++++++++++++++++++++++ 7 files changed, 111 insertions(+) diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index c6e3af1a5..594bb4cfd 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -1078,6 +1078,26 @@ bool runtime_create_filter(const char *name, const char *module, MXS_CONFIG_PARA return rval; } +bool runtime_destroy_filter(MXS_FILTER_DEF* filter) +{ + ss_dassert(filter); + bool rval = false; + mxs::SpinLockGuard guard(crt_lock); + + if (filter_can_be_destroyed(filter)) + { + filter_destroy(filter); + rval = true; + } + else + { + runtime_error("Filter '%s' cannot be destroyed: Remove it from all services " + "first", filter->name); + } + + return rval; +} + static bool runtime_create_service(const char *name, const char *router, MXS_CONFIG_PARAMETER* params) { mxs::SpinLockGuard guard(crt_lock); diff --git a/server/core/filter.cc b/server/core/filter.cc index e10d01632..29bee12d0 100644 --- a/server/core/filter.cc +++ b/server/core/filter.cc @@ -37,6 +37,7 @@ #include "internal/config.h" #include "internal/modules.h" +#include "internal/service.h" using std::string; using std::set; @@ -152,6 +153,17 @@ filter_def_find(const char *name) return filter; } +bool filter_can_be_destroyed(MXS_FILTER_DEF *filter) +{ + return !service_filter_in_use(filter); +} + +void filter_destroy(MXS_FILTER_DEF *filter) +{ + ss_dassert(filter_can_be_destroyed(filter)); + ss_info_dassert(!true, "Not yet implemented"); +} + const char* filter_def_get_name(const MXS_FILTER_DEF* filter_def) { return filter_def->name; diff --git a/server/core/internal/config_runtime.h b/server/core/internal/config_runtime.h index 6ac49885a..9b7f8ede6 100644 --- a/server/core/internal/config_runtime.h +++ b/server/core/internal/config_runtime.h @@ -205,6 +205,17 @@ bool runtime_create_monitor(const char *name, const char *module); */ bool runtime_create_filter(const char *name, const char *module, MXS_CONFIG_PARAMETER* params); +/** + * Destroy a filter + * + * The filter can only be destroyed if no service uses it + * + * @param service Filter to destroy + * + * @return True if filter was destroyed + */ +bool runtime_destroy_filter(MXS_FILTER_DEF* filter); + /** * @brief Destroy a monitor * diff --git a/server/core/internal/filter.h b/server/core/internal/filter.h index f1fa35234..3b1b168e9 100644 --- a/server/core/internal/filter.h +++ b/server/core/internal/filter.h @@ -46,4 +46,23 @@ MXS_UPSTREAM *filter_upstream(MXS_FILTER_DEF *filter_def, MXS_FILTER_SESSION *fsession, MXS_UPSTREAM *upstream); +/** + * Check if filter can be destroyed + * + * A filter can be destroyed if no service uses it. + * + * @param filter Filter to check + * + * @return True if filter can be destroyed + */ +bool filter_can_be_destroyed(MXS_FILTER_DEF *filter); + +/** + * Destroy a filter + * + * @param filter Filter to destroy + */ +void filter_destroy(MXS_FILTER_DEF *filter); + + MXS_END_DECLS diff --git a/server/core/internal/service.h b/server/core/internal/service.h index 5279e5b3f..6b79a404f 100644 --- a/server/core/internal/service.h +++ b/server/core/internal/service.h @@ -148,6 +148,15 @@ int service_isvalid(SERVICE *service); */ bool service_server_in_use(const SERVER *server); +/** + * Check if filter is used by any service + * + * @param filter Filter to inspect + * + * @return True if at least one service uses the filter + */ +bool service_filter_in_use(const MXS_FILTER_DEF *filter); + /** Update the server weights used by services */ void service_update_weights(); diff --git a/server/core/resource.cc b/server/core/resource.cc index bf79c1e69..0ac5c7d0e 100644 --- a/server/core/resource.cc +++ b/server/core/resource.cc @@ -484,6 +484,18 @@ HttpResponse cb_delete_service(const HttpRequest& request) return HttpResponse(MHD_HTTP_FORBIDDEN, runtime_get_json_error()); } +HttpResponse cb_delete_filter(const HttpRequest& request) +{ + MXS_FILTER_DEF* filter = filter_def_find(request.uri_part(1).c_str()); + ss_dassert(filter); + + if (runtime_destroy_filter(filter)) + { + return HttpResponse(MHD_HTTP_NO_CONTENT); + } + + return HttpResponse(MHD_HTTP_FORBIDDEN, runtime_get_json_error()); +} HttpResponse cb_all_servers(const HttpRequest& request) { return HttpResponse(MHD_HTTP_OK, server_list_to_json(request.host())); @@ -957,6 +969,7 @@ public: m_delete.push_back(SResource(new Resource(cb_delete_server, 2, "servers", ":server"))); m_delete.push_back(SResource(new Resource(cb_delete_monitor, 2, "monitors", ":monitor"))); m_delete.push_back(SResource(new Resource(cb_delete_service, 2, "services", ":service"))); + m_delete.push_back(SResource(new Resource(cb_delete_filter, 2, "filters", ":filter"))); m_delete.push_back(SResource(new Resource(cb_delete_user, 3, "users", "inet", ":inetuser"))); m_delete.push_back(SResource(new Resource(cb_delete_user, 3, "users", "unix", ":unixuser"))); diff --git a/server/core/service.cc b/server/core/service.cc index 93ff8ee76..9b22018aa 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -2196,6 +2196,33 @@ bool service_server_in_use(const SERVER *server) return rval; } +bool service_filter_in_use(const MXS_FILTER_DEF *filter) +{ + ss_dassert(filter); + bool rval = false; + + spinlock_acquire(&service_spin); + + for (SERVICE *service = allServices; service && !rval; service = service->next) + { + spinlock_acquire(&service->spin); + for (int i = 0; i < service->n_filters; i++) + { + if (service->filters[i] == filter) + { + rval = true; + break; + } + } + + spinlock_release(&service->spin); + } + + spinlock_release(&service_spin); + + return rval; +} + /** * Creates a service configuration at the location pointed by @c filename *