Skip to content

Commit 31db847

Browse files
committed
MDEV-32363 Add interface to set node isolation mode in provider
1 parent 664d8cc commit 31db847

File tree

6 files changed

+96
-3
lines changed

6 files changed

+96
-3
lines changed

include/wsrep/provider.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,21 @@ namespace wsrep
288288
static std::string str(int);
289289
};
290290

291+
/**
292+
* Node isolation mode.
293+
*/
294+
enum node_isolation
295+
{
296+
/** Node is not isolated. */
297+
not_isolated,
298+
/** Node is isolated from the rest of the cluster on
299+
* network level. */
300+
isolated,
301+
/** As on, but also force the provider to deliver a view with
302+
* disconnected status. */
303+
force_disconnect
304+
};
305+
291306
provider(wsrep::server_state& server_state)
292307
: server_state_(server_state)
293308
{ }
@@ -389,6 +404,16 @@ namespace wsrep
389404

390405
virtual std::string options() const = 0;
391406
virtual enum status options(const std::string&) = 0;
407+
408+
409+
/**
410+
* Set node isolation mode.
411+
*
412+
* @param mode node_isolation mode.
413+
* @return Provider status indicating the result of the call.
414+
*/
415+
virtual enum status set_node_isolation(enum node_isolation mode) = 0;
416+
392417
/**
393418
* Get provider name.
394419
*

src/service_helpers.hpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,29 @@ namespace wsrep_impl
100100
<< service_name;
101101
}
102102
}
103-
}
103+
104+
template <typename Fn> Fn resolve_function(void* dlh, const char* symbol)
105+
{
106+
union
107+
{
108+
Fn fun;
109+
void* obj;
110+
} alias;
111+
(void)dlerror();
112+
alias.obj = dlsym(dlh, symbol);
113+
if (alias.obj)
114+
{
115+
wsrep::log_info() << "Resolved symbol '" << symbol << "'";
116+
return alias.fun;
117+
}
118+
else
119+
{
120+
wsrep::log_info()
121+
<< "Symbol '" << symbol << "' not found from provider";
122+
return nullptr;
123+
}
124+
}
125+
} // namespace wsrep_impl
104126

105127
#endif // WSREP_SERVICE_HELPERS_HPP
106128

src/wsrep_provider_v26.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@
2929
#include "wsrep/tls_service.hpp"
3030
#include "wsrep/allowlist_service.hpp"
3131

32+
#include "service_helpers.hpp"
3233
#include "thread_service_v1.hpp"
3334
#include "tls_service_v1.hpp"
3435
#include "allowlist_service_v1.hpp"
3536
#include "event_service_v1.hpp"
3637
#include "v26/wsrep_api.h"
37-
38+
#include "v26/wsrep_node_isolation.h"
3839

3940
#include <dlfcn.h>
4041
#include <cassert>
@@ -671,6 +672,8 @@ namespace
671672
{
672673
wsrep::event_service_v1_deinit(dlh);
673674
}
675+
676+
wsrep_node_isolation_mode_set_fn_v1 node_isolation_mode_set;
674677
}
675678

676679

@@ -714,6 +717,10 @@ void wsrep::wsrep_provider_v26::init_services(
714717
services_enabled_.event_service = services.event_service;
715718
}
716719
}
720+
721+
node_isolation_mode_set
722+
= wsrep_impl::resolve_function<wsrep_node_isolation_mode_set_fn_v1>(
723+
wsrep_->dlh, WSREP_NODE_ISOLATION_MODE_SET_V1);
717724
}
718725

719726
void wsrep::wsrep_provider_v26::deinit_services()
@@ -726,6 +733,7 @@ void wsrep::wsrep_provider_v26::deinit_services()
726733
deinit_thread_service(wsrep_->dlh);
727734
if (services_enabled_.allowlist_service)
728735
deinit_allowlist_service(wsrep_->dlh);
736+
node_isolation_mode_set = nullptr;
729737
}
730738

731739
wsrep::wsrep_provider_v26::wsrep_provider_v26(
@@ -1162,6 +1170,40 @@ wsrep::wsrep_provider_v26::options(const std::string& opts)
11621170
return map_return_value(wsrep_->options_set(wsrep_, opts.c_str()));
11631171
}
11641172

1173+
/*
1174+
* Set node isolation mode in the provider. This function may be called from
1175+
* signal handler, so make sure that only 'safe' system calls and library
1176+
* functions are used. See
1177+
* https://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
1178+
*/
1179+
enum wsrep::provider::status
1180+
wsrep::wsrep_provider_v26::set_node_isolation(node_isolation mode)
1181+
{
1182+
if (not node_isolation_mode_set)
1183+
{
1184+
return error_not_implemented;
1185+
}
1186+
1187+
enum wsrep_node_isolation_mode ws_mode = WSREP_NODE_ISOLATION_NOT_ISOLATED;
1188+
switch (mode)
1189+
{
1190+
case node_isolation::not_isolated:
1191+
ws_mode = WSREP_NODE_ISOLATION_NOT_ISOLATED;
1192+
break;
1193+
case node_isolation::isolated:
1194+
ws_mode = WSREP_NODE_ISOLATION_ISOLATED;
1195+
break;
1196+
case node_isolation::force_disconnect:
1197+
ws_mode = WSREP_NODE_ISOLATION_FORCE_DISCONNECT;
1198+
break;
1199+
}
1200+
if ((*node_isolation_mode_set)(ws_mode) != WSREP_NODE_ISOLATION_SUCCESS)
1201+
{
1202+
return error_warning;
1203+
}
1204+
return success;
1205+
}
1206+
11651207
std::string wsrep::wsrep_provider_v26::name() const
11661208
{
11671209
return (wsrep_->provider_name ? wsrep_->provider_name : "unknown");

src/wsrep_provider_v26.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ namespace wsrep
100100
void reset_status() WSREP_OVERRIDE;
101101
std::string options() const WSREP_OVERRIDE;
102102
enum wsrep::provider::status options(const std::string&) WSREP_OVERRIDE;
103+
enum status set_node_isolation(enum node_isolation mode) WSREP_OVERRIDE;
103104
std::string name() const WSREP_OVERRIDE;
104105
std::string version() const WSREP_OVERRIDE;
105106
std::string vendor() const WSREP_OVERRIDE;

test/mock_provider.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,9 @@ namespace wsrep
294294
enum wsrep::provider::status options(const std::string&)
295295
WSREP_OVERRIDE
296296
{ return wsrep::provider::success; }
297+
enum status set_node_isolation(enum node_isolation) WSREP_OVERRIDE {
298+
return error_not_implemented;
299+
}
297300
std::string name() const WSREP_OVERRIDE { return "mock"; }
298301
std::string version() const WSREP_OVERRIDE { return "0.0"; }
299302
std::string vendor() const WSREP_OVERRIDE { return "mock"; }

wsrep-API/v26

0 commit comments

Comments
 (0)