summaryrefslogtreecommitdiffstats
path: root/ctdb/tools
diff options
context:
space:
mode:
authorroot <root@test1n1.VSOFS1.COM>2008-12-09 12:03:42 +1100
committerroot <root@test1n1.VSOFS1.COM>2008-12-09 12:03:42 +1100
commit762d4be8f929bba2afb6a02f3620eff636382486 (patch)
tree4e03c9e8e1c7e327b7e7aa920584a59d4f907a4a /ctdb/tools
parent8241d3f9cf8d4140a7fed32d632e8b4b31382116 (diff)
downloadsamba-762d4be8f929bba2afb6a02f3620eff636382486.tar.gz
samba-762d4be8f929bba2afb6a02f3620eff636382486.tar.xz
samba-762d4be8f929bba2afb6a02f3620eff636382486.zip
add a helper that waits until the clueter is no longe rin recovery mode and return the generation number.
change the ban/unban logic to wait until we are not in recovery before it bans/unbans the node. also wait until after the cluster has recovered from the ban/unban before returning so that the cluster is in recpovery mode == normal when the command returns. this makes it much easier to script things ... (This used to be ctdb commit 39c77371a2f995025a584691fe61af12dc6ed5d7)
Diffstat (limited to 'ctdb/tools')
-rw-r--r--ctdb/tools/ctdb.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index 27fa7de2e1..bb663a6767 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/tools/ctdb.c
@@ -1255,6 +1255,49 @@ static int control_enable(struct ctdb_context *ctdb, int argc, const char **argv
return 0;
}
+static uint32_t get_generation(struct ctdb_context *ctdb)
+{
+ struct ctdb_vnn_map *vnnmap=NULL;
+ int ret;
+
+ /* wait until the recmaster is not in recovery mode */
+ while (1) {
+ uint32_t recmode, recmaster;
+
+ if (vnnmap != NULL) {
+ talloc_free(vnnmap);
+ vnnmap = NULL;
+ }
+
+ /* get the recmaster */
+ ret = ctdb_ctrl_getrecmaster(ctdb, ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, &recmaster);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get recmaster from node %u\n", options.pnn));
+ exit(10);
+ }
+
+ /* get recovery mode */
+ ret = ctdb_ctrl_getrecmode(ctdb, ctdb, TIMELIMIT(), recmaster, &recmode);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get recmode from node %u\n", options.pnn));
+ exit(10);
+ }
+
+ /* get the current generation number */
+ ret = ctdb_ctrl_getvnnmap(ctdb, TIMELIMIT(), recmaster, ctdb, &vnnmap);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get vnnmap from recmaster (%u)\n", recmaster));
+ exit(10);
+ }
+
+ if ((recmode == CTDB_RECOVERY_NORMAL)
+ && (vnnmap->generation != 1)){
+ return vnnmap->generation;
+ }
+ sleep(1);
+ }
+}
+
/*
ban a node from the cluster
*/
@@ -1264,10 +1307,27 @@ static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
struct ctdb_ban_info b;
TDB_DATA data;
uint32_t ban_time;
+ struct ctdb_node_map *nodemap=NULL;
+ uint32_t generation, next_generation;
if (argc < 1) {
usage();
}
+
+ /* record the current generation number */
+ generation = get_generation(ctdb);
+
+
+ /* verify the node exists */
+ ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
+ return ret;
+ }
+ if (options.pnn >= nodemap->num) {
+ DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
+ return ret;
+ }
/* verify we can access the node */
ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
@@ -1276,6 +1336,11 @@ static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
return -1;
}
+ if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
+ DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
+ return -1;
+ }
+
ban_time = strtoul(argv[0], NULL, 0);
b.pnn = options.pnn;
@@ -1289,7 +1354,16 @@ static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
DEBUG(DEBUG_ERR,("Failed to ban node %u\n", options.pnn));
return -1;
}
-
+
+ /* wait until we are in a new generation */
+ while (1) {
+ next_generation = get_generation(ctdb);
+ if (next_generation != generation) {
+ return 0;
+ }
+ sleep(1);
+ }
+
return 0;
}
@@ -1301,6 +1375,10 @@ static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
{
int ret;
TDB_DATA data;
+ uint32_t generation, next_generation;
+
+ /* record the current generation number */
+ generation = get_generation(ctdb);
/* verify we can access the node */
ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
@@ -1318,6 +1396,15 @@ static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
return -1;
}
+ /* wait until we are in a new generation */
+ while (1) {
+ next_generation = get_generation(ctdb);
+ if (next_generation != generation) {
+ return 0;
+ }
+ sleep(1);
+ }
+
return 0;
}