diff options
Diffstat (limited to 'ctdb/server')
-rw-r--r-- | ctdb/server/ctdb_takeover.c | 99 | ||||
-rw-r--r-- | ctdb/server/ipalloc.c | 92 |
2 files changed, 96 insertions, 95 deletions
diff --git a/ctdb/server/ctdb_takeover.c b/ctdb/server/ctdb_takeover.c index b40bbadbf56..c45b218cc38 100644 --- a/ctdb/server/ctdb_takeover.c +++ b/ctdb/server/ctdb_takeover.c @@ -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 diff --git a/ctdb/server/ipalloc.c b/ctdb/server/ipalloc.c index fa2503db42b..d60da0315c8 100644 --- a/ctdb/server/ipalloc.c +++ b/ctdb/server/ipalloc.c @@ -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. */ |