We default to non-deterministic ip now where ips are "sticky" and dont change
[sahlberg/ctdb.git] / tools / ctdb.c
index 5e4b9edd1d4b9d6b5b3457cbe0acd616e56736b1..674622a68afa129dabbf86a5a019f316964d4702 100644 (file)
@@ -1290,6 +1290,7 @@ static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn
 static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        uint32_t pnn;
+       int ret, retries = 0;
        ctdb_sock_addr addr;
 
        if (argc < 2) {
@@ -1308,8 +1309,16 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
                return -1;
        }
 
-       if (move_ip(ctdb, &addr, pnn) != 0) {
-               DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
+       do {
+               ret = move_ip(ctdb, &addr, pnn);
+               if (ret != 0) {
+                       DEBUG(DEBUG_ERR,("Failed to move ip to node %d. Wait 3 second and try again.\n", pnn));
+                       sleep(3);
+                       retries++;
+               }
+       } while (retries < 5 && ret != 0);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,("Failed to move ip to node %d. Giving up.\n", pnn));
                return -1;
        }
 
@@ -1616,8 +1625,7 @@ again:
 static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int i, ret;
-       int len;
-       uint32_t pnn;
+       int len, retries = 0;
        unsigned mask;
        ctdb_sock_addr addr;
        struct ctdb_control_ip_iface *pub;
@@ -1636,23 +1644,28 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
                return -1;
        }
 
-       ret = control_get_all_public_ips(ctdb, tmp_ctx, &ips);
+       /* read the public ip list from the node */
+       ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), options.pnn, tmp_ctx, &ips);
        if (ret != 0) {
-               DEBUG(DEBUG_ERR, ("Unable to get public ip list from cluster\n"));
+               DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", options.pnn));
                talloc_free(tmp_ctx);
-               return ret;
+               return -1;
        }
-
-
-       /* check if some other node is already serving this ip, if not,
-        * we will claim it
-        */
        for (i=0;i<ips->num;i++) {
                if (ctdb_same_ip(&addr, &ips->ips[i].addr)) {
-                       break;
+                       DEBUG(DEBUG_ERR,("Can not add ip to node. Node already hosts this ip\n"));
+                       return 0;
                }
        }
 
+
+
+       /* Dont timeout. This command waits for an ip reallocation
+          which sometimes can take wuite a while if there has
+          been a recent recovery
+       */
+       alarm(0);
+
        len = offsetof(struct ctdb_control_ip_iface, iface) + strlen(argv[1]) + 1;
        pub = talloc_size(tmp_ctx, len); 
        CTDB_NO_MEMORY(ctdb, pub);
@@ -1662,28 +1675,31 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
        pub->len   = strlen(argv[1])+1;
        memcpy(&pub->iface[0], argv[1], strlen(argv[1])+1);
 
-       ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
+       do {
+               ret = ctdb_ctrl_add_public_ip(ctdb, TIMELIMIT(), options.pnn, pub);
+               if (ret != 0) {
+                       DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u. Wait 3 seconds and try again.\n", options.pnn));
+                       sleep(3);
+                       retries++;
+               }
+       } while (retries < 5 && ret != 0);
        if (ret != 0) {
-               DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u\n", options.pnn));
+               DEBUG(DEBUG_ERR, ("Unable to add public ip to node %u. Giving up.\n", options.pnn));
                talloc_free(tmp_ctx);
                return ret;
        }
 
-       if (i == ips->num) {
-               /* no one has this ip so we claim it */
-               pnn  = options.pnn;
-       } else {
-               pnn  = ips->ips[i].pnn;
-       }
-
-       if (move_ip(ctdb, &addr, pnn) != 0) {
-               DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", pnn));
-               return -1;
-       }
-
-       ret = control_ipreallocate(ctdb, argc, argv);
+       do {
+               ret = control_ipreallocate(ctdb, argc, argv);
+               if (ret != 0) {
+                       DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u. Wait 3 seconds and try again.\n", options.pnn));
+                       sleep(3);
+                       retries++;
+               }
+       } while (retries < 5 && ret != 0);
        if (ret != 0) {
-               DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u\n", options.pnn));
+               DEBUG(DEBUG_ERR, ("IP Reallocate failed on node %u. Giving up.\n", options.pnn));
+               talloc_free(tmp_ctx);
                return ret;
        }
 
@@ -1767,6 +1783,7 @@ static int control_delip_all(struct ctdb_context *ctdb, int argc, const char **a
 static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int i, ret;
+       int retries = 0;
        ctdb_sock_addr addr;
        struct ctdb_control_ip_iface pub;
        TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
@@ -1813,8 +1830,16 @@ static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
        if (ips->ips[i].pnn == options.pnn) {
                ret = find_other_host_for_public_ip(ctdb, &addr);
                if (ret != -1) {
-                       if (move_ip(ctdb, &addr, ret) != 0) {
-                               DEBUG(DEBUG_ERR,("Failed to move ip to node %d\n", ret));
+                       do {
+                               ret = move_ip(ctdb, &addr, ret);
+                               if (ret != 0) {
+                                       DEBUG(DEBUG_ERR,("Failed to move ip to node %d. Wait 3 seconds and try again.\n", options.pnn));
+                                       sleep(3);
+                                       retries++;
+                               }
+                       } while (retries < 5 && ret != 0);
+                       if (ret != 0) {
+                               DEBUG(DEBUG_ERR,("Failed to move ip to node %d. Giving up.\n", options.pnn));
                                return -1;
                        }
                }