Skip to content

Commit e15035c

Browse files
committed
MDEV-26851 : Add interface to monitor connections in Galera
1 parent 2d7b357 commit e15035c

8 files changed

+307
-2
lines changed

Diff for: CONTRIBUTORS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Authors from Codership Oy:
2222
* Alexey Yurchenko <[email protected]>, Codership Oy
2323
* Mario Karuza <[email protected]>, Codership Oy
2424
* Daniele Sciascia <[email protected]>, Codership Oy
25+
* Jan Lindström <[email protected]>, Codership Oy
2526
[Codership employees, add name and email/username above this line, but leave this line intact]
2627

2728
Other contributors:

Diff for: include/wsrep/connection_monitor_service.hpp

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (C) 2024-2025 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
21+
/** @file connection_monitor_service.hpp
22+
*
23+
* Service interface for interacting with DBMS provided
24+
* connection monitor callback.
25+
*/
26+
27+
#ifndef WSREP_CONNECTION_MONITOR_SERVICE_HPP
28+
#define WSREP_CONNECTION_MONITOR_SERVICE_HPP
29+
30+
#include "compiler.hpp"
31+
#include "wsrep/buffer.hpp"
32+
33+
namespace wsrep
34+
{
35+
/* Type tag for connection key. */
36+
typedef const void* wsrep_connection_key_t;
37+
38+
class connection_monitor_service
39+
{
40+
public:
41+
42+
virtual ~connection_monitor_service() { }
43+
44+
/**
45+
* Connection monitor connect callback.
46+
*/
47+
virtual bool connection_monitor_connect_cb(
48+
wsrep_connection_key_t id,
49+
const wsrep::const_buffer& scheme,
50+
const wsrep::const_buffer& local_addr,
51+
const wsrep::const_buffer& remote_addr
52+
) WSREP_NOEXCEPT = 0;
53+
/**
54+
* Connection monitor disconnect callback.
55+
*/
56+
virtual bool connection_monitor_disconnect_cb(wsrep_connection_key_t id
57+
) WSREP_NOEXCEPT=0;
58+
59+
/**
60+
* Connection monitor SSL/TLS info callback.
61+
*/
62+
virtual bool connection_monitor_ssl_info_cb(wsrep_connection_key_t id,
63+
const wsrep::const_buffer& ciper,
64+
const wsrep::const_buffer& subject,
65+
const wsrep::const_buffer& issuer,
66+
const wsrep::const_buffer& version
67+
) WSREP_NOEXCEPT = 0;
68+
};
69+
}
70+
71+
#endif // WSREP_CONNECTION_MONITOR_SERVICE_HPP

Diff for: include/wsrep/provider.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ namespace wsrep
4949
class allowlist_service;
5050
class event_service;
5151
class client_service;
52+
class connection_monitor_service;
5253
class stid
5354
{
5455
public:
@@ -479,6 +480,7 @@ namespace wsrep
479480
wsrep::tls_service* tls_service;
480481
wsrep::allowlist_service* allowlist_service;
481482
wsrep::event_service* event_service;
483+
wsrep::connection_monitor_service* connection_monitor_service;
482484

483485
// some GCC and clang versions don't support C++11 default
484486
// initializers fully, so we need to use explicit constructors
@@ -490,17 +492,20 @@ namespace wsrep
490492
, tls_service()
491493
, allowlist_service()
492494
, event_service()
495+
, connection_monitor_service()
493496
{
494497
}
495498

496499
services(wsrep::thread_service* thr,
497500
wsrep::tls_service* tls,
498501
wsrep::allowlist_service* all,
499-
wsrep::event_service* event)
502+
wsrep::event_service* event,
503+
wsrep::connection_monitor_service* con)
500504
: thread_service(thr)
501505
, tls_service(tls)
502506
, allowlist_service(all)
503507
, event_service(event)
508+
, connection_monitor_service(con)
504509
{
505510
}
506511
};

