The branch, master has been updated via 33084a1 ctdb-ipalloc: Drop unnecessary struct ctdb_ipflags via e73496d ctdb-ipalloc: Move memory allocation into ipalloc_state_init() via 47c5e5a ctdb-ipalloc: Have set_ipflags_internal() set ipalloc_state->ipflags via dd163e2 ctdb-ipalloc: Fold IP flags into IP allocation state via 22a930a ctdb-ipalloc: Use number of nodes from IP allocation state via 1316241 ctdb-ipalloc: Allocate memory off IP allocation state via 921e17d ctdb-ipalloc: Add error handling to IP allocation via 25c1093 ctdb-ipalloc: Drop CTDB context argument from set_ipflags_internal() from 0111773 samba-tool:provision: fix bug 11600
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 33084a1c2ce74464e9b6b3e8241a7265c1cfbb66 Author: Martin Schwenke <mar...@meltin.net> Date: Tue Nov 3 16:41:55 2015 +1100 ctdb-ipalloc: Drop unnecessary struct ctdb_ipflags This can be easily decomposed into 2 separate arrays. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Autobuild-User(master): Amitay Isaacs <ami...@samba.org> Autobuild-Date(master): Mon Nov 23 05:34:55 CET 2015 on sn-devel-104 commit e73496d0dc2b8485a808f57d149856baf8a93b72 Author: Martin Schwenke <mar...@meltin.net> Date: Tue Nov 3 16:36:34 2015 +1100 ctdb-ipalloc: Move memory allocation into ipalloc_state_init() This puts all of the memory allocation for ipalloc_state into its init function. This also simplifies the code because set_ipflags_internal() can no longer fail because it no longer allocates memory. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 47c5e5aa14328a4cbe147dd1ef77f6fd9c69fd5c Author: Martin Schwenke <mar...@meltin.net> Date: Tue Nov 3 16:30:23 2015 +1100 ctdb-ipalloc: Have set_ipflags_internal() set ipalloc_state->ipflags This is cleaner than returning ipflags and assigning them into ipalloc_state afterwards. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit dd163e26d90ad8de064496cae6849c0fe83abffc Author: Martin Schwenke <mar...@meltin.net> Date: Mon Nov 2 16:50:05 2015 +1100 ctdb-ipalloc: Fold IP flags into IP allocation state Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 22a930a0454ef9b98d7d004f65fb15359910a3f6 Author: Martin Schwenke <mar...@meltin.net> Date: Tue Nov 3 15:29:30 2015 +1100 ctdb-ipalloc: Use number of nodes from IP allocation state Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 13162419be0f01ea67749390b03466f97fa2df80 Author: Martin Schwenke <mar...@meltin.net> Date: Tue Nov 3 15:26:34 2015 +1100 ctdb-ipalloc: Allocate memory off IP allocation state Instead of local or passed temporary contexts. This has the side effect of making ipalloc_state available inside the modified functions, making future use of ipalloc_state simpler. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 921e17d81ebbcc5ec4531925f108cff37e562845 Author: Martin Schwenke <mar...@meltin.net> Date: Fri Oct 30 11:47:22 2015 +1100 ctdb-ipalloc: Add error handling to IP allocation The only likely failure is out of memory, so just return boolean value. Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> commit 25c10936eb5a800e7f0a5874a4093581ac5da9af Author: Martin Schwenke <mar...@meltin.net> Date: Sat Oct 31 06:48:23 2015 +1100 ctdb-ipalloc: Drop CTDB context argument from set_ipflags_internal() Signed-off-by: Martin Schwenke <mar...@meltin.net> Reviewed-by: Amitay Isaacs <ami...@gmail.com> ----------------------------------------------------------------------- Summary of changes: ctdb/server/ctdb_takeover.c | 203 ++++++++++++++++++----------------- ctdb/tests/src/ctdb_takeover_tests.c | 33 +++--- 2 files changed, 116 insertions(+), 120 deletions(-) Changeset truncated at 500 lines: diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c index d99f9aa..00d35e1 100644 --- a/ctdb/server/ctdb_takeover.c +++ b/ctdb/server/ctdb_takeover.c @@ -48,11 +48,6 @@ #define CTDB_ARP_REPEAT 3 /* Flags used in IP allocation algorithms. */ -struct ctdb_ipflags { - bool noiptakeover; - bool noiphost; -}; - enum ipalloc_algorithm { IPALLOC_DETERMINISTIC, IPALLOC_NONDETERMINISTIC, @@ -65,6 +60,8 @@ struct ipalloc_state { /* Arrays with data for each node */ struct ctdb_public_ip_list_old **known_public_ips; struct ctdb_public_ip_list_old **available_public_ips; + bool *noiptakeover; + bool *noiphost; enum ipalloc_algorithm algorithm; uint32_t no_ip_failback; @@ -1277,13 +1274,12 @@ static int node_ip_coverage(int32_t pnn, struct public_ip_list *ips) */ static bool can_node_host_ip(struct ipalloc_state *ipalloc_state, int32_t pnn, - struct ctdb_ipflags ipflags, struct public_ip_list *ip) { struct ctdb_public_ip_list_old *public_ips; int i; - if (ipflags.noiphost) { + if (ipalloc_state->noiphost[pnn]) { return false; } @@ -1305,14 +1301,13 @@ static bool can_node_host_ip(struct ipalloc_state *ipalloc_state, static bool can_node_takeover_ip(struct ipalloc_state *ipalloc_state, int32_t pnn, - struct ctdb_ipflags ipflags, struct public_ip_list *ip) { - if (ipflags.noiptakeover) { + if (ipalloc_state->noiptakeover[pnn]) { return false; } - return can_node_host_ip(ipalloc_state, pnn, ipflags, ip); + return can_node_host_ip(ipalloc_state, pnn, ip); } /* search the node lists list for a node to takeover this ip. @@ -1320,18 +1315,17 @@ static bool can_node_takeover_ip(struct ipalloc_state *ipalloc_state, so that the ips get spread out evenly. */ static int find_takeover_node(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *ip, struct public_ip_list *all_ips) { int pnn, min=0, num; int i, numnodes; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; pnn = -1; for (i=0; i<numnodes; i++) { /* verify that this node can serve this ip */ - if (!can_node_takeover_ip(ipalloc_state, i, ipflags[i], ip)) { + if (!can_node_takeover_ip(ipalloc_state, i, ip)) { /* no it couldnt so skip to the next node */ continue; } @@ -1626,7 +1620,6 @@ static uint32_t lcp2_imbalance(struct public_ip_list * all_ips, int pnn) * finding the best node for each. */ static void basic_allocate_unassigned(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *all_ips) { struct public_ip_list *tmp_ip; @@ -1636,7 +1629,7 @@ static void basic_allocate_unassigned(struct ipalloc_state *ipalloc_state, */ for (tmp_ip=all_ips;tmp_ip;tmp_ip=tmp_ip->next) { if (tmp_ip->pnn == -1) { - if (find_takeover_node(ipalloc_state, ipflags, + if (find_takeover_node(ipalloc_state, tmp_ip, all_ips)) { DEBUG(DEBUG_WARNING, ("Failed to find node to cover ip %s\n", @@ -1649,7 +1642,6 @@ static void basic_allocate_unassigned(struct ipalloc_state *ipalloc_state, /* Basic non-deterministic rebalancing algorithm. */ static void basic_failback(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *all_ips, int num_ips) { @@ -1657,7 +1649,7 @@ static void basic_failback(struct ipalloc_state *ipalloc_state, int maxnode, maxnum, minnode, minnum, num, retries; struct public_ip_list *tmp_ip; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; retries = 0; try_again: @@ -1682,7 +1674,7 @@ try_again: for (i=0; i<numnodes; i++) { /* only check nodes that can actually serve this ip */ if (!can_node_takeover_ip(ipalloc_state, i, - ipflags[i], tmp_ip)) { + tmp_ip)) { /* no it couldnt so skip to the next node */ continue; } @@ -1728,7 +1720,6 @@ try_again: for (tmp=all_ips;tmp;tmp=tmp->next) { if (tmp->pnn == maxnode) { (void)find_takeover_node(ipalloc_state, - ipflags, tmp, all_ips); retries++; @@ -1739,8 +1730,7 @@ try_again: } } -static void lcp2_init(TALLOC_CTX *tmp_ctx, - struct ctdb_ipflags *ipflags, +static bool lcp2_init(struct ipalloc_state *ipalloc_state, struct public_ip_list *all_ips, uint32_t *force_rebalance_nodes, uint32_t **lcp2_imbalances, @@ -1749,12 +1739,18 @@ static void lcp2_init(TALLOC_CTX *tmp_ctx, int i, numnodes; struct public_ip_list *tmp_ip; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; - *rebalance_candidates = talloc_array(tmp_ctx, bool, numnodes); - CTDB_NO_MEMORY_FATAL(tmp_ctx, *rebalance_candidates); - *lcp2_imbalances = talloc_array(tmp_ctx, uint32_t, numnodes); - CTDB_NO_MEMORY_FATAL(tmp_ctx, *lcp2_imbalances); + *rebalance_candidates = talloc_array(ipalloc_state, bool, numnodes); + if (*rebalance_candidates == NULL) { + DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); + return false; + } + *lcp2_imbalances = talloc_array(ipalloc_state, uint32_t, numnodes); + if (*lcp2_imbalances == NULL) { + DEBUG(DEBUG_ERR, (__location__ " out of memory\n")); + return false; + } for (i=0; i<numnodes; i++) { (*lcp2_imbalances)[i] = lcp2_imbalance(all_ips, i); @@ -1778,7 +1774,7 @@ static void lcp2_init(TALLOC_CTX *tmp_ctx, /* 3rd step: if a node is forced to re-balance then we allow failback onto the node */ if (force_rebalance_nodes == NULL) { - return; + return true; } for (i = 0; i < talloc_array_length(force_rebalance_nodes); i++) { uint32_t pnn = force_rebalance_nodes[i]; @@ -1792,13 +1788,14 @@ static void lcp2_init(TALLOC_CTX *tmp_ctx, ("Forcing rebalancing of IPs to node %u\n", pnn)); (*rebalance_candidates)[pnn] = true; } + + return true; } /* Allocate any unassigned addresses using the LCP2 algorithm to find * the IP/node combination that will cost the least. */ static void lcp2_allocate_unassigned(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *all_ips, uint32_t *lcp2_imbalances) { @@ -1812,7 +1809,7 @@ static void lcp2_allocate_unassigned(struct ipalloc_state *ipalloc_state, bool should_loop = true; bool have_unassigned = true; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; while (have_unassigned && should_loop) { should_loop = false; @@ -1834,7 +1831,6 @@ static void lcp2_allocate_unassigned(struct ipalloc_state *ipalloc_state, /* only check nodes that can actually takeover this ip */ if (!can_node_takeover_ip(ipalloc_state, dstnode, - ipflags[dstnode], tmp_ip)) { /* no it couldnt so skip to the next node */ continue; @@ -1897,7 +1893,6 @@ static void lcp2_allocate_unassigned(struct ipalloc_state *ipalloc_state, * combination to move from the source node. */ static bool lcp2_failback_candidate(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *all_ips, int srcnode, uint32_t *lcp2_imbalances, @@ -1916,7 +1911,7 @@ static bool lcp2_failback_candidate(struct ipalloc_state *ipalloc_state, mindstnode = -1; mindstimbl = 0; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; DEBUG(DEBUG_DEBUG,(" ----------------------------------------\n")); DEBUG(DEBUG_DEBUG,(" CONSIDERING MOVES FROM %d [%d]\n", @@ -1945,7 +1940,7 @@ static bool lcp2_failback_candidate(struct ipalloc_state *ipalloc_state, /* only check nodes that can actually takeover this ip */ if (!can_node_takeover_ip(ipalloc_state, dstnode, - ipflags[dstnode], tmp_ip)) { + tmp_ip)) { /* no it couldnt so skip to the next node */ continue; } @@ -2014,7 +2009,6 @@ static int lcp2_cmp_imbalance_pnn(const void * a, const void * b) * IP/destination node combination to move from the source node. */ static void lcp2_failback(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *all_ips, uint32_t *lcp2_imbalances, bool *rebalance_candidates) @@ -2023,7 +2017,7 @@ static void lcp2_failback(struct ipalloc_state *ipalloc_state, struct lcp2_imbalance_pnn * lips; bool again; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; try_again: /* Put the imbalances and nodes into an array, sort them and @@ -2051,7 +2045,6 @@ try_again: } if (lcp2_failback_candidate(ipalloc_state, - ipflags, all_ips, lips[i].pnn, lcp2_imbalances, @@ -2068,7 +2061,6 @@ try_again: } static void unassign_unsuitable_ips(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, struct public_ip_list *all_ips) { struct public_ip_list *tmp_ip; @@ -2081,7 +2073,7 @@ static void unassign_unsuitable_ips(struct ipalloc_state *ipalloc_state, continue; } if (!can_node_host_ip(ipalloc_state, tmp_ip->pnn, - ipflags[tmp_ip->pnn], tmp_ip) != 0) { + tmp_ip) != 0) { /* this node can not serve this ip. */ DEBUG(DEBUG_DEBUG,("Unassign IP: %s from %d\n", ctdb_addr_to_str(&(tmp_ip->addr)), @@ -2091,14 +2083,13 @@ static void unassign_unsuitable_ips(struct ipalloc_state *ipalloc_state, } } -static void ip_alloc_deterministic_ips(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, +static bool ip_alloc_deterministic_ips(struct ipalloc_state *ipalloc_state, struct public_ip_list *all_ips) { struct public_ip_list *tmp_ip; int i, numnodes; - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; DEBUG(DEBUG_NOTICE,("Deterministic IPs enabled. Resetting all ip allocations\n")); /* Allocate IPs to nodes in a modulo fashion so that IPs will @@ -2118,15 +2109,16 @@ static void ip_alloc_deterministic_ips(struct ipalloc_state *ipalloc_state, DEBUG(DEBUG_WARNING, ("WARNING: 'NoIPFailback' set but ignored - incompatible with 'DeterministicIPs\n")); } - unassign_unsuitable_ips(ipalloc_state, ipflags, all_ips); + unassign_unsuitable_ips(ipalloc_state, all_ips); - basic_allocate_unassigned(ipalloc_state, ipflags, all_ips); + basic_allocate_unassigned(ipalloc_state, all_ips); /* No failback here! */ + + return true; } -static void ip_alloc_nondeterministic_ips(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, +static bool ip_alloc_nondeterministic_ips(struct ipalloc_state *ipalloc_state, struct public_ip_list *all_ips) { /* This should be pushed down into basic_failback. */ @@ -2136,38 +2128,41 @@ static void ip_alloc_nondeterministic_ips(struct ipalloc_state *ipalloc_state, num_ips++; } - unassign_unsuitable_ips(ipalloc_state, ipflags, all_ips); + unassign_unsuitable_ips(ipalloc_state, all_ips); - basic_allocate_unassigned(ipalloc_state, ipflags, all_ips); + basic_allocate_unassigned(ipalloc_state, all_ips); /* If we don't want IPs to fail back then don't rebalance IPs. */ if (1 == ipalloc_state->no_ip_failback) { - return; + return true; } /* Now, try to make sure the ip adresses are evenly distributed across the nodes. */ - basic_failback(ipalloc_state, ipflags, all_ips, num_ips); + basic_failback(ipalloc_state, all_ips, num_ips); + + return true; } -static void ip_alloc_lcp2(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, +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; bool *rebalance_candidates; int numnodes, num_rebalance_candidates, i; + bool ret = true; - TALLOC_CTX *tmp_ctx = talloc_new(ipalloc_state); - - unassign_unsuitable_ips(ipalloc_state, ipflags, all_ips); + unassign_unsuitable_ips(ipalloc_state, all_ips); - lcp2_init(tmp_ctx, ipflags, all_ips,force_rebalance_nodes, - &lcp2_imbalances, &rebalance_candidates); + if (!lcp2_init(ipalloc_state, all_ips,force_rebalance_nodes, + &lcp2_imbalances, &rebalance_candidates)) { + ret = false; + goto finished; + } - lcp2_allocate_unassigned(ipalloc_state, ipflags, all_ips, lcp2_imbalances); + lcp2_allocate_unassigned(ipalloc_state, all_ips, lcp2_imbalances); /* If we don't want IPs to fail back then don't rebalance IPs. */ if (1 == ipalloc_state->no_ip_failback) { @@ -2178,7 +2173,7 @@ static void ip_alloc_lcp2(struct ipalloc_state *ipalloc_state, * nodes to transfer IPs to. This check is much cheaper than * continuing on... */ - numnodes = talloc_array_length(ipflags); + numnodes = ipalloc_state->num; num_rebalance_candidates = 0; for (i=0; i<numnodes; i++) { if (rebalance_candidates[i]) { @@ -2192,11 +2187,11 @@ static void ip_alloc_lcp2(struct ipalloc_state *ipalloc_state, /* Now, try to make sure the ip adresses are evenly distributed across the nodes. */ - lcp2_failback(ipalloc_state, ipflags, all_ips, + lcp2_failback(ipalloc_state, all_ips, lcp2_imbalances, rebalance_candidates); finished: - talloc_free(tmp_ctx); + return ret; } static bool all_nodes_are_disabled(struct ctdb_node_map_old *nodemap) @@ -2214,21 +2209,22 @@ static bool all_nodes_are_disabled(struct ctdb_node_map_old *nodemap) } /* The calculation part of the IP allocation algorithm. */ -static void ctdb_takeover_run_core(struct ipalloc_state *ipalloc_state, - struct ctdb_ipflags *ipflags, +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: - ip_alloc_lcp2(ipalloc_state, ipflags, all_ips, - force_rebalance_nodes); + ret = ip_alloc_lcp2(ipalloc_state, all_ips, + force_rebalance_nodes); break; case IPALLOC_DETERMINISTIC: - ip_alloc_deterministic_ips(ipalloc_state, ipflags, all_ips); + ret = ip_alloc_deterministic_ips(ipalloc_state, all_ips); break; case IPALLOC_NONDETERMINISTIC: - ip_alloc_nondeterministic_ips(ipalloc_state, ipflags, all_ips); + ret = ip_alloc_nondeterministic_ips(ipalloc_state, all_ips); break; } @@ -2236,7 +2232,7 @@ static void ctdb_takeover_run_core(struct ipalloc_state *ipalloc_state, or -1 if there is no node that can cover this ip */ - return; + return ret; } struct get_tunable_callback_data { @@ -2360,29 +2356,22 @@ static uint32_t *get_tunable_from_nodes(struct ctdb_context *ctdb, * else * Set NOIPHOST ip flags for disabled nodes */ -static struct ctdb_ipflags * -set_ipflags_internal(struct ctdb_context *ctdb, - TALLOC_CTX *tmp_ctx, - struct ctdb_node_map_old *nodemap, - uint32_t *tval_noiptakeover, - uint32_t *tval_noiphostonalldisabled) +static void set_ipflags_internal(struct ipalloc_state *ipalloc_state, + struct ctdb_node_map_old *nodemap, + uint32_t *tval_noiptakeover, + uint32_t *tval_noiphostonalldisabled) { int i; - struct ctdb_ipflags *ipflags; - - /* Clear IP flags - implicit due to talloc_zero */ - ipflags = talloc_zero_array(tmp_ctx, struct ctdb_ipflags, nodemap->num); - CTDB_NO_MEMORY_NULL(ctdb, ipflags); for (i=0;i<nodemap->num;i++) { /* Can not take IPs on node with NoIPTakeover set */ if (tval_noiptakeover[i] != 0) { - ipflags[i].noiptakeover = true; + ipalloc_state->noiptakeover[i] = true; } /* Can not host IPs on INACTIVE node */ if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) { - ipflags[i].noiphost = true; + ipalloc_state->noiphost[i] = true; } } @@ -2392,7 +2381,7 @@ set_ipflags_internal(struct ctdb_context *ctdb, */ for (i=0;i<nodemap->num;i++) { if (tval_noiphostonalldisabled[i] != 0) { - ipflags[i].noiphost = true; + ipalloc_state->noiphost[i] = true; } } } else { @@ -2401,45 +2390,41 @@ set_ipflags_internal(struct ctdb_context *ctdb, */ for (i=0;i<nodemap->num;i++) { if (nodemap->nodes[i].flags & NODE_FLAGS_DISABLED) { - ipflags[i].noiphost = true; + ipalloc_state->noiphost[i] = true; } } } - - return ipflags; } -static struct ctdb_ipflags *set_ipflags(struct ctdb_context *ctdb, - TALLOC_CTX *tmp_ctx, - struct ctdb_node_map_old *nodemap) +static bool set_ipflags(struct ctdb_context *ctdb, + struct ipalloc_state *ipalloc_state, + struct ctdb_node_map_old *nodemap) { uint32_t *tval_noiptakeover; uint32_t *tval_noiphostonalldisabled; - struct ctdb_ipflags *ipflags; - - tval_noiptakeover = get_tunable_from_nodes(ctdb, tmp_ctx, nodemap, + tval_noiptakeover = get_tunable_from_nodes(ctdb, ipalloc_state, nodemap, "NoIPTakeover", 0); if (tval_noiptakeover == NULL) { -- Samba Shared Repository