mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
ctdb-ipalloc: Move create_merged_ip_list() into ipalloc
How the existing IP layout is constructed and how the merged IP list is sorted are important aspects of the IP allocation algorithm. Construct the merged IP list when known and available IPs are assigned. Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com>
This commit is contained in:
parent
5c47c35c5a
commit
e8ff433c46
@ -1129,31 +1129,6 @@ int ctdb_set_public_addresses(struct ctdb_context *ctdb, bool check_addresses)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *add_ip_callback(void *parm, void *data)
|
||||
{
|
||||
struct public_ip_list *this_ip = parm;
|
||||
struct public_ip_list *prev_ip = data;
|
||||
|
||||
if (prev_ip == NULL) {
|
||||
return parm;
|
||||
}
|
||||
if (this_ip->pnn == -1) {
|
||||
this_ip->pnn = prev_ip->pnn;
|
||||
}
|
||||
|
||||
return parm;
|
||||
}
|
||||
|
||||
static int getips_count_callback(void *param, void *data)
|
||||
{
|
||||
struct public_ip_list **ip_list = (struct public_ip_list **)param;
|
||||
struct public_ip_list *new_ip = (struct public_ip_list *)data;
|
||||
|
||||
new_ip->next = *ip_list;
|
||||
*ip_list = new_ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ctdb_public_ip_list *
|
||||
ctdb_fetch_remote_public_ips(struct ctdb_context *ctdb,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -1210,61 +1185,6 @@ ctdb_fetch_remote_public_ips(struct ctdb_context *ctdb,
|
||||
return public_ips;
|
||||
}
|
||||
|
||||
static struct public_ip_list *
|
||||
create_merged_ip_list(struct ipalloc_state *ipalloc_state)
|
||||
{
|
||||
int i, j;
|
||||
struct public_ip_list *ip_list;
|
||||
struct ctdb_public_ip_list *public_ips;
|
||||
struct trbt_tree *ip_tree;
|
||||
|
||||
ip_tree = trbt_create(ipalloc_state, 0);
|
||||
|
||||
if (ipalloc_state->known_public_ips == NULL) {
|
||||
DEBUG(DEBUG_ERR, ("Known public IPs not set\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < ipalloc_state->num; i++) {
|
||||
|
||||
public_ips = &ipalloc_state->known_public_ips[i];
|
||||
|
||||
for (j=0; j < public_ips->num; j++) {
|
||||
struct public_ip_list *tmp_ip;
|
||||
|
||||
/* This is returned as part of ip_list */
|
||||
tmp_ip = talloc_zero(ipalloc_state, struct public_ip_list);
|
||||
if (tmp_ip == NULL) {
|
||||
DEBUG(DEBUG_ERR,
|
||||
(__location__ " out of memory\n"));
|
||||
talloc_free(ip_tree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Do not use information about IP addresses hosted
|
||||
* on other nodes, it may not be accurate */
|
||||
if (public_ips->ip[j].pnn == i) {
|
||||
tmp_ip->pnn = public_ips->ip[j].pnn;
|
||||
} else {
|
||||
tmp_ip->pnn = -1;
|
||||
}
|
||||
tmp_ip->addr = public_ips->ip[j].addr;
|
||||
tmp_ip->next = NULL;
|
||||
|
||||
trbt_insertarray32_callback(ip_tree,
|
||||
IP_KEYLEN, ip_key(&public_ips->ip[j].addr),
|
||||
add_ip_callback,
|
||||
tmp_ip);
|
||||
}
|
||||
}
|
||||
|
||||
ip_list = NULL;
|
||||
trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &ip_list);
|
||||
talloc_free(ip_tree);
|
||||
|
||||
return ip_list;
|
||||
}
|
||||
|
||||
static bool all_nodes_are_disabled(struct ctdb_node_map_old *nodemap)
|
||||
{
|
||||
int i;
|
||||
@ -1624,7 +1544,6 @@ static void takeover_run_process_failures(struct ctdb_context *ctdb,
|
||||
* - Use ipalloc_set_public_ips() to set known and available IP
|
||||
addresses for allocation
|
||||
* - If no available IP addresses then early exit
|
||||
* - Build list of (known IPs, currently assigned node)
|
||||
* - Populate list of nodes to force rebalance - internal structure,
|
||||
* currently no way to fetch, only used by LCP2 for nodes that have
|
||||
* had new IP addresses added
|
||||
@ -1717,23 +1636,15 @@ int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map_old *nodem
|
||||
goto ipreallocated;
|
||||
}
|
||||
|
||||
/* since nodes only know about those public addresses that
|
||||
can be served by that particular node, no single node has
|
||||
a full list of all public addresses that exist in the cluster.
|
||||
Walk over all node structures and create a merged list of
|
||||
all public addresses that exist in the cluster.
|
||||
*/
|
||||
all_ips = create_merged_ip_list(ipalloc_state);
|
||||
if (all_ips == NULL) {
|
||||
talloc_free(tmp_ctx);
|
||||
return -1;
|
||||
}
|
||||
ipalloc_state->all_ips = all_ips;
|
||||
|
||||
ipalloc_state->force_rebalance_nodes = force_rebalance_nodes;
|
||||
|
||||
/* Do the IP reassignment calculations */
|
||||
ipalloc(ipalloc_state);
|
||||
if (ipalloc_state->all_ips == NULL) {
|
||||
talloc_free(tmp_ctx);
|
||||
return -1;
|
||||
}
|
||||
all_ips = ipalloc_state->all_ips;
|
||||
|
||||
/* Now tell all nodes to release any public IPs should not
|
||||
* host. This will be a NOOP on nodes that don't currently
|
||||
|
@ -19,15 +19,103 @@
|
||||
along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <talloc.h>
|
||||
|
||||
#include "replace.h"
|
||||
#include "system/network.h"
|
||||
|
||||
#include "lib/util/debug.h"
|
||||
|
||||
#include "common/logging.h"
|
||||
#include "common/rb_tree.h"
|
||||
|
||||
#include "server/ipalloc_private.h"
|
||||
|
||||
static void *add_ip_callback(void *parm, void *data)
|
||||
{
|
||||
struct public_ip_list *this_ip = parm;
|
||||
struct public_ip_list *prev_ip = data;
|
||||
|
||||
if (prev_ip == NULL) {
|
||||
return parm;
|
||||
}
|
||||
if (this_ip->pnn == -1) {
|
||||
this_ip->pnn = prev_ip->pnn;
|
||||
}
|
||||
|
||||
return parm;
|
||||
}
|
||||
|
||||
static int getips_count_callback(void *param, void *data)
|
||||
{
|
||||
struct public_ip_list **ip_list = (struct public_ip_list **)param;
|
||||
struct public_ip_list *new_ip = (struct public_ip_list *)data;
|
||||
|
||||
new_ip->next = *ip_list;
|
||||
*ip_list = new_ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Nodes only know about those public addresses that they are
|
||||
* configured to serve and no individual node has a full list of all
|
||||
* public addresses configured across the cluster. Therefore, a
|
||||
* merged list of all public addresses needs to be built so that IP
|
||||
* allocation can be done. */
|
||||
static struct public_ip_list *
|
||||
create_merged_ip_list(struct ipalloc_state *ipalloc_state)
|
||||
{
|
||||
int i, j;
|
||||
struct public_ip_list *ip_list;
|
||||
struct ctdb_public_ip_list *public_ips;
|
||||
struct trbt_tree *ip_tree;
|
||||
|
||||
ip_tree = trbt_create(ipalloc_state, 0);
|
||||
|
||||
if (ipalloc_state->known_public_ips == NULL) {
|
||||
DEBUG(DEBUG_ERR, ("Known public IPs not set\n"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i < ipalloc_state->num; i++) {
|
||||
|
||||
public_ips = &ipalloc_state->known_public_ips[i];
|
||||
|
||||
for (j=0; j < public_ips->num; j++) {
|
||||
struct public_ip_list *tmp_ip;
|
||||
|
||||
/* This is returned as part of ip_list */
|
||||
tmp_ip = talloc_zero(ipalloc_state, struct public_ip_list);
|
||||
if (tmp_ip == NULL) {
|
||||
DEBUG(DEBUG_ERR,
|
||||
(__location__ " out of memory\n"));
|
||||
talloc_free(ip_tree);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Do not use information about IP addresses hosted
|
||||
* on other nodes, it may not be accurate */
|
||||
if (public_ips->ip[j].pnn == i) {
|
||||
tmp_ip->pnn = public_ips->ip[j].pnn;
|
||||
} else {
|
||||
tmp_ip->pnn = -1;
|
||||
}
|
||||
tmp_ip->addr = public_ips->ip[j].addr;
|
||||
tmp_ip->next = NULL;
|
||||
|
||||
trbt_insertarray32_callback(ip_tree,
|
||||
IP_KEYLEN, ip_key(&public_ips->ip[j].addr),
|
||||
add_ip_callback,
|
||||
tmp_ip);
|
||||
}
|
||||
}
|
||||
|
||||
ip_list = NULL;
|
||||
trbt_traversearray32(ip_tree, IP_KEYLEN, getips_count_callback, &ip_list);
|
||||
talloc_free(ip_tree);
|
||||
|
||||
return ip_list;
|
||||
}
|
||||
|
||||
bool ipalloc_set_public_ips(struct ipalloc_state *ipalloc_state,
|
||||
struct ctdb_public_ip_list *known_ips,
|
||||
struct ctdb_public_ip_list *available_ips)
|
||||
@ -35,7 +123,9 @@ bool ipalloc_set_public_ips(struct ipalloc_state *ipalloc_state,
|
||||
ipalloc_state->known_public_ips = known_ips;
|
||||
ipalloc_state->available_public_ips = available_ips;
|
||||
|
||||
return true;
|
||||
ipalloc_state->all_ips = create_merged_ip_list(ipalloc_state);
|
||||
|
||||
return (ipalloc_state->all_ips != NULL);
|
||||
}
|
||||
|
||||
/* The calculation part of the IP allocation algorithm. */
|
||||
|
@ -318,8 +318,6 @@ static void ctdb_test_init(const char nodestates[],
|
||||
tval_noiptakeover,
|
||||
tval_noiptakeoverondisabled);
|
||||
|
||||
(*ipalloc_state)->all_ips = create_merged_ip_list(*ipalloc_state);
|
||||
|
||||
(*ipalloc_state)->force_rebalance_nodes = NULL;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user