diff --git a/include/maxscale/server.hh b/include/maxscale/server.hh index 6d4c75d9d..5e287fc19 100644 --- a/include/maxscale/server.hh +++ b/include/maxscale/server.hh @@ -39,15 +39,6 @@ const int MAINTENANCE_ON = 100; const int MAINTENANCE_FLAG_NOCHECK = 0; const int MAINTENANCE_FLAG_CHECK = -1; -/* Custom server parameters. These can be used by modules for e.g. weighting routing decisions. */ -struct SERVER_PARAM -{ - char* name; /**< Parameter name */ - char* value; /**< Parameter value */ - bool active; /**< Whether the parameter is valid */ - struct SERVER_PARAM* next; /**< Next Paramter in the linked list */ -}; - /* Server connection and usage statistics */ struct SERVER_STATS { @@ -119,8 +110,7 @@ public: char monpw[MAX_MONPW_LEN] = {'\0'}; /**< Monitor password, overrides monitor setting */ bool proxy_protocol = false; /**< Send proxy-protocol header to backends when connecting * routing sessions. */ - SERVER_PARAM* parameters = nullptr; /**< Additional custom parameters which may affect routing - * decisions. */ + // Base variables bool is_active = false; /**< Server is active and has not been "destroyed" */ void* auth_instance = nullptr; /**< Authenticator instance data */ @@ -182,6 +172,14 @@ public: */ virtual bool persistent_conns_enabled() const = 0; + /** + * Fetch value of custom parameter. + * + * @param name Parameter name + * @return Value of parameter, or empty if not found + */ + virtual std::string get_custom_parameter(const std::string& name) const = 0; + protected: SERVER() { @@ -383,18 +381,6 @@ inline bool server_is_disk_space_exhausted(const SERVER* server) return status_is_disk_space_exhausted(server->status); } -/** - * @brief Serialize a server to a file - * - * This converts @c server into an INI format file. This allows created servers - * to be persisted to disk. This will replace any existing files with the same - * name. - * - * @param server Server to serialize - * @return False if the serialization of the server fails, true if it was successful - */ -bool server_serialize(const SERVER* server); - /** * @brief Add a server parameter * @@ -404,24 +390,6 @@ bool server_serialize(const SERVER* server); */ void server_add_parameter(SERVER* server, const char* name, const char* value); -/** - * @brief Remove a server parameter - * - * @param server Server to remove the parameter from - * @param name The name of the parameter to remove - * @return True if a parameter was removed - */ -bool server_remove_parameter(SERVER* server, const char* name); - -/** - * @brief Set server parameter - * - * @param server Server to update - * @param name Parameter to set - * @param value Value of parameter - */ -void server_set_parameter(SERVER* server, const char* name, const char* value); - /** * @brief Check if a server points to a local MaxScale service * @@ -430,16 +398,6 @@ void server_set_parameter(SERVER* server, const char* name, const char* value); */ bool server_is_mxs_service(const SERVER* server); -/** - * @brief Convert a server to JSON format - * - * @param server Server to convert - * @param host Hostname of this server - * - * @return JSON representation of server or NULL if an error occurred - */ -json_t* server_to_json(const SERVER* server, const char* host); - /** * @brief Convert all servers into JSON format * @@ -478,7 +436,6 @@ extern void server_set_status_nolock(SERVER* server, uint64_t bit); extern void server_clear_status_nolock(SERVER* server, uint64_t bit); extern void server_transfer_status(SERVER* dest_server, const SERVER* source_server); extern void server_add_mon_user(SERVER* server, const char* user, const char* passwd); -extern size_t server_get_parameter(const SERVER* server, const char* name, char* out, size_t size); extern void server_update_credentials(SERVER* server, const char* user, const char* passwd); extern void server_update_address(SERVER* server, const char* address); extern void server_update_port(SERVER* server, unsigned short port); diff --git a/server/core/config_runtime.cc b/server/core/config_runtime.cc index b30147841..acbbff376 100644 --- a/server/core/config_runtime.cc +++ b/server/core/config_runtime.cc @@ -244,7 +244,7 @@ bool runtime_create_server(const char* name, Server* server = Server::server_alloc(name, ctx.parameters); - if (server && server_serialize(server)) + if (server && server->serialize()) { rval = true; MXS_NOTICE("Created server '%s' at %s:%u", @@ -383,7 +383,7 @@ bool runtime_enable_server_ssl(Server* server, atomic_synchronize(); server->server_ssl = ssl; - if (server_serialize(server)) + if (server->serialize()) { MXS_NOTICE("Enabled SSL for server '%s'", server->name); rval = true; @@ -476,7 +476,7 @@ bool runtime_alter_server(Server* server, const char* key, const char* value) } std::lock_guard guard(crt_lock); - server_set_parameter(server, key, value); + server->set_parameter(key, value); if (strcmp(key, CN_ADDRESS) == 0) { @@ -524,7 +524,7 @@ bool runtime_alter_server(Server* server, const char* key, const char* value) service_update_weights(); } - server_serialize(server); + server->serialize(); MXS_NOTICE("Updated server '%s': %s=%s", server->name, key, value); return true; diff --git a/server/core/internal/server.hh b/server/core/internal/server.hh index 6e1349827..c78ba6e26 100644 --- a/server/core/internal/server.hh +++ b/server/core/internal/server.hh @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -36,6 +37,12 @@ public: { } + struct ConfigParameter + { + std::string name; + std::string value; + }; + int response_time_num_samples() const { return m_response_time.num_samples(); @@ -133,6 +140,14 @@ public: */ static Server* find_by_unique_name(const std::string& name); + /** + * Test if name is a normal server setting name. + * + * @param name Name to check + * @return True if name is a standard parameter + */ + bool is_custom_parameter(const std::string& name) const; + /** * Print server details to a DCB * @@ -168,17 +183,52 @@ public: */ static void dListServers(DCB*); + static bool create_server_config(const Server* server, const char* filename); + + static json_t* server_json_attributes(const Server* server); + + /** + * @brief Set server parameter + * + * @param server Server to update + * @param name Parameter to set + * @param value Value of parameter + */ + void set_parameter(const std::string& name, const std::string& value); + + std::string get_custom_parameter(const std::string& name) const override; + + /** + * @brief Serialize a server to a file + * + * This converts @c server into an INI format file. This allows created servers + * to be persisted to disk. This will replace any existing files with the same + * name. + * + * @return False if the serialization of the server fails, true if it was successful + */ + bool serialize() const; + mutable std::mutex m_lock; DCB** persistent = nullptr; /**< List of unused persistent connections to the server */ private: struct Settings { - mutable std::mutex lock; /**< Protects array-like settings from concurrent access */ - MxsDiskSpaceThreshold disk_space_limits; /**< Disk space thresholds */ + mutable std::mutex lock; /**< Protects array-like settings from concurrent access */ - long persistpoolmax = 0; /**< Maximum size of persistent connections pool */ - long persistmaxtime = 0; /**< Maximum number of seconds connection can live */ + /** Disk space thresholds. Can be queried from modules at any time so access must be protected + * by mutex. */ + MxsDiskSpaceThreshold disk_space_limits; + /** All config settings in text form. This is only read and written from the admin thread + * so no need for locking. */ + std::vector all_parameters; + /** Additional custom parameters which may affect routing decisions or the monitor module. + * Can be queried from modules at any time so access must be protected by mutex. */ + std::map custom_parameters; + + long persistpoolmax = 0; /**< Maximum size of persistent connections pool */ + long persistmaxtime = 0; /**< Maximum number of seconds connection can live */ }; Settings m_settings; /**< Server settings */ @@ -186,3 +236,12 @@ private: }; void server_free(Server* server); +/** + * @brief Convert a server to JSON format + * + * @param server Server to convert + * @param host Hostname of this server + * + * @return JSON representation of server or NULL if an error occurred + */ +json_t* server_to_json(const Server* server, const char* host); diff --git a/server/core/resource.cc b/server/core/resource.cc index dbd48951d..4080c9e04 100644 --- a/server/core/resource.cc +++ b/server/core/resource.cc @@ -548,7 +548,7 @@ HttpResponse cb_all_servers(const HttpRequest& request) HttpResponse cb_get_server(const HttpRequest& request) { - SERVER* server = server_find_by_unique_name(request.uri_part(1).c_str()); + auto server = Server::find_by_unique_name(request.uri_part(1)); mxb_assert(server); return HttpResponse(MHD_HTTP_OK, server_to_json(server, request.host())); } diff --git a/server/core/server.cc b/server/core/server.cc index 5ba518376..e72bcee5a 100644 --- a/server/core/server.cc +++ b/server/core/server.cc @@ -75,8 +75,6 @@ static const char ERR_CANNOT_MODIFY[] = "The server is monitored, so only the ma "set/cleared manually. Status was not modified."; static const char WRN_REQUEST_OVERWRITTEN[] = "Previous maintenance request was not yet read by the monitor " "and was overwritten."; -static void server_parameter_free(SERVER_PARAM* tofree); - Server* Server::server_alloc(const char* name, MXS_CONFIG_PARAMETER* params) { @@ -170,7 +168,11 @@ Server* Server::server_alloc(const char* name, MXS_CONFIG_PARAMETER* params) for (MXS_CONFIG_PARAMETER* p = params; p; p = p->next) { - server_set_parameter(server, p->name, p->value); + server->m_settings.all_parameters.push_back({p->name, p->value}); + if (server->is_custom_parameter(p->name)) + { + server->set_parameter(p->name, p->value); + } } Guard guard(server_lock); @@ -202,7 +204,6 @@ void server_free(Server* server) MXS_FREE(server->protocol); MXS_FREE(server->name); MXS_FREE(server->authenticator); - server_parameter_free(server->parameters); if (server->persistent) { @@ -482,20 +483,14 @@ void Server::print_to_dcb(DCB* dcb) const "\tLast Repl Heartbeat: %s", asctime_r(localtime_r((time_t*)(&server->node_ts), &result), buf)); } - SERVER_PARAM* param; - if ((param = server->parameters)) + + if (!server->m_settings.all_parameters.empty()) { dcb_printf(dcb, "\tServer Parameters:\n"); - while (param) + for (const auto& elem : server->m_settings.all_parameters) { - if (param->active) - { - dcb_printf(dcb, - "\t %s\t%s\n", - param->name, - param->value); - } - param = param->next; + dcb_printf(dcb, "\t %s\t%s\n", + elem.name.c_str(), elem.value.c_str()); } } dcb_printf(dcb, "\tNumber of connections: %d\n", server->stats.n_connections); @@ -789,130 +784,39 @@ void server_update_credentials(SERVER* server, const char* user, const char* pas } } -static SERVER_PARAM* allocate_parameter(const char* name, const char* value) +void Server::set_parameter(const string& name, const string& value) { - char* my_name = MXS_STRDUP(name); - char* my_value = MXS_STRDUP(value); - - SERVER_PARAM* param = (SERVER_PARAM*)MXS_MALLOC(sizeof(SERVER_PARAM)); - - if (!my_name || !my_value || !param) + // Set/add the parameter in both containers + bool found = false; + for (auto& elem : m_settings.all_parameters) { - MXS_FREE(my_name); - MXS_FREE(my_value); - MXS_FREE(param); - return NULL; - } - - param->active = true; - param->name = my_name; - param->value = my_value; - - return param; -} - -bool server_remove_parameter(SERVER* srv, const char* name) -{ - Server* server = static_cast(srv); - bool rval = false; - std::lock_guard guard(server->m_lock); - - for (SERVER_PARAM* p = server->parameters; p; p = p->next) - { - if (strcmp(p->name, name) == 0 && p->active) + if (name == elem.name) { - p->active = false; - rval = true; + found = true; + elem.value = value; // Update break; } } + if (!found) + { + m_settings.all_parameters.push_back({name, value}); + } + std::lock_guard guard(m_settings.lock); + m_settings.custom_parameters[name] = value; +} +string Server::get_custom_parameter(const string& name) const +{ + string rval; + std::lock_guard guard(m_settings.lock); + auto iter = m_settings.custom_parameters.find(name); + if (iter != m_settings.custom_parameters.end()) + { + rval = iter->second; + } return rval; } -void server_set_parameter(SERVER* srv, const char* name, const char* value) -{ - Server* server = static_cast(srv); - SERVER_PARAM* param = allocate_parameter(name, value); - - if (param) - { - std::lock_guard guard(server->m_lock); - - // Insert new value - param->next = server->parameters; - server->parameters = param; - - // Mark old value, if found, as inactive - for (SERVER_PARAM* p = server->parameters->next; p; p = p->next) - { - if (strcmp(p->name, name) == 0 && p->active) - { - p->active = false; - break; - } - } - } -} - -/** - * Free a list of server parameters - * @param tofree Parameter list to free - */ -static void server_parameter_free(SERVER_PARAM* tofree) -{ - SERVER_PARAM* param; - - if (tofree) - { - param = tofree; - tofree = tofree->next; - MXS_FREE(param->name); - MXS_FREE(param->value); - MXS_FREE(param); - } -} - -/** - * Same as server_get_parameter but doesn't lock the server - * - * @note Should only be called when the server is already locked - */ -static size_t server_get_parameter_nolock(const SERVER* server, const char* name, char* out, size_t size) -{ - size_t len = 0; - SERVER_PARAM* param = server->parameters; - - while (param) - { - if (strcmp(param->name, name) == 0 && param->active) - { - len = snprintf(out, out ? size : 0, "%s", param->value); - break; - } - param = param->next; - } - - return len; -} - -/** - * Retrieve a parameter value from a server - * - * @param server The server we are looking for a parameter of - * @param name The name of the parameter we require - * @param out Buffer where value is stored, use NULL to check if the parameter exists - * @param size Size of @c out, ignored if @c out is NULL - * - * @return Length of the parameter value or 0 if parameter was not found - */ -size_t server_get_parameter(const SERVER* srv, const char* name, char* out, size_t size) -{ - const Server* server = static_cast(srv); - std::lock_guard guard(server->m_lock); - return server_get_parameter_nolock(server, name, out, size); -} - /** * Return a resultset that has the current set of servers in it * @@ -1074,53 +978,59 @@ uint64_t server_get_version(const SERVER* server) namespace { -// Converts SERVER_PARAM to MXS_CONFIG_PARAM and keeps them in the same order +// Converts Server::ConfigParam to MXS_CONFIG_PARAM and keeps them in the same order. Required for some +// functions taking MXS_CONFIG_PARAMs as arguments. class ParamAdaptor { public: - ParamAdaptor(SERVER_PARAM* params) + ParamAdaptor(const std::vector& parameters) { - for (auto p = params; p; p = p->next) + for (const auto& elem : parameters) { - if (p->active) - { - // The current tail of the list - auto it = m_params.begin(); + // Allocate and add new head element. + MXS_CONFIG_PARAMETER* new_elem = + static_cast(MXS_MALLOC(sizeof(MXS_CONFIG_PARAMETER))); + new_elem->name = MXS_STRDUP(elem.name.c_str()); + new_elem->value = MXS_STRDUP(elem.value.c_str()); + new_elem->next = m_params; + m_params = new_elem; + } + } - // Push the new tail - m_params.push_front({p->name, p->value, nullptr}); - - if (it != m_params.end()) - { - // Update the old tail to point to the new tail - it->next = &m_params.front(); - } - } + ~ParamAdaptor() + { + while (m_params) + { + auto elem = m_params; + m_params = elem->next; + MXS_FREE(elem->name); + MXS_FREE(elem->value); + MXS_FREE(elem); } } operator MXS_CONFIG_PARAMETER*() { - // Return the head of the parameter list which is the tail of the internal list - return m_params.empty() ? nullptr : &m_params.back(); + return m_params; } private: // Holds the temporary configuration objects. Needs to be a list so that // inserts into the container won't invalidate the next pointers - std::list m_params; + MXS_CONFIG_PARAMETER* m_params = nullptr; }; } /** * Creates a server configuration at the location pointed by @c filename + * TODO: Move to member * * @param server Server to serialize into a configuration * @param filename Filename where configuration is written * @return True on success, false on error */ -static bool create_server_config(const SERVER* server, const char* filename) +bool Server::create_server_config(const Server* server, const char* filename) { int file = open(filename, O_EXCL | O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); @@ -1140,36 +1050,24 @@ static bool create_server_config(const SERVER* server, const char* filename) const MXS_MODULE* mod = get_module(server->protocol, MODULE_PROTOCOL); dump_param_list(file, - ParamAdaptor(server->parameters), + ParamAdaptor(server->m_settings.all_parameters), {CN_TYPE}, config_server_params, mod->parameters); - std::unordered_set known; - - for (auto a : {config_server_params, mod->parameters}) + // Print custom parameters + for (const auto& elem : server->m_settings.custom_parameters) { - for (int i = 0; a[i].name; i++) - { - known.insert(a[i].name); - } - } - - for (auto p = server->parameters; p; p = p->next) - { - if (known.count(p->name) == 0 && p->active) - { - dprintf(file, "%s=%s\n", p->name, p->value); - } + dprintf(file, "%s=%s\n", elem.first.c_str(), elem.second.c_str()); } close(file); - return true; } -bool server_serialize(const SERVER* server) +bool Server::serialize() const { + const Server* server = this; bool rval = false; char filename[PATH_MAX]; snprintf(filename, @@ -1329,7 +1227,8 @@ bool server_is_mxs_service(const SERVER* server) return rval; } -static json_t* server_json_attributes(const SERVER* server) +// TODO: member function +json_t* Server::server_json_attributes(const Server* server) { /** Resource attributes */ json_t* attr = json_object(); @@ -1338,18 +1237,18 @@ static json_t* server_json_attributes(const SERVER* server) json_t* params = json_object(); const MXS_MODULE* mod = get_module(server->protocol, MODULE_PROTOCOL); - config_add_module_params_json(ParamAdaptor(server->parameters), + config_add_module_params_json(ParamAdaptor(server->m_settings.all_parameters), {CN_TYPE}, config_server_params, mod->parameters, params); // Add weighting parameters that weren't added by config_add_module_params_json - for (SERVER_PARAM* p = server->parameters; p; p = p->next) + for (const auto& elem : server->m_settings.custom_parameters) { - if (!json_object_get(params, p->name)) + if (!json_object_get(params, elem.first.c_str())) { - json_object_set_new(params, p->name, json_string(p->value)); + json_object_set_new(params, elem.first.c_str(), json_string(elem.second.c_str())); } } @@ -1402,7 +1301,7 @@ static json_t* server_json_attributes(const SERVER* server) return attr; } -static json_t* server_to_json_data(const SERVER* server, const char* host) +static json_t* server_to_json_data(const Server* server, const char* host) { json_t* rval = json_object(); @@ -1427,13 +1326,13 @@ static json_t* server_to_json_data(const SERVER* server, const char* host) json_object_set_new(rval, CN_RELATIONSHIPS, rel); /** Attributes */ - json_object_set_new(rval, CN_ATTRIBUTES, server_json_attributes(server)); + json_object_set_new(rval, CN_ATTRIBUTES, Server::server_json_attributes(server)); json_object_set_new(rval, CN_LINKS, mxs_json_self_link(host, CN_SERVERS, server->name)); return rval; } -json_t* server_to_json(const SERVER* server, const char* host) +json_t* server_to_json(const Server* server, const char* host) { string self = MXS_JSON_API_SERVERS; self += server->name; @@ -1544,3 +1443,23 @@ Server* Server::find_by_unique_name(const string& name) } return nullptr; } + +bool Server::is_custom_parameter(const string& name) const +{ + for (int i = 0; config_server_params[i].name; i++) + { + if (name == config_server_params[i].name) + { + return false; + } + } + auto module_params = get_module(protocol, MODULE_PROTOCOL)->parameters; + for (int i = 0; module_params[i].name; i++) + { + if (name == module_params[i].name) + { + return false; + } + } + return true; +} \ No newline at end of file diff --git a/server/core/service.cc b/server/core/service.cc index 0b3a16777..1346acb38 100644 --- a/server/core/service.cc +++ b/server/core/service.cc @@ -1319,16 +1319,16 @@ static void service_calculate_weights(SERVICE* service) " and will be removed in a later version of MaxScale.", weightby); - char buf[50]; // Enough to hold most numbers /** Service has a weighting parameter and at least one server */ double total {0}; /** Calculate total weight */ for (SERVER_REF* server = service->dbref; server; server = server->next) { - if (server_get_parameter(server->server, weightby, buf, sizeof(buf))) + string buf = server->server->get_custom_parameter(weightby); + if (!buf.empty()) { - long w = atol(buf); + long w = atol(buf.c_str()); if (w > 0) { total += w; @@ -1348,9 +1348,10 @@ static void service_calculate_weights(SERVICE* service) /** Calculate the relative weight of the servers */ for (SERVER_REF* server = service->dbref; server; server = server->next) { - if (server_get_parameter(server->server, weightby, buf, sizeof(buf))) + string buf = server->server->get_custom_parameter(weightby); + if (!buf.empty()) { - long config_weight = atol(buf); + long config_weight = atol(buf.c_str()); if (config_weight <= 0) { MXS_WARNING("Weighting parameter '%s' is set to %ld for server '%s'." diff --git a/server/core/test/test_server.cc b/server/core/test/test_server.cc index e266e4f6c..c520e203f 100644 --- a/server/core/test/test_server.cc +++ b/server/core/test/test_server.cc @@ -66,13 +66,12 @@ static int test1() Server* server = Server::server_alloc("uniquename", params.params()); mxb_assert_message(server, "Allocating the server should not fail"); - char buf[120]; fprintf(stderr, "\t..done\nTest Parameter for Server."); - mxb_assert_message(!server_get_parameter(server, "name", buf, sizeof(buf)), - "Parameter should be null when not set"); - server_set_parameter(server, "name", "value"); - mxb_assert(server_get_parameter(server, "name", buf, sizeof(buf))); - mxb_assert_message(strcmp("value", buf) == 0, "Parameter should be returned correctly"); + mxb_assert_message(server->get_custom_parameter("name").empty(), + "Parameter should be empty when not set"); + server->set_parameter("name", "value"); + std::string buf = server->get_custom_parameter("name"); + mxb_assert_message(buf == "value", "Parameter should be returned correctly"); fprintf(stderr, "\t..done\nTesting Unique Name for Server."); mxb_assert_message(NULL == server_find_by_unique_name("non-existent"), "Should not find non-existent unique name."); @@ -145,18 +144,18 @@ bool test_serialize() unlink(old_config_name); /** Serialize server to disk */ - TEST(server_serialize(server), "Failed to synchronize original server"); + TEST(server->serialize(), "Failed to synchronize original server"); /** Load it again */ TEST(test_load_config(config_name, server), "Failed to load the serialized server"); /** We should have two identical servers */ - SERVER* created = server_find_by_unique_name(name); + Server* created = Server::find_by_unique_name(name); rename(config_name, old_config_name); /** Serialize the loaded server to disk */ - TEST(server_serialize(created), "Failed to synchronize the copied server"); + TEST(created->serialize(), "Failed to synchronize the copied server"); /** Check that they serialize to identical files */ char cmd[1024]; diff --git a/server/modules/monitor/galeramon/galeramon.cc b/server/modules/monitor/galeramon/galeramon.cc index 6dca00511..6c2a39481 100644 --- a/server/modules/monitor/galeramon/galeramon.cc +++ b/server/modules/monitor/galeramon/galeramon.cc @@ -375,18 +375,20 @@ MXS_MONITORED_SERVER* GaleraMonitor::get_candidate_master() if (!server_is_in_maint(moitor_servers->server) && (moitor_servers->pending_status & SERVER_JOINED)) { - - char buf[50]; // Enough to hold most numbers - if (m_use_priority && server_get_parameter(moitor_servers->server, "priority", buf, sizeof(buf))) + if (m_use_priority) { - /** The server has a priority */ - if ((currval = atoi(buf)) > 0) + std::string buf = moitor_servers->server->get_custom_parameter("priority"); + if (!buf.empty()) { - /** The priority is valid */ - if (currval < minval && currval > 0) + /** The server has a priority */ + if ((currval = atoi(buf.c_str())) > 0) { - minval = currval; - candidate_master = moitor_servers; + /** The priority is valid */ + if (currval < minval && currval > 0) + { + minval = currval; + candidate_master = moitor_servers; + } } } } @@ -527,7 +529,7 @@ void GaleraMonitor::update_sst_donor_nodes(int is_cluster) * the server list will be order by default method. */ - if (m_use_priority && server_get_parameter(ptr->server, "priority", NULL, 0)) + if (m_use_priority && !ptr->server->get_custom_parameter("priority").empty()) { ignore_priority = false; } @@ -641,10 +643,10 @@ static int compare_node_priority(const void* a, const void* b) { const MXS_MONITORED_SERVER* s_a = *(MXS_MONITORED_SERVER* const*)a; const MXS_MONITORED_SERVER* s_b = *(MXS_MONITORED_SERVER* const*)b; - char pri_a[50]; - char pri_b[50]; - bool have_a = server_get_parameter(s_a->server, "priority", pri_a, sizeof(pri_a)); - bool have_b = server_get_parameter(s_b->server, "priority", pri_b, sizeof(pri_b)); + std::string pri_a = s_a->server->get_custom_parameter("priority"); + std::string pri_b = s_b->server->get_custom_parameter("priority"); + bool have_a = !pri_a.empty(); + bool have_b = !pri_b.empty(); /** * Check priority parameter: @@ -672,8 +674,8 @@ static int compare_node_priority(const void* a, const void* b) } /* The given priority is valid */ - int pri_val_a = atoi(pri_a); - int pri_val_b = atoi(pri_b); + int pri_val_a = atoi(pri_a.c_str()); + int pri_val_b = atoi(pri_b.c_str()); /* Return a - b in case of issues */ if ((pri_val_a < INT_MAX && pri_val_a > 0) && !(pri_val_b < INT_MAX && pri_val_b > 0))