bool *noiptakeover;
bool *noiphost;
+ struct public_ip_list *all_ips;
enum ipalloc_algorithm algorithm;
uint32_t no_ip_failback;
};
so that the ips get spread out evenly.
*/
static int find_takeover_node(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *ip,
- struct public_ip_list *all_ips)
+ struct public_ip_list *ip)
{
int pnn, min=0, num;
int i, numnodes;
continue;
}
- num = node_ip_coverage(i, all_ips);
+ num = node_ip_coverage(i, ipalloc_state->all_ips);
/* was this the first node we checked ? */
if (pnn == -1) {
pnn = i;
/* Allocate any unassigned IPs just by looping through the IPs and
* finding the best node for each.
*/
-static void basic_allocate_unassigned(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips)
+static void basic_allocate_unassigned(struct ipalloc_state *ipalloc_state)
{
struct public_ip_list *t;
/* loop over all ip's and find a physical node to cover for
each unassigned ip.
*/
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
if (t->pnn == -1) {
- if (find_takeover_node(ipalloc_state,
- t, all_ips)) {
+ if (find_takeover_node(ipalloc_state, t)) {
DEBUG(DEBUG_WARNING,
("Failed to find node to cover ip %s\n",
ctdb_addr_to_str(&t->addr)));
/* Basic non-deterministic rebalancing algorithm.
*/
static void basic_failback(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
int num_ips)
{
int i, numnodes;
serving the most and the node serving the least ip's are
not greater than 1.
*/
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
if (t->pnn == -1) {
continue;
}
continue;
}
- num = node_ip_coverage(i, all_ips);
+ num = node_ip_coverage(i, ipalloc_state->all_ips);
if (maxnode == -1) {
maxnode = i;
maxnum = num;
struct public_ip_list *tt;
/* Reassign one of maxnode's VNNs */
- for (tt = all_ips; tt != NULL; tt = tt->next) {
+ for (tt = ipalloc_state->all_ips; tt != NULL; tt = tt->next) {
if (tt->pnn == maxnode) {
(void)find_takeover_node(ipalloc_state,
- tt,
- all_ips);
+ tt);
retries++;
goto try_again;;
}
}
static bool lcp2_init(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
uint32_t *force_rebalance_nodes,
uint32_t **lcp2_imbalances,
bool **rebalance_candidates)
}
for (i=0; i<numnodes; i++) {
- (*lcp2_imbalances)[i] = lcp2_imbalance(all_ips, i);
+ (*lcp2_imbalances)[i] =
+ lcp2_imbalance(ipalloc_state->all_ips, i);
/* First step: assume all nodes are candidates */
(*rebalance_candidates)[i] = true;
}
* keep state and invalidate it every time the recovery master
* changes.
*/
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
if (t->pnn != -1) {
(*rebalance_candidates)[t->pnn] = false;
}
* the IP/node combination that will cost the least.
*/
static void lcp2_allocate_unassigned(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
uint32_t *lcp2_imbalances)
{
struct public_ip_list *t;
minip = NULL;
/* loop over each unassigned ip. */
- for (t = all_ips; t != NULL ; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL ; t = t->next) {
if (t->pnn != -1) {
continue;
}
continue;
}
- dstdsum = ip_distance_2_sum(&(t->addr), all_ips, dstnode);
+ dstdsum = ip_distance_2_sum(&(t->addr),
+ ipalloc_state->all_ips,
+ dstnode);
dstimbl = lcp2_imbalances[dstnode] + dstdsum;
DEBUG(DEBUG_DEBUG,
(" %s -> %d [+%d]\n",
/* There might be a better way but at least this is clear. */
have_unassigned = false;
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
if (t->pnn == -1) {
have_unassigned = true;
}
* well optimise.
*/
if (have_unassigned) {
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
if (t->pnn == -1) {
DEBUG(DEBUG_WARNING,
("Failed to find node to cover ip %s\n",
* combination to move from the source node.
*/
static bool lcp2_failback_candidate(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
int srcnode,
uint32_t *lcp2_imbalances,
bool *rebalance_candidates)
DEBUG(DEBUG_DEBUG,(" CONSIDERING MOVES FROM %d [%d]\n",
srcnode, lcp2_imbalances[srcnode]));
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
/* Only consider addresses on srcnode. */
if (t->pnn != srcnode) {
continue;
}
/* What is this IP address costing the source node? */
- srcdsum = ip_distance_2_sum(&(t->addr), all_ips, srcnode);
+ srcdsum = ip_distance_2_sum(&(t->addr),
+ ipalloc_state->all_ips,
+ srcnode);
srcimbl = lcp2_imbalances[srcnode] - srcdsum;
/* Consider this IP address would cost each potential
continue;
}
- dstdsum = ip_distance_2_sum(&(t->addr), all_ips, dstnode);
+ dstdsum = ip_distance_2_sum(&(t->addr),
+ ipalloc_state->all_ips,
+ dstnode);
dstimbl = lcp2_imbalances[dstnode] + dstdsum;
DEBUG(DEBUG_DEBUG,(" %d [%d] -> %s -> %d [+%d]\n",
srcnode, -srcdsum,
* IP/destination node combination to move from the source node.
*/
static void lcp2_failback(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
uint32_t *lcp2_imbalances,
bool *rebalance_candidates)
{
}
if (lcp2_failback_candidate(ipalloc_state,
- all_ips,
lips[i].pnn,
lcp2_imbalances,
rebalance_candidates)) {
}
}
-static void unassign_unsuitable_ips(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips)
+static void unassign_unsuitable_ips(struct ipalloc_state *ipalloc_state)
{
struct public_ip_list *t;
/* verify that the assigned nodes can serve that public ip
and set it to -1 if not
*/
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
if (t->pnn == -1) {
continue;
}
}
}
-static bool ip_alloc_deterministic_ips(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips)
+static bool ip_alloc_deterministic_ips(struct ipalloc_state *ipalloc_state)
{
struct public_ip_list *t;
int i, numnodes;
* available/unavailable nodes.
*/
- for (i = 0, t = all_ips; t!= NULL; t = t->next, i++) {
+ for (i = 0, t = ipalloc_state->all_ips; t!= NULL; t = t->next, i++) {
t->pnn = i % numnodes;
}
DEBUG(DEBUG_WARNING, ("WARNING: 'NoIPFailback' set but ignored - incompatible with 'DeterministicIPs\n"));
}
- unassign_unsuitable_ips(ipalloc_state, all_ips);
+ unassign_unsuitable_ips(ipalloc_state);
- basic_allocate_unassigned(ipalloc_state, all_ips);
+ basic_allocate_unassigned(ipalloc_state);
/* No failback here! */
return true;
}
-static bool ip_alloc_nondeterministic_ips(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips)
+static bool ip_alloc_nondeterministic_ips(struct ipalloc_state *ipalloc_state)
{
/* This should be pushed down into basic_failback. */
struct public_ip_list *t;
int num_ips = 0;
- for (t = all_ips; t != NULL; t = t->next) {
+ for (t = ipalloc_state->all_ips; t != NULL; t = t->next) {
num_ips++;
}
- unassign_unsuitable_ips(ipalloc_state, all_ips);
+ unassign_unsuitable_ips(ipalloc_state);
- basic_allocate_unassigned(ipalloc_state, all_ips);
+ basic_allocate_unassigned(ipalloc_state);
/* If we don't want IPs to fail back then don't rebalance IPs. */
if (1 == ipalloc_state->no_ip_failback) {
/* Now, try to make sure the ip adresses are evenly distributed
across the nodes.
*/
- basic_failback(ipalloc_state, all_ips, num_ips);
+ basic_failback(ipalloc_state, num_ips);
return true;
}
static bool ip_alloc_lcp2(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
uint32_t *force_rebalance_nodes)
{
uint32_t *lcp2_imbalances;
int numnodes, num_rebalance_candidates, i;
bool ret = true;
- unassign_unsuitable_ips(ipalloc_state, all_ips);
+ unassign_unsuitable_ips(ipalloc_state);
- if (!lcp2_init(ipalloc_state, all_ips,force_rebalance_nodes,
+ if (!lcp2_init(ipalloc_state, force_rebalance_nodes,
&lcp2_imbalances, &rebalance_candidates)) {
ret = false;
goto finished;
}
- lcp2_allocate_unassigned(ipalloc_state, all_ips, lcp2_imbalances);
+ lcp2_allocate_unassigned(ipalloc_state, lcp2_imbalances);
/* If we don't want IPs to fail back then don't rebalance IPs. */
if (1 == ipalloc_state->no_ip_failback) {
/* Now, try to make sure the ip adresses are evenly distributed
across the nodes.
*/
- lcp2_failback(ipalloc_state, all_ips,
- lcp2_imbalances, rebalance_candidates);
+ lcp2_failback(ipalloc_state, lcp2_imbalances, rebalance_candidates);
finished:
return ret;
/* The calculation part of the IP allocation algorithm. */
static bool ctdb_takeover_run_core(struct ipalloc_state *ipalloc_state,
- struct public_ip_list *all_ips,
uint32_t *force_rebalance_nodes)
{
bool ret;
switch (ipalloc_state->algorithm) {
case IPALLOC_LCP2:
- ret = ip_alloc_lcp2(ipalloc_state, all_ips,
- force_rebalance_nodes);
+ ret = ip_alloc_lcp2(ipalloc_state, force_rebalance_nodes);
break;
case IPALLOC_DETERMINISTIC:
- ret = ip_alloc_deterministic_ips(ipalloc_state, all_ips);
+ ret = ip_alloc_deterministic_ips(ipalloc_state);
break;
case IPALLOC_NONDETERMINISTIC:
- ret = ip_alloc_nondeterministic_ips(ipalloc_state, all_ips);
+ ret = ip_alloc_nondeterministic_ips(ipalloc_state);
break;
}
keep the tree of ips around as ctdb->ip_tree
*/
all_ips = create_merged_ip_list(ctdb, ipalloc_state);
+ ipalloc_state->all_ips = all_ips;
/* Do the IP reassignment calculations */
- ctdb_takeover_run_core(ipalloc_state,
- all_ips, force_rebalance_nodes);
+ ctdb_takeover_run_core(ipalloc_state, force_rebalance_nodes);
/* Now tell all nodes to release any public IPs should not
* host. This will be a NOOP on nodes that don't currently
talloc_free(tmp_ctx);
}
-/* Read some IPs from stdin, calculate the sume of the squares of the
+/* Read some IPs from stdin, calculate the sum of the squares of the
* IP distances between the first and the rest, and print it. */
static void ctdb_test_lcp2_imbalance(int pnn)
{
*/
static void ctdb_test_init(const char nodestates[],
struct ctdb_context **ctdb,
- struct public_ip_list **all_ips,
struct ipalloc_state **ipalloc_state,
bool read_ips_for_multiple_nodes)
{
struct ctdb_node_map_old *nodemap;
uint32_t *tval_noiptakeover;
uint32_t *tval_noiptakeoverondisabled;
+ struct public_ip_list *all_ips;
*ctdb = talloc_zero(NULL, struct ctdb_context);
nodemap->num = numnodes;
if (!read_ips_for_multiple_nodes) {
- read_ctdb_public_ip_info(*ctdb, numnodes, all_ips,
- &known, &avail);
+ read_ctdb_public_ip_info(*ctdb, numnodes,
+ &all_ips, &known, &avail);
}
(*ctdb)->nodes = talloc_array(*ctdb, struct ctdb_node *, numnodes); // FIXME: bogus size, overkill
if (read_ips_for_multiple_nodes) {
read_ctdb_public_ip_info(*ctdb, numnodes,
- all_ips, &known, &avail);
+ &all_ips, &known, &avail);
}
(*ctdb)->nodes[i] = talloc(*ctdb, struct ctdb_node);
set_ipflags_internal(*ipalloc_state, nodemap,
tval_noiptakeover,
tval_noiptakeoverondisabled);
+
+ (*ipalloc_state)->all_ips = create_merged_ip_list(*ctdb,
+ *ipalloc_state);
}
/* IP layout is read from stdin. */
static void ctdb_test_lcp2_allocate_unassigned(const char nodestates[])
{
struct ctdb_context *ctdb;
- struct public_ip_list *all_ips;
struct ipalloc_state *ipalloc_state;
uint32_t *lcp2_imbalances;
bool *newly_healthy;
- ctdb_test_init(nodestates, &ctdb, &all_ips, &ipalloc_state,
- false);
+ ctdb_test_init(nodestates, &ctdb, &ipalloc_state, false);
- lcp2_init(ipalloc_state, all_ips, NULL,
- &lcp2_imbalances, &newly_healthy);
+ lcp2_init(ipalloc_state, NULL, &lcp2_imbalances, &newly_healthy);
- lcp2_allocate_unassigned(ipalloc_state,
- all_ips, lcp2_imbalances);
+ lcp2_allocate_unassigned(ipalloc_state, lcp2_imbalances);
- print_ctdb_public_ip_list(all_ips);
+ print_ctdb_public_ip_list(ipalloc_state->all_ips);
talloc_free(ctdb);
}
static void ctdb_test_lcp2_failback(const char nodestates[])
{
struct ctdb_context *ctdb;
- struct public_ip_list *all_ips;
struct ipalloc_state *ipalloc_state;
uint32_t *lcp2_imbalances;
bool *newly_healthy;
- ctdb_test_init(nodestates, &ctdb, &all_ips, &ipalloc_state,
- false);
+ ctdb_test_init(nodestates, &ctdb, &ipalloc_state, false);
- lcp2_init(ipalloc_state, all_ips, NULL,
- &lcp2_imbalances, &newly_healthy);
+ lcp2_init(ipalloc_state, NULL, &lcp2_imbalances, &newly_healthy);
- lcp2_failback(ipalloc_state,
- all_ips, lcp2_imbalances, newly_healthy);
+ lcp2_failback(ipalloc_state, lcp2_imbalances, newly_healthy);
- print_ctdb_public_ip_list(all_ips);
+ print_ctdb_public_ip_list(ipalloc_state->all_ips);
talloc_free(ctdb);
}
static void ctdb_test_lcp2_failback_loop(const char nodestates[])
{
struct ctdb_context *ctdb;
- struct public_ip_list *all_ips;
struct ipalloc_state *ipalloc_state;
uint32_t *lcp2_imbalances;
bool *newly_healthy;
- ctdb_test_init(nodestates, &ctdb, &all_ips, &ipalloc_state,
- false);
+ ctdb_test_init(nodestates, &ctdb, &ipalloc_state, false);
- lcp2_init(ipalloc_state, all_ips, NULL,
- &lcp2_imbalances, &newly_healthy);
+ lcp2_init(ipalloc_state, NULL, &lcp2_imbalances, &newly_healthy);
- lcp2_failback(ipalloc_state,
- all_ips, lcp2_imbalances, newly_healthy);
+ lcp2_failback(ipalloc_state, lcp2_imbalances, newly_healthy);
- print_ctdb_public_ip_list(all_ips);
+ print_ctdb_public_ip_list(ipalloc_state->all_ips);
talloc_free(ctdb);
}
bool read_ips_for_multiple_nodes)
{
struct ctdb_context *ctdb;
- struct public_ip_list *all_ips;
struct ipalloc_state *ipalloc_state;
- ctdb_test_init(nodestates, &ctdb, &all_ips, &ipalloc_state,
+ ctdb_test_init(nodestates, &ctdb, &ipalloc_state,
read_ips_for_multiple_nodes);
- all_ips = create_merged_ip_list(ctdb, ipalloc_state);
-
- ctdb_takeover_run_core(ipalloc_state, all_ips, NULL);
+ ctdb_takeover_run_core(ipalloc_state, NULL);
- print_ctdb_public_ip_list(all_ips);
+ print_ctdb_public_ip_list(ipalloc_state->all_ips);
talloc_free(ctdb);
}