/* * Copyright (C) 2022 Codership Oy <info@codership.com> * * 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 <https://www.gnu.org/licenses/>. */ #include "config_service_v1.hpp" #include "service_helpers.hpp" #include "v26/wsrep_config_service.h" #include "wsrep/logger.hpp" #include "wsrep/provider_options.hpp" #include <cassert> namespace wsrep_config_service_v1 { wsrep_config_service_v1_t service{ 0 }; static int map_flags(int flags) { int option_flags = 0; if (flags & WSREP_PARAM_DEPRECATED) option_flags |= wsrep::provider_options::flag::deprecated; if (flags & WSREP_PARAM_READONLY) option_flags |= wsrep::provider_options::flag::readonly; if (flags & WSREP_PARAM_TYPE_BOOL) option_flags |= wsrep::provider_options::flag::type_bool; if (flags & WSREP_PARAM_TYPE_INTEGER) option_flags |= wsrep::provider_options::flag::type_integer; if (flags & WSREP_PARAM_TYPE_DOUBLE) option_flags |= wsrep::provider_options::flag::type_double; return option_flags; } static enum wsrep::provider::status make_option(wsrep::provider_options* opt, const char* name, const char* val, int flags) { std::unique_ptr<wsrep::provider_options::option_value> value( new wsrep::provider_options::option_value_string(val)); std::unique_ptr<wsrep::provider_options::option_value> default_value( new wsrep::provider_options::option_value_string(val)); return opt->set_default(name, std::move(value), std::move(default_value), flags); } static enum wsrep::provider::status make_option(wsrep::provider_options* opt, const char* name, int64_t val, int flags) { std::unique_ptr<wsrep::provider_options::option_value> value( new wsrep::provider_options::option_value_int(val)); std::unique_ptr<wsrep::provider_options::option_value> default_value( new wsrep::provider_options::option_value_int(val)); return opt->set_default(name, std::move(value), std::move(default_value), flags); } static enum wsrep::provider::status make_option(wsrep::provider_options* opt, const char* name, bool val, int flags) { std::unique_ptr<wsrep::provider_options::option_value> value( new wsrep::provider_options::option_value_bool(val)); std::unique_ptr<wsrep::provider_options::option_value> default_value( new wsrep::provider_options::option_value_bool(val)); return opt->set_default(name, std::move(value), std::move(default_value), flags); } static enum wsrep::provider::status make_option(wsrep::provider_options* opt, const char* name, double val, int flags) { std::unique_ptr<wsrep::provider_options::option_value> value( new wsrep::provider_options::option_value_double(val)); std::unique_ptr<wsrep::provider_options::option_value> default_value( new wsrep::provider_options::option_value_double(val)); return opt->set_default(name, std::move(value), std::move(default_value), flags); } wsrep_status_t service_callback(const wsrep_parameter* p, void* context) { const int flags = map_flags(p->flags); enum wsrep::provider::status ret(wsrep::provider::error_unknown); wsrep::provider_options* options = (wsrep::provider_options*)context; switch (p->flags & WSREP_PARAM_TYPE_MASK) { case WSREP_PARAM_TYPE_BOOL: ret = make_option(options, p->name, p->value.as_bool, flags); break; case WSREP_PARAM_TYPE_INTEGER: ret = make_option(options, p->name, p->value.as_integer, flags); break; case WSREP_PARAM_TYPE_DOUBLE: ret = make_option(options, p->name, p->value.as_double, flags); break; default: assert((p->flags & WSREP_PARAM_TYPE_MASK) == 0); ret = make_option(options, p->name, p->value.as_string, flags); break; } if (ret == wsrep::provider::success) return WSREP_OK; else return WSREP_FATAL; } } // namespace wsrep_config_service_v1 static int config_service_v1_probe(void* dlh) { typedef int (*init_fn)(wsrep_config_service_v1_t*); typedef void (*deinit_fn)(); return wsrep_impl::service_probe<init_fn>( dlh, WSREP_CONFIG_SERVICE_INIT_FUNC_V1, "config service v1") || wsrep_impl::service_probe<deinit_fn>( dlh, WSREP_CONFIG_SERVICE_DEINIT_FUNC_V1, "config service v1"); } static int config_service_v1_init(void* dlh) { typedef int (*init_fn)(wsrep_config_service_v1_t*); return wsrep_impl::service_init<init_fn>( dlh, WSREP_CONFIG_SERVICE_INIT_FUNC_V1, &wsrep_config_service_v1::service, "config service v1"); } static void config_service_v1_deinit(void* dlh) { typedef int (*deinit_fn)(); wsrep_impl::service_deinit<deinit_fn>( dlh, WSREP_CONFIG_SERVICE_DEINIT_FUNC_V1, "config service v1"); } int wsrep::config_service_v1_fetch(wsrep::provider& provider, wsrep::provider_options* options) { struct wsrep_st* wsrep = (struct wsrep_st*)provider.native(); if (config_service_v1_probe(wsrep->dlh)) { wsrep::log_warning() << "Provider does not support config service v1"; return 1; } if (config_service_v1_init(wsrep->dlh)) { wsrep::log_warning() << "Failed to initialize config service v1"; return 1; } wsrep_status_t ret = wsrep_config_service_v1::service.get_parameters( wsrep, &wsrep_config_service_v1::service_callback, options); config_service_v1_deinit(wsrep->dlh); if (ret != WSREP_OK) { return 1; } return 0; }