#include "common/logging.h"
#include "common/rb_tree.h"
+#include "protocol/protocol_util.h"
+
#include "server/ipalloc_private.h"
/* Initialise main ipalloc state and sub-structures */
ipalloc_state_init(TALLOC_CTX *mem_ctx,
uint32_t num_nodes,
enum ipalloc_algorithm algorithm,
+ bool no_ip_takeover,
bool no_ip_failback,
+ bool no_ip_host_on_all_disabled,
uint32_t *force_rebalance_nodes)
{
struct ipalloc_state *ipalloc_state =
ipalloc_state->num = num_nodes;
- ipalloc_state->noiptakeover =
- talloc_zero_array(ipalloc_state,
- bool,
- ipalloc_state->num);
- if (ipalloc_state->noiptakeover == NULL) {
- DEBUG(DEBUG_ERR, (__location__ " Out of memory\n"));
- goto fail;
- }
- ipalloc_state->noiphost =
- talloc_zero_array(ipalloc_state,
- bool,
- ipalloc_state->num);
+ ipalloc_state->noiphost = bitmap_talloc(ipalloc_state,
+ ipalloc_state->num);
if (ipalloc_state->noiphost == NULL) {
DEBUG(DEBUG_ERR, (__location__ " Out of memory\n"));
goto fail;
}
ipalloc_state->algorithm = algorithm;
+ ipalloc_state->no_ip_takeover = no_ip_takeover;
ipalloc_state->no_ip_failback = no_ip_failback;
+ ipalloc_state->no_ip_host_on_all_disabled = no_ip_host_on_all_disabled;
ipalloc_state->force_rebalance_nodes = force_rebalance_nodes;
return ipalloc_state;
return ip_list;
}
+static bool populate_bitmap(struct ipalloc_state *ipalloc_state)
+{
+ struct public_ip_list *ip = NULL;
+ int i, j;
+
+ for (ip = ipalloc_state->all_ips; ip != NULL; ip = ip->next) {
+
+ ip->known_on = bitmap_talloc(ip, ipalloc_state->num);
+ if (ip->known_on == NULL) {
+ return false;
+ }
+
+ ip->available_on = bitmap_talloc(ip, ipalloc_state->num);
+ if (ip->available_on == NULL) {
+ return false;
+ }
+
+ for (i = 0; i < ipalloc_state->num; i++) {
+ struct ctdb_public_ip_list *known =
+ &ipalloc_state->known_public_ips[i];
+ struct ctdb_public_ip_list *avail =
+ &ipalloc_state->available_public_ips[i];
+
+ /* Check to see if "ip" is available on node "i" */
+ for (j = 0; j < avail->num; j++) {
+ if (ctdb_sock_addr_same_ip(
+ &ip->addr, &avail->ip[j].addr)) {
+ bitmap_set(ip->available_on, i);
+ break;
+ }
+ }
+
+ /* Optimisation: available => known */
+ if (bitmap_query(ip->available_on, i)) {
+ bitmap_set(ip->known_on, i);
+ continue;
+ }
+
+ /* Check to see if "ip" is known on node "i" */
+ for (j = 0; j < known->num; j++) {
+ if (ctdb_sock_addr_same_ip(
+ &ip->addr, &known->ip[j].addr)) {
+ bitmap_set(ip->known_on, i);
+ break;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
static bool all_nodes_are_disabled(struct ctdb_node_map *nodemap)
{
int i;
/* Set internal flags for IP allocation:
* Clear ip flags
- * Set NOIPTAKOVER ip flags from per-node NoIPTakeover tunable
* Set NOIPHOST ip flag for each INACTIVE node
* if all nodes are disabled:
* Set NOIPHOST ip flags from per-node NoIPHostOnAllDisabled tunable
* Set NOIPHOST ip flags for disabled nodes
*/
void ipalloc_set_node_flags(struct ipalloc_state *ipalloc_state,
- struct ctdb_node_map *nodemap,
- uint32_t *tval_noiptakeover,
- uint32_t *tval_noiphostonalldisabled)
+ struct ctdb_node_map *nodemap)
{
int i;
+ bool all_disabled = all_nodes_are_disabled(nodemap);
for (i=0;i<nodemap->num;i++) {
- /* Can not take IPs on node with NoIPTakeover set */
- if (tval_noiptakeover[i] != 0) {
- ipalloc_state->noiptakeover[i] = true;
- }
-
/* Can not host IPs on INACTIVE node */
if (nodemap->node[i].flags & NODE_FLAGS_INACTIVE) {
- ipalloc_state->noiphost[i] = true;
+ bitmap_set(ipalloc_state->noiphost, i);
}
- }
- if (all_nodes_are_disabled(nodemap)) {
- /* If all nodes are disabled, can not host IPs on node
- * with NoIPHostOnAllDisabled set
- */
- for (i=0;i<nodemap->num;i++) {
- if (tval_noiphostonalldisabled[i] != 0) {
- ipalloc_state->noiphost[i] = true;
- }
- }
- } else {
- /* If some nodes are not disabled, then can not host
- * IPs on DISABLED node
+ /* If node is disabled then it can only host IPs if
+ * all nodes are disabled and NoIPHostOnAllDisabled is
+ * unset
*/
- for (i=0;i<nodemap->num;i++) {
- if (nodemap->node[i].flags & NODE_FLAGS_DISABLED) {
- ipalloc_state->noiphost[i] = true;
+ if (nodemap->node[i].flags & NODE_FLAGS_DISABLED) {
+ if (!(all_disabled &&
+ ipalloc_state->no_ip_host_on_all_disabled == 0)) {
+
+ bitmap_set(ipalloc_state->noiphost, i);
}
}
}
return NULL;
}
+ if (!populate_bitmap(ipalloc_state)) {
+ return NULL;
+ }
+
switch (ipalloc_state->algorithm) {
case IPALLOC_LCP2:
ret = ipalloc_lcp2(ipalloc_state);