Skip to content

Commit db41d67

Browse files
committedApr 4, 2025·
Retrieve provider options before provider is initialized
Change provider_options so that it does not depend on provider. Call into config_service when provider is created, i.e. after library is loaded, before it is initialized, so that we can inject additional options at startup. Change the signature of the call provider options callback to take provider_options object as parameter.
1 parent 97b0da6 commit db41d67

11 files changed

+72
-49
lines changed
 

‎include/wsrep/provider.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ namespace wsrep
5151
class event_service;
5252
class client_service;
5353
class connection_monitor_service;
54+
class provider_options;
5455
class stid
5556
{
5657
public:
@@ -520,7 +521,7 @@ namespace wsrep
520521
static std::unique_ptr<provider> make_provider(
521522
wsrep::server_state&,
522523
const std::string& provider_spec,
523-
const std::function<std::string()>& provider_options_cb,
524+
const std::function<std::string(provider_options&)>& provider_options_cb,
524525
const wsrep::provider::services& services
525526
= wsrep::provider::services());
526527
protected:

‎include/wsrep/provider_options.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ namespace wsrep
214214
int flags_;
215215
};
216216

217-
provider_options(wsrep::provider&);
217+
provider_options();
218218
provider_options(const provider_options&) = delete;
219219
provider_options& operator=(const provider_options&) = delete;
220220

@@ -225,7 +225,7 @@ namespace wsrep
225225
*
226226
* @return Provider status code.
227227
*/
228-
enum wsrep::provider::status initial_options();
228+
enum wsrep::provider::status initial_options(wsrep::provider& provider);
229229

230230
/**
231231
* Get the option with the given name
@@ -241,7 +241,8 @@ namespace wsrep
241241
* @return wsrep::provider::error_size_exceeded if memory could
242242
* not be allocated for the new value.
243243
*/
244-
enum wsrep::provider::status set(const std::string& name,
244+
enum wsrep::provider::status set(wsrep::provider& provider,
245+
const std::string& name,
245246
std::unique_ptr<option_value> value);
246247

247248
/**
@@ -255,7 +256,6 @@ namespace wsrep
255256
void for_each(const std::function<void(option*)>& fn);
256257

257258
private:
258-
provider& provider_;
259259
using options_map = std::map<std::string, std::unique_ptr<option>>;
260260
options_map options_;
261261
};

‎include/wsrep/server_state.hpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ namespace wsrep
117117
class server_service;
118118
class client_service;
119119
class encryption_service;
120+
class provider_options;
120121

121122
/** @class Server Context
122123
*
@@ -296,16 +297,15 @@ namespace wsrep
296297
* @return Zero on success, non-zero on error.
297298
*/
298299
int load_provider(const std::string& provider,
299-
const std::function<std::string()>& provider_options_cb,
300+
const std::function<std::string(provider_options&)>&,
300301
const wsrep::provider::services& services
301302
= wsrep::provider::services());
302303

303-
304304
/**
305305
* Load WSRep provider.
306306
*
307307
* @param provider WSRep provider library to be loaded.
308-
* @param provider_options Provider specific options string
308+
* @param options Provider specific options string
309309
* to be passed for provider during initialization.
310310
* @param services Application defined services passed to
311311
* the provider.
@@ -315,13 +315,13 @@ namespace wsrep
315315
* @note Provided for backward compatibility.
316316
*/
317317
int load_provider(const std::string& provider,
318-
const std::string& provider_options,
318+
const std::string& options,
319319
const wsrep::provider::services& services
320320
= wsrep::provider::services())
321321
{
322-
return load_provider(provider,
323-
[provider_options]() { return provider_options; },
324-
services);
322+
return load_provider(
323+
provider, [options](provider_options&) { return options; },
324+
services);
325325
}
326326

327327
using provider_factory_func =

‎src/config_service_v1.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "config_service_v1.hpp"
2121
#include "service_helpers.hpp"
22+
#include "v26/wsrep_api.h"
2223
#include "v26/wsrep_config_service.h"
2324
#include "wsrep/logger.hpp"
2425
#include "wsrep/provider_options.hpp"
@@ -147,10 +148,9 @@ static void config_service_v1_deinit(void* dlh)
147148
dlh, WSREP_CONFIG_SERVICE_DEINIT_FUNC_V1, "config service v1");
148149
}
149150

