1
0
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:
Martin Schwenke 2016-05-23 20:23:18 +10:00 committed by Amitay Isaacs
parent 5c47c35c5a
commit e8ff433c46
3 changed files with 96 additions and 97 deletions

View File

@ -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

View File

@ -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. */

View File

@ -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;
}