Diff for: src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_library(wsrep-lib
66
allowlist_service_v1.cpp
77
client_state.cpp
88
config_service_v1.cpp
9+
connection_monitor_service_v1.cpp
910
event_service_v1.cpp
1011
exception.cpp
1112
gtid.cpp

Diff for: src/connection_monitor_service_v1.cpp

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright (C) 2024-2025 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
#include "connection_monitor_service_v1.hpp"
21+
#include "service_helpers.hpp"
22+
23+
#include "wsrep/buffer.hpp"
24+
#include "v26/wsrep_connection_monitor_service.h"
25+
#include "wsrep/connection_monitor_service.hpp"
26+
27+
#include <cassert>
28+
#include <dlfcn.h>
29+
#include <cerrno>
30+
31+
namespace wsrep_connection_monitor_service_v1
32+
{
33+
// Pointer to connection monitor service implementation provided by
34+
// the application.
35+
static wsrep::connection_monitor_service* connection_monitor_service_impl{ 0 };
36+
static std::atomic<size_t> use_count;
37+
38+
//
39+
// connection monitor service callbacks
40+
//
41+
42+
void connection_monitor_connect_cb(
43+
wsrep_connection_monitor_context_t*,
44+
wsrep_connection_key_t id,
45+
const wsrep_buf_t* scheme,
46+
const wsrep_buf_t* local_address,
47+
const wsrep_buf_t* remote_address
48+
)
49+
{
50+
assert(connection_monitor_service_impl);
51+
wsrep::const_buffer scheme_value(scheme->ptr, scheme->len);
52+
wsrep::const_buffer remote_addr(remote_address->ptr, remote_address->len);
53+
wsrep::const_buffer local_addr(local_address->ptr, local_address->len);
54+
connection_monitor_service_impl->connection_monitor_connect_cb(
55+
id,
56+
scheme_value,
57+
local_addr,
58+
remote_addr);
59+
}
60+
61+
void connection_monitor_disconnect_cb(
62+
wsrep_connection_monitor_context_t*,
63+
wsrep_connection_key_t id
64+
)
65+
{
66+
assert(connection_monitor_service_impl);
67+
connection_monitor_service_impl->connection_monitor_disconnect_cb(id);
68+
}
69+
70+
void connection_monitor_ssl_info_cb(
71+
wsrep_connection_monitor_context_t*,
72+
wsrep_connection_key_t id,
73+
const wsrep_buf_t* cipher,
74+
const wsrep_buf_t* certificate_subject,
75+
const wsrep_buf_t* certificate_issuer,
76+
const wsrep_buf_t* version)
77+
{
78+
assert(connection_monitor_service_impl);
79+
wsrep::const_buffer ssl_cipher(cipher->ptr, cipher->len);
80+
wsrep::const_buffer cert_sub(certificate_subject->ptr, certificate_subject->len);
81+
wsrep::const_buffer cert_iss(certificate_issuer->ptr, certificate_issuer->len);
82+
wsrep::const_buffer vers(version->ptr, version->len);
83+
connection_monitor_service_impl->connection_monitor_ssl_info_cb(
84+
id, ssl_cipher, cert_sub, cert_iss, vers);
85+
}
86+
87+
static wsrep_connection_monitor_service_v1_t connection_monitor_service_callbacks
88+
= { connection_monitor_connect_cb,
89+
connection_monitor_disconnect_cb,
90+
connection_monitor_ssl_info_cb,
91+
0 };
92+
}
93+
94+
int wsrep::connection_monitor_service_v1_probe(void* dlh)
95+
{
96+
typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*);
97+
typedef void (*deinit_fn)();
98+
if (wsrep_impl::service_probe<init_fn>(
99+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1, "connection monitor service v1") ||
100+
wsrep_impl::service_probe<deinit_fn>(
101+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1"))
102+
{
103+
wsrep::log_warning() << "Provider does not support connection monitor service v1";
104+
return 1;
105+
}
106+
107+
return 0;
108+
}
109+
110+
int wsrep::connection_monitor_service_v1_init(void* dlh,
111+
wsrep::connection_monitor_service* connection_service)
112+
{
113+
if (not (dlh && connection_service)) return EINVAL;
114+
typedef int (*init_fn)(wsrep_connection_monitor_service_v1_t*);
115+
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = connection_service;
116+
int ret(0);
117+
if ((ret = wsrep_impl::service_init<init_fn>(
118+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_INIT_FUNC_V1,
119+
&wsrep_connection_monitor_service_v1::connection_monitor_service_callbacks,
120+
"connection monitor service v1")))
121+
{
122+
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0;
123+
}
124+
else
125+
{
126+
++wsrep_connection_monitor_service_v1::use_count;
127+
}
128+
return ret;
129+
}
130+
131+
void wsrep::connection_monitor_service_v1_deinit(void* dlh)
132+
{
133+
typedef int (*deinit_fn)();
134+
wsrep_impl::service_deinit<deinit_fn>(
135+
dlh, WSREP_CONNECTION_MONITOR_SERVICE_DEINIT_FUNC_V1, "connection monitor service v1");
136+
assert(wsrep_connection_monitor_service_v1::use_count > 0);
137+
--wsrep_connection_monitor_service_v1::use_count;
138+
if (wsrep_connection_monitor_service_v1::use_count == 0)
139+
{
140+
wsrep_connection_monitor_service_v1::connection_monitor_service_impl = 0;
141+
}
142+
}

Diff for: src/connection_monitor_service_v1.hpp

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (C) 2024-2025 Codership Oy <[email protected]>
3+
*
4+
* This file is part of wsrep-lib.
5+
*
6+
* Wsrep-lib is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* Wsrep-lib is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with wsrep-lib. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
#ifndef WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP
21+
#define WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP
22+
23+
namespace wsrep
24+
{
25+
class connection_monitor_service;
26+
/**
27+
* Probe connection_monitor_service_v1 support in loaded library.
28+
*
29+
* @param dlh Handle returned by dlopen().
30+
*
31+
* @return Zero on success, non-zero system error code on failure.
32+
*/
33+
int connection_monitor_service_v1_probe(void *dlh);
34+
35+
/**
36+
* Initialize the connection_monitor service.
37+
*
38+
* @param dlh Handle returned by dlopen().
39+
* @param connection_monitor_service Pointer to
40+
* wsrep::connection_monitor_service implementation.
41+
*
42+
* @return Zero on success, non-zero system error code on failure.
43+
*/
44+
int connection_monitor_service_v1_init(void* dlh,
45+
wsrep::connection_monitor_service* connection_monitor_service);
46+
47+
/**
48+
* Deinitialize the connection monitor service.
49+
*
50+
* @params dlh Handler returned by dlopen().
51+
*/
52+
void connection_monitor_service_v1_deinit(void* dlh);
53+
54+
}
55+
56+
#endif // WSREP_CONNECTION_MONITOR_SERVICE_V1_HPP

Diff for: src/wsrep_provider_v26.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "wsrep/thread_service.hpp"
2929
#include "wsrep/tls_service.hpp"
3030
#include "wsrep/allowlist_service.hpp"
31+
#include "wsrep/connection_monitor_service.hpp"
3132

3233
#include "service_helpers.hpp"
3334
#include "thread_service_v1.hpp"
@@ -36,6 +37,7 @@
3637
#include "event_service_v1.hpp"
3738
#include "v26/wsrep_api.h"
3839
#include "v26/wsrep_node_isolation.h"
40+
#include "connection_monitor_service_v1.hpp"
3941

4042
#include <dlfcn.h>
4143
#include <cassert>
@@ -675,6 +677,22 @@ namespace
675677

676678
wsrep_node_isolation_mode_set_fn_v1 node_isolation_mode_set;
677679
wsrep_certify_fn_v1 certify_v1;
680+
681+
static int init_connection_monitor_service(void* dlh,
682+
wsrep::connection_monitor_service* connection_monitor_service)
683+
{
684+
assert(connection_monitor_service);
685+
if (not wsrep::connection_monitor_service_v1_probe(dlh))
686+
{
687+
return wsrep::connection_monitor_service_v1_init(dlh, connection_monitor_service);
688+
}
689+
return 1;
690+
}
691+
692+
static void deinit_connection_monitor_service(void* dlh)
693+
{
694+
wsrep::connection_monitor_service_v1_deinit(dlh);
695+
}
678696
}
679697

680698

@@ -725,6 +743,15 @@ void wsrep::wsrep_provider_v26::init_services(
725743

726744
certify_v1 = wsrep_impl::resolve_function<wsrep_certify_fn_v1>(
727745
wsrep_->dlh, WSREP_CERTIFY_V1);
746+
747+
if (services.connection_monitor_service)
748+
{
749+
if (init_connection_monitor_service(wsrep_->dlh, services.connection_monitor_service))
750+
{
751+
throw wsrep::runtime_error("Failed to initialize connection monitor service");
752+
}
753+
services_enabled_.connection_monitor_service = services.connection_monitor_service;
754+
}
728755
}
729756

730757
void wsrep::wsrep_provider_v26::deinit_services()
@@ -738,6 +765,8 @@ void wsrep::wsrep_provider_v26::deinit_services()
738765
if (services_enabled_.allowlist_service)
739766
deinit_allowlist_service(wsrep_->dlh);
740767
node_isolation_mode_set = nullptr;
768+
if (services_enabled_.connection_monitor_service)
769+
deinit_connection_monitor_service(wsrep_->dlh);
741770
}
742771

743772
wsrep::wsrep_provider_v26::wsrep_provider_v26(

Diff for: wsrep-API/v26

0 commit comments

Comments
 (0)