150-
int wsrep::config_service_v1_fetch(wsrep::provider& provider,
151+
int wsrep::config_service_v1_fetch(struct wsrep_st* wsrep,
151152
wsrep::provider_options* options)
152153
{
153-
struct wsrep_st* wsrep = (struct wsrep_st*)provider.native();
154154
if (wsrep == nullptr)
155155
{
156156
// Not a provider which was loaded via wsrep-API
@@ -179,3 +179,10 @@ int wsrep::config_service_v1_fetch(wsrep::provider& provider,
179179

180180
return 0;
181181
}
182+
183+
int wsrep::config_service_v1_fetch(wsrep::provider& provider,
184+
wsrep::provider_options* options)
185+
{
186+
struct wsrep_st* wsrep = (struct wsrep_st*)provider.native();
187+
return config_service_v1_fetch(wsrep, options);
188+
}

‎src/config_service_v1.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
#ifndef WSREP_CONFIG_SERVICE_V1_HPP
2121
#define WSREP_CONFIG_SERVICE_V1_HPP
2222

23+
struct wsrep_st;
24+
2325
namespace wsrep
2426
{
2527
class provider;
2628
class provider_options;
2729
int config_service_v1_fetch(provider& provider, provider_options* opts);
30+
int config_service_v1_fetch(struct wsrep_st* wsrep, provider_options* opts);
2831
} // namespace wsrep
2932

3033
#endif // WSREP_CONFIG_SERVICE_V1_HPP

‎src/provider.cpp

+8-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "wsrep/provider.hpp"
2121
#include "wsrep/logger.hpp"
22+
#include "wsrep/provider_options.hpp"
2223

2324
#include "wsrep_provider_v26.hpp"
2425

@@ -29,27 +30,30 @@
2930
std::unique_ptr<wsrep::provider> wsrep::provider::make_provider(
3031
wsrep::server_state& server_state,
3132
const std::string& provider_spec,
32-
const std::function<std::string()>& provider_options_cb,
33+
const std::function<std::string(provider_options&)>& provider_options_cb,
3334
const wsrep::provider::services& services)
3435
{
3536
try
3637
{
3738
return std::unique_ptr<wsrep::provider>(new wsrep::wsrep_provider_v26(
38-
server_state, provider_spec, provider_options_cb, services));
39+
server_state, provider_spec, provider_options_cb,
40+
services));
3941
}
4042
catch (const wsrep::runtime_error& e)
4143
{
44+
provider_options opts;
4245
wsrep::log_error() << "Failed to create a new provider '"
4346
<< provider_spec << "'"
44-
<< " with options '" << provider_options_cb()
47+
<< " with options '" << provider_options_cb(opts)
4548
<< "': " << e.what();
4649
}
4750
catch (...)
4851
{
52+
provider_options opts;
4953
wsrep::log_error() << "Caught unknown exception when trying to "
5054
<< "create a new provider '"
5155
<< provider_spec << "'"
52-
<< " with options '" << provider_options_cb();
56+
<< " with options '" << provider_options_cb(opts);
5357
}
5458
return 0;
5559
}

‎src/provider_options.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include "wsrep/provider_options.hpp"
21+
#include "wsrep/provider.hpp"
2122
#include "config_service_v1.hpp"
2223
#include "wsrep/logger.hpp"
2324

@@ -92,16 +93,16 @@ void wsrep::provider_options::option::update_value(
9293

9394
wsrep::provider_options::option::~option() {}
9495

95-
wsrep::provider_options::provider_options(wsrep::provider& provider)
96-
: provider_(provider)
97-
, options_()
96+
wsrep::provider_options::provider_options()
97+
: options_()
9898
{
9999
}
100100

101-
enum wsrep::provider::status wsrep::provider_options::initial_options()
101+
enum wsrep::provider::status
102+
wsrep::provider_options::initial_options(wsrep::provider& provider)
102103
{
103104
options_.clear();
104-
if (config_service_v1_fetch(provider_, this))
105+
if (config_service_v1_fetch(provider, this))
105106
{
106107
return wsrep::provider::error_not_implemented;
107108
}
@@ -123,7 +124,7 @@ wsrep::provider_options::get_option(const std::string& name) const
123124
}
124125

125126
enum wsrep::provider::status wsrep::provider_options::set(
126-
const std::string& name,
127+
wsrep::provider& provider, const std::string& name,
127128
std::unique_ptr<wsrep::provider_options::option_value> value)
128129
{
129130
auto option(options_.find(name));
@@ -132,7 +133,7 @@ enum wsrep::provider::status wsrep::provider_options::set(
132133
return not_found_error;
133134
}
134135
provider_options_sep sep;
135-
auto ret(provider_.options(std::string(option->second->real_name())
136+
auto ret(provider.options(std::string(option->second->real_name())
136137
+ sep.key_value + value->as_string()
137138
+ sep.param));
138139
if (ret == provider::success)

‎src/server_state.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -500,13 +500,13 @@ static int apply_toi(wsrep::provider& provider,
500500

501501
int wsrep::server_state::load_provider(
502502
const std::string& provider_spec,
503-
const std::function<std::string()>& provider_options_cb,
503+
const std::function<std::string(provider_options&)>& provider_options_cb,
504504
const wsrep::provider::services& services)
505505
{
506506
wsrep::log_info() << "Loading provider " << provider_spec
507507
<< " initial position: " << initial_position_;
508-
provider_
509-
= provider_factory_(*this, provider_spec, provider_options_cb, services);
508+
provider_ = provider_factory_(*this, provider_spec, provider_options_cb,
509+
services);
510510
return (provider_ ? 0 : 1);
511511
}
512512

‎src/wsrep_provider_v26.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
#include "wsrep/tls_service.hpp"
3030
#include "wsrep/allowlist_service.hpp"
3131
#include "wsrep/connection_monitor_service.hpp"
32+
#include "wsrep/provider_options.hpp"
3233

3334
#include "service_helpers.hpp"
3435
#include "thread_service_v1.hpp"
3536
#include "tls_service_v1.hpp"
3637
#include "allowlist_service_v1.hpp"
3738
#include "event_service_v1.hpp"
39+
#include "config_service_v1.hpp"
3840
#include "v26/wsrep_api.h"
3941
#include "v26/wsrep_node_isolation.h"
4042
#include "connection_monitor_service_v1.hpp"
@@ -772,7 +774,7 @@ void wsrep::wsrep_provider_v26::deinit_services()
772774
wsrep::wsrep_provider_v26::wsrep_provider_v26(
773775
wsrep::server_state& server_state,
774776
const std::string& provider_spec,
775-
const std::function<std::string()>& provider_options_cb,
777+
const std::function<std::string(provider_options&)>& provider_options_cb,
776778
const wsrep::provider::services& services)
777779
: provider(server_state)
778780
, wsrep_()
@@ -785,14 +787,24 @@ wsrep::wsrep_provider_v26::wsrep_provider_v26(
785787
server_state.initial_position().id().data(),
786788
sizeof(state_id.uuid.data));
787789
state_id.seqno = server_state.initial_position().seqno().get();
790+
791+
if (wsrep_load(provider_spec.c_str(), &wsrep_, logger_cb))
792+
{
793+
throw wsrep::runtime_error("Failed to load wsrep library");
794+
}
795+
796+
init_services(services);
797+
provider_options options;
798+
config_service_v1_fetch(wsrep_, &options);
799+
788800
struct wsrep_init_args init_args;
789801
memset(&init_args, 0, sizeof(init_args));
790802
init_args.app_ctx = &server_state;
791803
init_args.node_name = server_state_.name().c_str();
792804
init_args.node_address = server_state_.address().c_str();
793805
init_args.node_incoming = server_state_.incoming_address().c_str();
794806
init_args.data_dir = server_state_.working_dir().c_str();
795-
const auto& provider_options = provider_options_cb();
807+
const auto& provider_options = provider_options_cb(options);
796808
init_args.options = provider_options.c_str();
797809
init_args.proto_ver = server_state.max_protocol_version();
798810
init_args.state_id = &state_id;
@@ -807,13 +819,6 @@ wsrep::wsrep_provider_v26::wsrep_provider_v26(
807819
init_args.sst_donate_cb = &sst_donate_cb;
808820
init_args.synced_cb = &synced_cb;
809821

810-
if (wsrep_load(provider_spec.c_str(), &wsrep_, logger_cb))
811-
{
812-
throw wsrep::runtime_error("Failed to load wsrep library");
813-
}
814-
815-
init_services(services);
816-
817822
if (wsrep_->init(wsrep_, &init_args) != WSREP_OK)
818823
{
819824
throw wsrep::runtime_error("Failed to initialize wsrep provider");

‎src/wsrep_provider_v26.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ struct wsrep_st;
2626

2727
namespace wsrep
2828
{
29-
class thread_service;
29+
class provider_options;
30+
3031
class wsrep_provider_v26 : public wsrep::provider
3132
{
3233
public:
3334
void init_services(const wsrep::provider::services& services);
3435
void deinit_services();
3536
wsrep_provider_v26(wsrep::server_state&, const std::string&,
36-
const std::function<std::string()>&,
37+
const std::function<std::string(provider_options&)>&,
3738
const wsrep::provider::services& services);
3839
~wsrep_provider_v26() WSREP_OVERRIDE;
3940
enum wsrep::provider::status

‎test/mock_server_state.hpp

+11-10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "wsrep/server_state.hpp"
2424
#include "wsrep/server_service.hpp"
25+
#include "wsrep/provider_options.hpp"
2526
#include "mock_client_state.hpp"
2627
#include "mock_high_priority_service.hpp"
2728
#include "mock_storage_service.hpp"
@@ -260,16 +261,16 @@ namespace wsrep
260261
, cond_()
261262
, provider_()
262263
{
263-
set_provider_factory([&](wsrep::server_state&,
264-
const std::string&,
265-
const std::function<std::string()>&,
266-
const wsrep::provider::services&)
267-
{
268-
// The provider object is destroyed upon server state
269-
// destruction, so using a raw pointer is safe.
270-
provider_ = new wsrep::mock_provider(*this);
271-
return std::unique_ptr<wsrep::provider>(provider_);
272-
});
264+
set_provider_factory(
265+
[&](wsrep::server_state&, const std::string&,
266+
const std::function<std::string(wsrep::provider_options&)>&,
267+
const wsrep::provider::services&)
268+
{
269+
// The provider object is destroyed upon server state
270+
// destruction, so using a raw pointer is safe.
271+
provider_ = new wsrep::mock_provider(*this);
272+
return std::unique_ptr<wsrep::provider>(provider_);
273+
});
273274

274275
const int ret WSREP_UNUSED = load_provider("mock", "");
275276
assert(ret == 0);

0 commit comments

Comments
 (0)
Please sign in to comment.