ctdb-daemon: Move ctdb_init() to the only place it is used
[vlendec/samba-autobuild/.git] / ctdb / server / ipalloc.c
index 37804ea029e48c578c6d2acf8a22ed3d874990b7..caa50224156eb7a1b8eea5c6e03102c6a7d6fee8 100644 (file)
@@ -29,6 +29,8 @@
 #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 */
@@ -36,7 +38,9 @@ struct ipalloc_state *
 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 =
@@ -48,25 +52,17 @@ ipalloc_state_init(TALLOC_CTX *mem_ctx,
 
        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;
@@ -160,6 +156,58 @@ create_merged_ip_list(struct ipalloc_state *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;
@@ -177,7 +225,6 @@ static bool all_nodes_are_disabled(struct ctdb_node_map *nodemap)
 
 /* 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
@@ -185,40 +232,26 @@ static bool all_nodes_are_disabled(struct ctdb_node_map *nodemap)
  *     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);
                        }
                }
        }
@@ -283,6 +316,10 @@ struct public_ip_list *ipalloc(struct ipalloc_state *ipalloc_state)
                return NULL;
        }
 
+       if (!populate_bitmap(ipalloc_state)) {
+               return NULL;
+       }
+
        switch (ipalloc_state->algorithm) {
        case IPALLOC_LCP2:
                ret = ipalloc_lcp2(ipalloc_state);