diff options
-rw-r--r-- | ctdb/tests/src/ctdb_test_stubs.c | 23 | ||||
-rwxr-xr-x | ctdb/tests/tool/stubby.natgwlist.009.sh | 36 | ||||
-rwxr-xr-x | ctdb/tests/tool/stubby.natgwlist.010.sh | 37 | ||||
-rw-r--r-- | ctdb/tools/ctdb.c | 80 |
4 files changed, 143 insertions, 33 deletions
diff --git a/ctdb/tests/src/ctdb_test_stubs.c b/ctdb/tests/src/ctdb_test_stubs.c index 6149b3d334..d36fe81567 100644 --- a/ctdb/tests/src/ctdb_test_stubs.c +++ b/ctdb/tests/src/ctdb_test_stubs.c @@ -30,6 +30,10 @@ static struct ctdb_context *ctdb_global; * -CTDB_CAP_RECMASTER. LVS can be faked on by adding * CTDB_CAP_LVS. */ + +/* A fake flag that is only supported by some functions */ +#define NODE_FLAGS_FAKE_TIMEOUT 0x80000000 + void ctdb_test_stubs_read_nodemap(struct ctdb_context *ctdb) { char line[1024]; @@ -95,6 +99,12 @@ void ctdb_test_stubs_read_nodemap(struct ctdb_context *ctdb) capabilities &= ~CTDB_CAP_NATGW; } else if (strcmp(tok, "CTDB_CAP_LVS") == 0) { capabilities |= CTDB_CAP_LVS; + } else if (strcmp(tok, "TIMEOUT") == 0) { + /* This can be done with just a flag + * value but it is probably clearer + * and less error-prone to fake this + * with an explicit token */ + flags |= NODE_FLAGS_FAKE_TIMEOUT; } tok = strtok(NULL, " \t"); } @@ -550,6 +560,19 @@ int ctdb_ctrl_getcapabilities_stub(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *capabilities) { + + if (ctdb->nodes[destnode]->flags & NODE_FLAGS_FAKE_TIMEOUT) { + /* Placeholder for line#, instead of __location__ */ + DEBUG(DEBUG_ERR, + ("__LOCATION__ control timed out." + " reqid:1234567890 opcode:80 dstnode:%d\n", destnode)); + DEBUG(DEBUG_ERR, + ("__LOCATION__ ctdb_control_recv failed\n")); + DEBUG(DEBUG_ERR, + ("__LOCATION__ ctdb_ctrl_getcapabilities_recv failed\n")); + return -1; + } + if (ctdb->nodes[destnode]->flags & NODE_FLAGS_DISCONNECTED) { DEBUG(DEBUG_ERR, ("ctdb_control error: 'ctdb_control to disconnected node\n")); diff --git a/ctdb/tests/tool/stubby.natgwlist.009.sh b/ctdb/tests/tool/stubby.natgwlist.009.sh new file mode 100755 index 0000000000..7534fd220a --- /dev/null +++ b/ctdb/tests/tool/stubby.natgwlist.009.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "3 nodes, all in natgw group, 1 actual time-out" + +setup_natgw <<EOF +192.168.20.41 +192.168.20.42 +192.168.20.43 +EOF + +required_result 255 <<EOF +DATE TIME [PID]: __LOCATION__ control timed out. reqid:1234567890 opcode:80 dstnode:0 +DATE TIME [PID]: __LOCATION__ ctdb_control_recv failed +DATE TIME [PID]: __LOCATION__ ctdb_ctrl_getcapabilities_recv failed +DATE TIME [PID]: Unable to get capabilities from node 0 +EOF + +simple_test <<EOF +NODEMAP +0 192.168.20.41 0x0 TIMEOUT +1 192.168.20.42 0x0 CURRENT RECMASTER +2 192.168.20.43 0x0 + +VNNMAP +654321 +0 +1 +2 + +IFACES +:Name:LinkStatus:References: +:eth2:1:2: +:eth1:1:4: +EOF diff --git a/ctdb/tests/tool/stubby.natgwlist.010.sh b/ctdb/tests/tool/stubby.natgwlist.010.sh new file mode 100755 index 0000000000..aaa3161d0b --- /dev/null +++ b/ctdb/tests/tool/stubby.natgwlist.010.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +. "${TEST_SCRIPTS_DIR}/unit.sh" + +define_test "3 nodes, all in natgw group, 1 potential time-out" + +setup_natgw <<EOF +192.168.20.41 +192.168.20.42 +192.168.20.43 +EOF + +required_result 0 <<EOF +0 192.168.20.41 +Number of nodes:3 +pnn:0 192.168.20.41 OK (THIS NODE) +pnn:1 192.168.20.42 OK +pnn:2 192.168.20.43 OK +EOF + +simple_test <<EOF +NODEMAP +0 192.168.20.41 0x0 CURRENT RECMASTER +1 192.168.20.42 0x0 +2 192.168.20.43 0x0 TIMEOUT + +VNNMAP +654321 +0 +1 +2 + +IFACES +:Name:LinkStatus:References: +:eth2:1:2: +:eth1:1:4: +EOF diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c index 8033fcb7ae..4704726de7 100644 --- a/ctdb/tools/ctdb.c +++ b/ctdb/tools/ctdb.c @@ -1179,7 +1179,8 @@ filter_nodemap_by_addrs(struct ctdb_context *ctdb, static struct ctdb_node_map * filter_nodemap_by_capabilities(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap, - uint32_t required_capabilities) + uint32_t required_capabilities, + bool first_only) { int i; uint32_t capabilities; @@ -1213,6 +1214,9 @@ filter_nodemap_by_capabilities(struct ctdb_context *ctdb, ret->nodes[ret->num] = nodemap->nodes[i]; ret->num++; + if (first_only) { + break; + } } return ret; @@ -1252,7 +1256,7 @@ static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **a int i, ret; struct pnn_node *natgw_nodes = NULL; struct ctdb_node_map *orig_nodemap=NULL; - struct ctdb_node_map *cnodemap, *nodemap; + struct ctdb_node_map *nodemap; uint32_t mypnn, pnn; const char *ip; @@ -1293,21 +1297,15 @@ static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **a goto done; } - /* Get a nodemap that includes only the nodes with the NATGW - * capability */ - cnodemap = filter_nodemap_by_capabilities(ctdb, nodemap, - CTDB_CAP_NATGW); - if (cnodemap == NULL) { - ret = -1; - goto done; - } - ret = 2; /* matches ENOENT */ pnn = -1; ip = "0.0.0.0"; + /* For each flag mask... */ for (i = 0; exclude_flags[i] != 0; i++) { + /* ... get a nodemap that excludes nodes with with + * masked flags... */ struct ctdb_node_map *t = - filter_nodemap_by_flags(ctdb, cnodemap, + filter_nodemap_by_flags(ctdb, nodemap, exclude_flags[i]); if (t == NULL) { /* No memory */ @@ -1315,10 +1313,23 @@ static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **a goto done; } if (t->num > 0) { - ret = 0; - pnn = t->nodes[0].pnn; - ip = ctdb_addr_to_str(&t->nodes[0].addr); - break; + /* ... and find the first node with the NATGW + * capability */ + struct ctdb_node_map *n; + n = filter_nodemap_by_capabilities(ctdb, t, + CTDB_CAP_NATGW, + true); + if (n == NULL) { + /* No memory */ + ret = -1; + goto done; + } + if (n->num > 0) { + ret = 0; + pnn = n->nodes[0].pnn; + ip = ctdb_addr_to_str(&n->nodes[0].addr); + break; + } } talloc_free(t); } @@ -3569,7 +3580,7 @@ static int control_lvs(struct ctdb_context *ctdb, int argc, const char **argv) } nodemap = filter_nodemap_by_capabilities(ctdb, orig_nodemap, - CTDB_CAP_LVS); + CTDB_CAP_LVS, false); if (nodemap == NULL) { /* No memory */ ret = -1; @@ -3609,26 +3620,17 @@ done: static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **argv) { TALLOC_CTX *tmp_ctx = talloc_new(ctdb); - struct ctdb_node_map *orig_nodemap=NULL; - struct ctdb_node_map *nodemap; + struct ctdb_node_map *nodemap=NULL; int i, ret; ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, - tmp_ctx, &orig_nodemap); + tmp_ctx, &nodemap); if (ret != 0) { DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n", options.pnn)); talloc_free(tmp_ctx); return -1; } - nodemap = filter_nodemap_by_capabilities(ctdb, orig_nodemap, - CTDB_CAP_LVS); - if (nodemap == NULL) { - /* No memory */ - ret = -1; - goto done; - } - for (i = 0; lvs_exclude_flags[i] != 0; i++) { struct ctdb_node_map *t = filter_nodemap_by_flags(ctdb, nodemap, @@ -3639,11 +3641,23 @@ static int control_lvsmaster(struct ctdb_context *ctdb, int argc, const char **a goto done; } if (t->num > 0) { - ret = 0; - printf(options.machinereadable ? - "%d\n" : "Node %d is LVS master\n", - t->nodes[0].pnn); - goto done; + struct ctdb_node_map *n; + n = filter_nodemap_by_capabilities(ctdb, + t, + CTDB_CAP_LVS, + true); + if (n == NULL) { + /* No memory */ + ret = -1; + goto done; + } + if (n->num > 0) { + ret = 0; + printf(options.machinereadable ? + "%d\n" : "Node %d is LVS master\n", + n->nodes[0].pnn); + goto done; + } } talloc_free(t); } |