diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 5b7072d7..e36db851 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -22,6 +22,7 @@ Authors from Codership Oy: * Alexey Yurchenko , Codership Oy * Mario Karuza , Codership Oy * Daniele Sciascia , Codership Oy + * Jan Lindström , Codership Oy [Codership employees, add name and email/username above this line, but leave this line intact] Other contributors: diff --git a/include/wsrep/connection_monitor_service.hpp b/include/wsrep/connection_monitor_service.hpp new file mode 100644 index 00000000..d3144dbb --- /dev/null +++ b/include/wsrep/connection_monitor_service.hpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024 Codership Oy + * + * This file is part of wsrep-lib. + * + * Wsrep-lib is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Wsrep-lib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wsrep-lib. If not, see . + */ + + +/** @file connection_monitor_service.hpp + * + * Service interface for interacting with DBMS provided + * connection monitor callback. + */ + +#ifndef WSREP_CONNECTION_MONITOR_SERVICE_HPP +#define WSREP_CONNECTION_MONITOR_SERVICE_HPP + +#include "compiler.hpp" +#include "wsrep/buffer.hpp" +#include "v26/wsrep_connection_monitor_service.h" + +namespace wsrep +{ + class connection_monitor_service + { + public: + + virtual ~connection_monitor_service() { } + + /** + * Connection monitor connect callback. + */ + virtual bool connection_monitor_connect_cb( + wsrep_connection_key_t id, + const wsrep::const_buffer& scheme, + const wsrep::const_buffer& local_addr, + const wsrep::const_buffer& remote_uuid, + const wsrep::const_buffer& remote_addr + ) WSREP_NOEXCEPT = 0; + /** + * Connection monitor disconnect callback. + */ + virtual bool connection_monitor_disconnect_cb(wsrep_connection_key_t id + ) WSREP_NOEXCEPT=0; + }; +} + +#endif // WSREP_CONNECTION_MONITOR_SERVICE_HPP diff --git a/include/wsrep/provider.hpp b/include/wsrep/provider.hpp index 5e82ecd8..1ebcba84 100644 --- a/include/wsrep/provider.hpp +++ b/include/wsrep/provider.hpp @@ -47,6 +47,7 @@ namespace wsrep class tls_service; class allowlist_service; class event_service; + class connection_monitor_service; class stid { @@ -450,6 +451,7 @@ namespace wsrep wsrep::tls_service* tls_service; wsrep::allowlist_service* allowlist_service; wsrep::event_service* event_service; + wsrep::connection_monitor_service* connection_monitor_service; // some GCC and clang versions don't support C++11 default // initializers fully, so we need to use explicit constructors @@ -461,17 +463,20 @@ namespace wsrep , tls_service() , allowlist_service() , event_service() + , connection_monitor_service() { } services(wsrep::thread_service* thr, wsrep::tls_service* tls, wsrep::allowlist_service* all, - wsrep::event_service* event) + wsrep::event_service* event, + wsrep::connection_monitor_service* con) : thread_service(thr) , tls_service(tls) , allowlist_service(all) , event_service(event) + , connection_monitor_service(con) { } }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 85524cea..45b6f623 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ add_library(wsrep-lib allowlist_service_v1.cpp client_state.cpp config_service_v1.cpp + connection_monitor_service_v1.cpp event_service_v1.cpp exception.cpp gtid.cpp diff --git a/src/connection_monitor_service_v1.cpp b/src/connection_monitor_service_v1.cpp new file mode 100644 index 00000000..12d08c66 --- /dev/null +++ b/src/connection_monitor_service_v1.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2024 Codership Oy + * + * This file is part of wsrep-lib. + * + * Wsrep-lib is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Wsrep-lib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wsrep-lib. If not, see . + */ + +#include "connection_monitor_service_v1.hpp" +#include "service_helpers.hpp" + +#include "wsrep/buffer.hpp" +#include "v26/wsrep_connection_monitor_service.h" +#include "wsrep/connection_monitor_service.hpp" + +#include +#include +#include + +namespace wsrep_connection_monitor_service_v1 +{ + // Pointer to connection monitor service implementation provided by + // the application. + static wsrep::connection_monitor_service* connection_monitor_service_impl{ 0 }; + static std::atomic use_count; + + // + // connection monitor service callbacks + // + + void connection_monitor_connect_cb( + wsrep_connection_monitor_context_t*, + wsrep_connection_key_t id, + const wsrep_buf_t* scheme, + const wsrep_buf_t* local_address, + const wsrep_buf_t* remote_uuid, + const wsrep_buf_t* remote_address + ) + { + assert(connection_monitor_service_impl); + wsrep::const_buffer scheme_value(scheme->ptr, scheme->len); + wsrep::const_buffer remote_addr(remote_address->ptr, remote_address->len); + wsrep::const_buffer remote(remote_uuid->ptr, remote_uuid->len); + wsrep::const_buffer local_addr(local_address->ptr, local_address->len); + connection_monitor_service_impl->connection_monitor_connect_cb( + id, + scheme_value, + local_addr, + remote, + remote_addr); + } + + void connection_monitor_disconnect_cb( + wsrep_connection_monitor_context_t*, + wsrep_connection_key_t id + ) + { + assert(connection_monitor_service_impl); + connection_monitor_service_impl->connection_monitor_disconnect_cb(id); + } + + static wsrep_connection_monitor_service_v1_t connection_monitor_service_callbacks + = { connection_monitor_connect_cb, + connection_monitor_disconnect_cb, + 0 }; +} + +int wsrep::connection_monitor_service_v1_probe(void* dlh) +{ + typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*); + typedef void (*deinit_fn)(); + if (wsrep_impl::service_probe( + dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1, "connection monitor service v1") || + wsrep_impl::service_probe( + dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1")) + { + wsrep::log_warning() << "Provider does not support connection monitor service v1"; + return 1; + } + + return 0; +} + +int wsrep::connection_monitor_service_v1_init(void* dlh, + wsrep::connection_monitor_service* connection_service) +{ + if (not (dlh && connection_service)) return EINVAL; + typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*); + wsrep_connection_monitor_service_v1::connection_monitor_service_impl = connection_service; + int ret(0); + if ((ret = wsrep_impl::service_init( + dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1, + &wsrep_connection_monitor_service_v1::connection_monitor_service_callbacks, + "connection monitor service v1"))) + { + wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0; + } + else + { + ++wsrep_connection_monitor_service_v1::use_count; + } + return ret; +} + +void wsrep::connection_monitor_service_v1_deinit(void* dlh) +{ + typedef int (*deinit_fn)(); + wsrep_impl::service_deinit( + dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1"); + assert(wsrep_connection_monitor_service_v1::use_count > 0); + --wsrep_connection_monitor_service_v1::use_count; + if (wsrep_connection_monitor_service_v1::use_count == 0) + { + wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0; + } +} diff --git a/src/connection_monitor_service_v1.hpp b/src/connection_monitor_service_v1.hpp new file mode 100644 index 00000000..618203b7 --- /dev/null +++ b/src/connection_monitor_service_v1.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2024 Codership Oy + * + * This file is part of wsrep-lib. + * + * Wsrep-lib is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Wsrep-lib is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wsrep-lib. If not, see . + */ + +#ifndef WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP +#define WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP + +namespace wsrep +{ + class connection_monitor_service; + /** + * Probe connection_monitor_service_v1 support in loaded library. + * + * @param dlh Handle returned by dlopen(). + * + * @return Zero on success, non-zero system error code on failure. + */ + int connection_monitor_service_v1_probe(void *dlh); + + /** + * Initialize the connection_monitor service. + * + * @param dlh Handle returned by dlopen(). + * @param connection_monitor_service Pointer to + * wsrep::connection_monitor_service implementation. + * + * @return Zero on success, non-zero system error code on failure. + */ + int connection_monitor_service_v1_init(void* dlh, + wsrep::connection_monitor_service* connection_monitor_service); + + /** + * Deinitialize the connection monitor service. + * + * @params dlh Handler returned by dlopen(). + */ + void connection_monitor_service_v1_deinit(void* dlh); + +} + +#endif // WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP diff --git a/src/wsrep_provider_v26.cpp b/src/wsrep_provider_v26.cpp index 8fa9feec..e4d2f15c 100644 --- a/src/wsrep_provider_v26.cpp +++ b/src/wsrep_provider_v26.cpp @@ -28,6 +28,7 @@ #include "wsrep/thread_service.hpp" #include "wsrep/tls_service.hpp" #include "wsrep/allowlist_service.hpp" +#include "wsrep/connection_monitor_service.hpp" #include "service_helpers.hpp" #include "thread_service_v1.hpp" @@ -36,6 +37,7 @@ #include "event_service_v1.hpp" #include "v26/wsrep_api.h" #include "v26/wsrep_node_isolation.h" +#include "connection_monitor_service_v1.hpp" #include #include @@ -674,6 +676,22 @@ namespace } wsrep_node_isolation_mode_set_fn_v1 node_isolation_mode_set; + + static int init_connection_monitor_service(void* dlh, + wsrep::connection_monitor_service* connection_monitor_service) + { + assert(connection_monitor_service); + if (not wsrep::connection_monitor_service_v1_probe(dlh)) + { + return wsrep::connection_monitor_service_v1_init(dlh, connection_monitor_service); + } + return 1; + } + + static void deinit_connection_monitor_service(void* dlh) + { + wsrep::connection_monitor_service_v1_deinit(dlh); + } } @@ -721,6 +739,15 @@ void wsrep::wsrep_provider_v26::init_services( node_isolation_mode_set = wsrep_impl::resolve_function( wsrep_->dlh, WSREP_NODE_ISOLATION_MODE_SET_V1); + + if (services.connection_monitor_service) + { + if (init_connection_monitor_service(wsrep_->dlh, services.connection_monitor_service)) + { + throw wsrep::runtime_error("Failed to initialize connection monitor service"); + } + services_enabled_.connection_monitor_service = services.connection_monitor_service; + } } void wsrep::wsrep_provider_v26::deinit_services() @@ -734,6 +761,8 @@ void wsrep::wsrep_provider_v26::deinit_services() if (services_enabled_.allowlist_service) deinit_allowlist_service(wsrep_->dlh); node_isolation_mode_set = nullptr; + if (services_enabled_.connection_monitor_service) + deinit_connection_monitor_service(wsrep_->dlh); } wsrep::wsrep_provider_v26::wsrep_provider_v26( diff --git a/wsrep-API/v26 b/wsrep-API/v26 index 427c73c5..848b06d0 160000 --- a/wsrep-API/v26 +++ b/wsrep-API/v26 @@ -1 +1 @@ -Subproject commit 427c73c5c8c443765ec16bfc70d94a65a7fca64c +Subproject commit 848b06d027eea6ddbacad5847ddc6315064dbb2b