ctdb-daemon: Fix signed/unsigned comparisons by declaring as unsigned
[samba.git] / ctdb / server / ctdb_takeover_helper.c
index 14361b4ef2459b4f7e6fed2a2660c80ed2f9c1d9..8740838cfdde7c607b82ddfcf49a3ee672bcc5f7 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "protocol/protocol.h"
 #include "protocol/protocol_api.h"
+#include "protocol/protocol_util.h"
 #include "client/client.h"
 
 #include "common/logging.h"
@@ -91,6 +92,7 @@ struct get_public_ips_state {
        uint32_t *pnns;
        int count;
        struct ctdb_public_ip_list *ips;
+       uint32_t *ban_credits;
 };
 
 static void get_public_ips_done(struct tevent_req *subreq);
@@ -101,6 +103,7 @@ static struct tevent_req *get_public_ips_send(
                                struct ctdb_client_context *client,
                                uint32_t *pnns,
                                int count, int num_nodes,
+                               uint32_t *ban_credits,
                                bool available_only)
 {
        struct tevent_req *req, *subreq;
@@ -114,6 +117,7 @@ static struct tevent_req *get_public_ips_send(
 
        state->pnns = pnns;
        state->count = count;
+       state->ban_credits = ban_credits;
 
        state->ips  = talloc_zero_array(state,
                                        struct ctdb_public_ip_list,
@@ -164,6 +168,7 @@ static void get_public_ips_done(struct tevent_req *subreq)
                                D_ERR("control GET_PUBLIC_IPS failed on "
                                      "node %u, ret=%d\n", pnn, err_list[i]);
 
+                               state->ban_credits[pnn]++;
                                found_errors = true;
                        }
                }
@@ -183,6 +188,7 @@ static void get_public_ips_done(struct tevent_req *subreq)
                if (ret != 0) {
                        D_ERR("control GET_PUBLIC_IPS failed on "
                              "node %u\n", pnn);
+                       state->ban_credits[pnn]++;
                        found_errors = true;
                        continue;
                }
@@ -289,13 +295,20 @@ static struct tevent_req *release_ip_send(TALLOC_CTX *mem_ctx,
                substate->req = req;
 
                substate->ip_str  = ctdb_sock_addr_to_string(substate,
-                                                            &tmp_ip->addr);
+                                                            &tmp_ip->addr,
+                                                            false);
                if (tevent_req_nomem(substate->ip_str, req)) {
                        return tevent_req_post(req, ev);
                }
 
                for (i = 0; i < count; i++) {
                        uint32_t pnn = pnns[i];
+
+                       /* Skip this node if IP is not known */
+                       if (! bitmap_query(tmp_ip->known_on, pnn)) {
+                               continue;
+                       }
+
                        /* If pnn is not the node that should be
                         * hosting the IP then add it to the list of
                         * nodes that need to do a release. */
@@ -467,7 +480,8 @@ static struct tevent_req *take_ip_send(TALLOC_CTX *mem_ctx,
                substate->pnn = tmp_ip->pnn;
 
                substate->ip_str  = ctdb_sock_addr_to_string(substate,
-                                                            &tmp_ip->addr);
+                                                            &tmp_ip->addr,
+                                                            false);
                if (tevent_req_nomem(substate->ip_str, req)) {
                        return tevent_req_post(req, ev);
                }
@@ -658,7 +672,7 @@ static bool ipreallocated_recv(struct tevent_req *req, int *perr)
  * - Get nodemap
  * - Initialise IP allocation state.  Pass:
  *   + algorithm to be used;
- *   + various tunables (NoIPTakeover, NoIPFailback, NoIPHostOnAllDisabled)
+ *   + various tunables (NoIPTakeover, NoIPFailback)
  *   + 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).
@@ -678,7 +692,7 @@ struct takeover_state {
        struct tevent_context *ev;
        struct ctdb_client_context *client;
        struct timeval timeout;
-       int num_nodes;
+       unsigned int num_nodes;
        uint32_t *pnns_connected;
        int num_connected;
        uint32_t *pnns_active;
@@ -785,6 +799,7 @@ static void takeover_nodemap_done(struct tevent_req *subreq)
        bool status;
        int ret;
        struct ctdb_node_map *nodemap;
+       const char *ptr;
 
        status = ctdb_client_control_recv(subreq, &ret, state, &reply);
        TALLOC_FREE(subreq);
@@ -831,7 +846,8 @@ static void takeover_nodemap_done(struct tevent_req *subreq)
                return;
        }
 
-       if (state->tun_list->disable_ip_failover != 0) {
+       ptr = getenv("CTDB_DISABLE_IP_FAILOVER");
+       if (ptr != NULL) {
                /* IP failover is completely disabled so just send out
                 * ipreallocated event.
                 */
@@ -845,17 +861,15 @@ static void takeover_nodemap_done(struct tevent_req *subreq)
                        determine_algorithm(state->tun_list),
                        (state->tun_list->no_ip_takeover != 0),
                        (state->tun_list->no_ip_failback != 0),
-                       (state->tun_list->no_ip_host_on_all_disabled != 0),
                        state->force_rebalance_nodes);
        if (tevent_req_nomem(state->ipalloc_state, req)) {
                return;
        }
 
-       ipalloc_set_node_flags(state->ipalloc_state, nodemap);
-
        subreq = get_public_ips_send(state, state->ev, state->client,
-                                    state->pnns_active, state->num_active,
-                                    state->num_nodes, false);
+                                    state->pnns_connected, state->num_connected,
+                                    state->num_nodes, state->ban_credits,
+                                    false);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -879,7 +893,7 @@ static void takeover_known_ips_done(struct tevent_req *subreq)
 
        if (! status) {
                D_ERR("Failed to fetch known public IPs\n");
-               tevent_req_error(req, ret);
+               takeover_failed(req, ret);
                return;
        }
 
@@ -903,7 +917,8 @@ static void takeover_known_ips_done(struct tevent_req *subreq)
 
        subreq = get_public_ips_send(state, state->ev, state->client,
                                     pnns, count,
-                                    state->num_nodes, true);
+                                    state->num_nodes, state->ban_credits,
+                                    true);
        if (tevent_req_nomem(subreq, req)) {
                return;
        }
@@ -926,7 +941,7 @@ static void takeover_avail_ips_done(struct tevent_req *subreq)
 
        if (! status) {
                D_ERR("Failed to fetch available public IPs\n");
-               tevent_req_error(req, ret);
+               takeover_failed(req, ret);
                return;
        }
 
@@ -1061,8 +1076,8 @@ void takeover_failed(struct tevent_req *req, int ret)
                req, struct takeover_state);
        struct tevent_req *subreq;
        uint32_t max_pnn = CTDB_UNKNOWN_PNN;
-       int max_credits = 0;
-       int pnn;
+       unsigned int max_credits = 0;
+       uint32_t pnn;
 
        /* Check that bans are enabled */
        if (state->tun_list->enable_bans == 0) {