diff options
author | Martin Schwenke <martin@meltin.net> | 2013-02-27 16:01:55 +1100 |
---|---|---|
committer | Martin Schwenke <martin@meltin.net> | 2013-02-27 16:01:55 +1100 |
commit | 8cd6a67b8bf055cae6caf75e4f45602b8f9e4a50 (patch) | |
tree | 07eb1243b6e84722745f28aac81c9b31c57d9104 /ctdb/tools | |
parent | 12d07dd1c6c5130a67530165ec0be6476ecd6024 (diff) | |
download | samba-8cd6a67b8bf055cae6caf75e4f45602b8f9e4a50.tar.gz samba-8cd6a67b8bf055cae6caf75e4f45602b8f9e4a50.tar.xz samba-8cd6a67b8bf055cae6caf75e4f45602b8f9e4a50.zip |
tools/ctdb: delip no longer fails if IP can not be moved
Moving the IP is an optimisation so should not cause failure.
Refactor and simplify the retry-move-IP into new function
try_moveip().
Signed-off-by: Martin Schwenke <martin@meltin.net>
Pair-programmed-with: Amitay Isaacs <amitay@gmail.com>
(This used to be ctdb commit 5402f85dde045576cbaf64e01c68e28ed52204e8)
Diffstat (limited to 'ctdb/tools')
-rw-r--r-- | ctdb/tools/ctdb.c | 159 |
1 files changed, 83 insertions, 76 deletions
diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index fb3df8bf35..ff7dc44d3d 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -1594,13 +1594,88 @@ static int move_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn return 0; } + +/* + * scans all other nodes and returns a pnn for another node that can host this + * ip address or -1 + */ +static int +find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr) +{ + TALLOC_CTX *tmp_ctx = talloc_new(ctdb); + struct ctdb_all_public_ips *ips; + struct ctdb_node_map *nodemap=NULL; + int i, j, ret; + + ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap); + if (ret != 0) { + DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn)); + talloc_free(tmp_ctx); + return ret; + } + + for(i=0;i<nodemap->num;i++){ + if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) { + continue; + } + if (nodemap->nodes[i].pnn == options.pnn) { + continue; + } + + /* read the public ip list from this node */ + ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips); + if (ret != 0) { + DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn)); + return -1; + } + + for (j=0;j<ips->num;j++) { + if (ctdb_same_ip(addr, &ips->ips[j].addr)) { + talloc_free(tmp_ctx); + return nodemap->nodes[i].pnn; + } + } + talloc_free(ips); + } + + talloc_free(tmp_ctx); + return -1; +} + +/* If pnn is -1 then try to find a node to move IP to... */ +static bool try_moveip(struct ctdb_context *ctdb, ctdb_sock_addr *addr, uint32_t pnn) +{ + bool pnn_specified = (pnn == -1 ? false : true); + int retries = 0; + + while (retries < 5) { + if (!pnn_specified) { + pnn = find_other_host_for_public_ip(ctdb, addr); + if (pnn == -1) { + return false; + } + DEBUG(DEBUG_NOTICE, + ("Trying to move public IP to node %u\n", pnn)); + } + + if (move_ip(ctdb, addr, pnn) == 0) { + return true; + } + + sleep(3); + retries++; + } + + return false; +} + + /* move/failover an ip address to a specific node */ 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) { @@ -1619,16 +1694,8 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv return -1; } - 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)); + if (!try_moveip(ctdb, &addr, pnn)) { + DEBUG(DEBUG_ERR,("Failed to move IP to node %d.\n", pnn)); return -1; } @@ -1861,53 +1928,6 @@ control_get_all_public_ips(struct ctdb_context *ctdb, TALLOC_CTX *tmp_ctx, struc } -/* - * scans all other nodes and returns a pnn for another node that can host this - * ip address or -1 - */ -static int -find_other_host_for_public_ip(struct ctdb_context *ctdb, ctdb_sock_addr *addr) -{ - TALLOC_CTX *tmp_ctx = talloc_new(ctdb); - struct ctdb_all_public_ips *ips; - struct ctdb_node_map *nodemap=NULL; - int i, j, ret; - - ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, tmp_ctx, &nodemap); - if (ret != 0) { - DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn)); - talloc_free(tmp_ctx); - return ret; - } - - for(i=0;i<nodemap->num;i++){ - if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) { - continue; - } - if (nodemap->nodes[i].pnn == options.pnn) { - continue; - } - - /* read the public ip list from this node */ - ret = ctdb_ctrl_get_public_ips(ctdb, TIMELIMIT(), nodemap->nodes[i].pnn, tmp_ctx, &ips); - if (ret != 0) { - DEBUG(DEBUG_ERR, ("Unable to get public ip list from node %u\n", nodemap->nodes[i].pnn)); - return -1; - } - - for (j=0;j<ips->num;j++) { - if (ctdb_same_ip(addr, &ips->ips[j].addr)) { - talloc_free(tmp_ctx); - return nodemap->nodes[i].pnn; - } - } - talloc_free(ips); - } - - talloc_free(tmp_ctx); - return -1; -} - static uint32_t ipreallocate_finished; /* @@ -2220,7 +2240,6 @@ 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); @@ -2264,24 +2283,12 @@ static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv) return -1; } + /* This is an optimsation. If this node is hosting the IP + * then try to move it somewhere else without invoking a full + * takeover run. We don't care if this doesn't work! + */ if (ips->ips[i].pnn == options.pnn) { - int pnn; - - pnn = find_other_host_for_public_ip(ctdb, &addr); - if (pnn != -1) { - do { - ret = move_ip(ctdb, &addr, pnn); - 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; - } - } + (void) try_moveip(ctdb, &addr, -1); } ret = ctdb_ctrl_del_public_ip(ctdb, TIMELIMIT(), options.pnn, &pub); |