Skip to content

Commit 1931b01

Browse files
committed
Merge branch 'mysql-8.0' into mysql-8.4
Change-Id: Ib67bd1718480cfd4f59ce76eb1d1bcbebd2306d0
2 parents b2a2ce7 + 852295f commit 1931b01

File tree

2 files changed

+127
-108
lines changed

2 files changed

+127
-108
lines changed

storage/ndb/src/mgmsrv/MgmtSrvr.cpp

Lines changed: 119 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,7 +3501,6 @@ int MgmtSrvr::alloc_node_id_req(NodeId free_node_id,
35013501
}
35023502

35033503
enum class HostnameMatch {
3504-
no_resolve, // failure: could not resolve hostname
35053504
no_match, // failure: hostname does not match socket address
35063505
ok_exact_match, // success: exact match
35073506
ok_wildcard, // success: match not required
@@ -3519,7 +3518,7 @@ static HostnameMatch match_hostname(const ndb_sockaddr *client_addr,
35193518
// - compare the resolved address with the clients.
35203519
ndb_sockaddr resolved_addr;
35213520
if (Ndb_getAddr(&resolved_addr, config_hostname) != 0)
3522-
return HostnameMatch::no_resolve;
3521+
return HostnameMatch::no_match;
35233522

35243523
// Special case for client connecting on loopback address, check if it
35253524
// can use this hostname by trying to bind the configured hostname. If this
@@ -3543,14 +3542,16 @@ static HostnameMatch match_hostname(const ndb_sockaddr *client_addr,
35433542
/**
35443543
@brief Build list of nodes in configuration
35453544
3545+
@param node_id 0 for any, otherwise a specific node id
3546+
@param type Type of nodes to list (MGM/DATA/API)
35463547
@param config_nodes List of nodes
3548+
@param error_code Error code
3549+
@param error_string Error string
35473550
@return true if list was filled properly, false otherwise
35483551
*/
3549-
bool MgmtSrvr::build_node_list_from_config(NodeId node_id,
3550-
ndb_mgm_node_type type,
3551-
Vector<ConfigNode> &config_nodes,
3552-
int &error_code,
3553-
BaseString &error_string) const {
3552+
bool MgmtSrvr::build_node_type_list_from_config(
3553+
NodeId node_id, ndb_mgm_node_type type, Vector<ConfigNode> &config_nodes,
3554+
int &error_code, BaseString &error_string) const {
35543555
Guard g(m_local_config_mutex);
35553556

35563557
ConfigIter iter(m_local_config, CFG_SECTION_NODE);
@@ -3604,13 +3605,42 @@ bool MgmtSrvr::build_node_list_from_config(NodeId node_id,
36043605
return true;
36053606
}
36063607

3607-
int MgmtSrvr::find_node_type(NodeId node_id, ndb_mgm_node_type type,
3608-
const ndb_sockaddr *client_addr,
3609-
const Vector<ConfigNode> &config_nodes,
3610-
Vector<PossibleNode> &nodes, int &error_code,
3611-
BaseString &error_string) {
3612-
const char *found_config_hostname = nullptr;
3613-
bool found_unresolved_hosts = false;
3608+
/**
3609+
Given a list of nodes from config, find all that match the
3610+
supplied client address and (optional) node id
3611+
3612+
@param node_id If non zero then specifies required nodeid. Can only be
3613+
one match.
3614+
If zero then any nodeid matches, return all.
3615+
@param type Type of node being matched (DB|MGMD|API)
3616+
@param client_addr Address client is connecting from
3617+
@param config_nodes List of nodes matching type from config
3618+
@param nodes Output list of nodes matching client address
3619+
*/
3620+
void MgmtSrvr::match_client_addr_to_config_nodes(
3621+
NodeId node_id, ndb_mgm_node_type type, const ndb_sockaddr *client_addr,
3622+
const Vector<ConfigNode> &config_nodes,
3623+
Vector<PossibleNode> &node_matches) {
3624+
/**
3625+
* Examine every candidate node from config to see if it can
3626+
* be a match for the connecting client's address.
3627+
*
3628+
* If node_id is specified then we return the first match.
3629+
* If node_id is not specified then all matches are returned
3630+
*
3631+
* Types of config vs client address match :
3632+
* Wildcard match : Config has no address - matches anything
3633+
* Exact match : Config has address which matches client's when
3634+
* resolved (can also be loopback)
3635+
* No match : Config has address which does not match client's
3636+
* when resolved.
3637+
*
3638+
* The resulting vector of matching nodes can be length :
3639+
* 0 No config nodes match client address
3640+
* 1 One config node matches client address
3641+
* >1 Multiple config nodes match client address
3642+
* Exact matches are placed first in the Vector
3643+
*/
36143644

36153645
for (unsigned i = 0; i < config_nodes.size(); i++) {
36163646
const ConfigNode &node = config_nodes[i];
@@ -3625,97 +3655,35 @@ int MgmtSrvr::find_node_type(NodeId node_id, ndb_mgm_node_type type,
36253655
const HostnameMatch matchType =
36263656
match_hostname(client_addr, config_hostname);
36273657
switch (matchType) {
3628-
case HostnameMatch::no_resolve:
3629-
found_config_hostname = config_hostname;
3630-
found_unresolved_hosts = true;
3631-
break;
3632-
36333658
case HostnameMatch::no_match:
3634-
found_config_hostname = config_hostname;
3659+
/* Config address not resolvable or resolvable and
3660+
* - Client address is loopback but we cannot bind the config address
3661+
* - Client address and resolved config are not IPv6 equal
3662+
*/
36353663
break;
36363664

36373665
case HostnameMatch::ok_wildcard:
3638-
nodes.push_back({current_node_id, "", false});
3666+
/* Config hostname is null or empty */
3667+
node_matches.push_back({current_node_id, "", false});
36393668
break;
36403669

36413670
case HostnameMatch::ok_exact_match: {
3642-
found_config_hostname = config_hostname;
3643-
3671+
/* Config address resolvable
3672+
* - Client address is loopback and we can bind the config address
3673+
* - Client address and resolved config are IPv6 equal
3674+
*/
36443675
unsigned int pos = 0;
36453676
// Insert this node into the list ahead of the non-exact matches
3646-
for (; pos < nodes.size() && nodes[pos].exact_match; pos++)
3677+
for (; pos < node_matches.size() && node_matches[pos].exact_match;
3678+
pos++)
36473679
;
3648-
nodes.push({current_node_id, config_hostname, true}, pos);
3680+
node_matches.push({current_node_id, config_hostname, true}, pos);
36493681
break;
36503682
}
36513683
}
36523684

3653-
if (node_id) break;
3654-
}
3655-
3656-
if (nodes.size() != 0) {
3657-
return 0;
3658-
}
3659-
3660-
if (found_unresolved_hosts) {
3661-
error_code = NDB_MGM_ALLOCID_CONFIG_RETRY;
3662-
3663-
BaseString type_string;
3664-
const char *alias, *str = nullptr;
3665-
char addr_buf[NDB_ADDR_STRLEN];
3666-
alias = ndb_mgm_get_node_type_alias_string(type, &str);
3667-
type_string.assfmt("%s(%s)", alias, str);
3668-
3669-
char *addr_str = Ndb_inet_ntop(client_addr, addr_buf, sizeof(addr_buf));
3670-
3671-
error_string.appfmt(
3672-
"No configured host found of node type %s for "
3673-
"connection from ip %s. Some hostnames are currently "
3674-
"unresolvable. Can be retried.",
3675-
type_string.c_str(), addr_str);
3676-
return -1;
3685+
if (node_id) break; /* Found the only match */
36773686
}
3678-
3679-
/*
3680-
lock on m_configMutex held because found_config_hostname may have
3681-
reference into config structure
3682-
*/
3683-
error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
3684-
if (node_id) {
3685-
if (found_config_hostname) {
3686-
char addr_buf[NDB_ADDR_STRLEN];
3687-
{
3688-
// Append error describing which host the faulty connection was from
3689-
char *addr_str = Ndb_inet_ntop(client_addr, addr_buf, sizeof(addr_buf));
3690-
error_string.appfmt("Connection with id %d done from wrong host ip %s,",
3691-
node_id, addr_str);
3692-
}
3693-
{
3694-
// Append error describing which was the expected host
3695-
ndb_sockaddr config_addr;
3696-
int r_config_addr = Ndb_getAddr(&config_addr, found_config_hostname);
3697-
char *addr_str =
3698-
Ndb_inet_ntop(&config_addr, addr_buf, sizeof(addr_buf));
3699-
error_string.appfmt(" expected %s(%s).", found_config_hostname,
3700-
r_config_addr ? "lookup failed" : addr_str);
3701-
}
3702-
return -1;
3703-
}
3704-
error_string.appfmt("No node defined with id=%d in config file.", node_id);
3705-
return -1;
3706-
}
3707-
3708-
// node_id == 0 and nodes.size() == 0
3709-
if (found_config_hostname) {
3710-
char addr_buf[NDB_ADDR_STRLEN];
3711-
char *addr_str = Ndb_inet_ntop(client_addr, addr_buf, sizeof(addr_buf));
3712-
error_string.appfmt("Connection done from wrong host ip %s.",
3713-
(client_addr) ? addr_str : "");
3714-
return -1;
3715-
}
3716-
3717-
error_string.append("No nodes defined in config file.");
3718-
return -1;
37193687
}
37203688

37213689
int MgmtSrvr::try_alloc(NodeId id, ndb_mgm_node_type type, Uint32 timeout_ms,
@@ -3894,21 +3862,73 @@ bool MgmtSrvr::alloc_node_id_impl(NodeId &nodeid, enum ndb_mgm_node_type type,
38943862
}
38953863
}
38963864

3897-
// Build list of nodes fom configuration, this is done as a separate step
3898-
// in order to hold the config mutex only for a short time and also
3899-
// avoid holding it while resolving addresses.
3865+
// Build list of nodes matching (type[, nodeid]), from configuration,
3866+
// this is done as a separate step in order to hold the config mutex
3867+
// only for a short time and also avoid holding it while resolving
3868+
// addresses.
39003869
Vector<ConfigNode> config_nodes;
3901-
if (!build_node_list_from_config(nodeid, type, config_nodes, error_code,
3902-
error_string)) {
3870+
if (!build_node_type_list_from_config(nodeid, type, config_nodes, error_code,
3871+
error_string)) {
39033872
assert(error_string.length() > 0);
39043873
return false;
39053874
}
39063875

3907-
/* Find possible nodeids */
3876+
if (config_nodes.size() == 0) {
3877+
/* No nodes in config matching type [and nodeid] */
3878+
error_code = NDB_MGM_ALLOCID_CONFIG_MISMATCH;
3879+
if (nodeid != 0) {
3880+
error_string.appfmt("No node defined with id=%d in config file.", nodeid);
3881+
return false;
3882+
} else {
3883+
error_string.append("No nodes defined in config file.");
3884+
return false;
3885+
}
3886+
}
3887+
3888+
/* Choose subset of candidates matching client address */
39083889
Vector<PossibleNode> nodes;
3909-
if (find_node_type(nodeid, type, client_addr, config_nodes, nodes, error_code,
3910-
error_string))
3890+
match_client_addr_to_config_nodes(nodeid, type, client_addr, config_nodes,
3891+
nodes);
3892+
3893+
if (nodes.size() == 0) {
3894+
/**
3895+
* No candidate node ids matched client address
3896+
*
3897+
* This could indicate :
3898+
* 1 Temporary name resolution misalignment
3899+
* 2 Permanent name resolution misalignment
3900+
* 3 Attempt to connect from incorrect location
3901+
*
3902+
* To cover case 1, a temporary 'retry' error is returned rather
3903+
* than a permanent error.
3904+
*/
3905+
error_code = NDB_MGM_ALLOCID_CONFIG_RETRY;
3906+
char addr_buf[NDB_ADDR_STRLEN];
3907+
char *addr_str = Ndb_inet_ntop(client_addr, addr_buf, sizeof(addr_buf));
3908+
3909+
if (nodeid != 0) {
3910+
// Append error describing which host the faulty connection was from
3911+
error_string.appfmt("Connection with id %d done from host ip %s,", nodeid,
3912+
addr_str);
3913+
3914+
// Append error describing which was the expected host
3915+
ndb_sockaddr config_addr;
3916+
assert(config_nodes.size() == 1); /* Single matching nodeid from config */
3917+
const char *config_hostname = config_nodes[0].hostname.c_str();
3918+
int r_config_addr = Ndb_getAddr(&config_addr, config_hostname);
3919+
char *addr_str = Ndb_inet_ntop(&config_addr, addr_buf, sizeof(addr_buf));
3920+
error_string.appfmt(" not matching expected %s(%s).", config_hostname,
3921+
r_config_addr ? "lookup failed" : addr_str);
3922+
} else {
3923+
/* nodeid == 0 */
3924+
error_string.appfmt(
3925+
"Connection done from host ip %s, not matching any (resolved) "
3926+
"configured address.",
3927+
(client_addr) ? addr_str : "");
3928+
}
3929+
39113930
return false;
3931+
}
39123932

39133933
// Print list of possible nodes
39143934
for (unsigned i = 0; i < nodes.size(); i++) {
@@ -3917,7 +3937,7 @@ bool MgmtSrvr::alloc_node_id_impl(NodeId &nodeid, enum ndb_mgm_node_type type,
39173937
node.host.c_str(), node.exact_match);
39183938
}
39193939

3920-
// nodes.size() == 0 handled inside find_node_type
3940+
// nodes.size() == 0 handled above
39213941
assert(nodes.size() != 0);
39223942

39233943
if (type == NDB_MGM_NODE_TYPE_MGM && nodes.size() > 1) {

storage/ndb/src/mgmsrv/MgmtSrvr.hpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -519,15 +519,14 @@ class MgmtSrvr : private ConfigSubscriber, public trp_client {
519519
unsigned nodeid;
520520
BaseString hostname;
521521
};
522-
bool build_node_list_from_config(NodeId node_id, ndb_mgm_node_type type,
523-
Vector<ConfigNode> &config_nodes,
524-
int &error_code,
525-
BaseString &error_string) const;
526-
int find_node_type(NodeId nodeid, ndb_mgm_node_type type,
527-
const ndb_sockaddr *client_addr,
528-
const Vector<ConfigNode> &config_nodes,
529-
Vector<PossibleNode> &nodes, int &error_code,
530-
BaseString &error_string);
522+
bool build_node_type_list_from_config(NodeId node_id, ndb_mgm_node_type type,
523+
Vector<ConfigNode> &config_nodes,
524+
int &error_code,
525+
BaseString &error_string) const;
526+
void match_client_addr_to_config_nodes(NodeId nodeid, ndb_mgm_node_type type,
527+
const ndb_sockaddr *client_addr,
528+
const Vector<ConfigNode> &config_nodes,
529+
Vector<PossibleNode> &nodes);
531530
bool alloc_node_id_impl(NodeId &nodeid, ndb_mgm_node_type type,
532531
const ndb_sockaddr *client_addr, int &error_code,
533532
BaseString &error_string, Uint32 timeout_s = 20);

0 commit comments

Comments
 (0)