we need to set the port properly in the parse_ip helper
[sahlberg/ctdb.git] / tools / ctdb.c
index 458331f6b98a5bf52375ff66db6e42e8a07cee4f..8fcf95bdac29920569f85a9297a023ba992c7f4b 100644 (file)
 #include "../common/rb_tree.h"
 #include "db_wrap.h"
 
-#define ERR_TIMEOUT    20
+
+#define ERR_TIMEOUT    20      /* timed out trying to reach node */
+#define ERR_NONODE     21      /* node does not exist */
+#define ERR_DISNODE    22      /* node is disconnected */
 
 static void usage(void);
 
@@ -55,6 +58,43 @@ static int control_version(struct ctdb_context *ctdb, int argc, const char **arg
 #endif
 
 
+/*
+  verify that a node exists and is reachable
+ */
+static void verify_node(struct ctdb_context *ctdb)
+{
+       int ret;
+       struct ctdb_node_map *nodemap=NULL;
+
+       if (options.pnn == CTDB_CURRENT_NODE) {
+               return;
+       }
+       if (options.pnn == CTDB_BROADCAST_ALL) {
+               return;
+       }
+
+       /* verify the node exists */
+       if (ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap) != 0) {
+               DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node\n"));
+               exit(10);
+       }
+       if (options.pnn >= nodemap->num) {
+               DEBUG(DEBUG_ERR, ("Node %u does not exist\n", options.pnn));
+               exit(ERR_NONODE);
+       }
+       if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_DISCONNECTED) {
+               DEBUG(DEBUG_ERR, ("Node %u is DISCONNECTED\n", options.pnn));
+               exit(ERR_DISNODE);
+       }
+
+       /* verify we can access the node */
+       ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
+       if (ret == -1) {
+               DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
+               exit(10);
+       }
+}
+
 /*
  check if a database exists
 */
@@ -262,15 +302,9 @@ static int control_statistics_reset(struct ctdb_context *ctdb, int argc, const c
 static int control_uptime(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int ret;
-       int mypnn;
        struct ctdb_uptime *uptime = NULL;
        int tmp, days, hours, minutes, seconds;
 
-       mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
-       if (mypnn == -1) {
-               return -1;
-       }
-
        ret = ctdb_ctrl_uptime(ctdb, ctdb, TIMELIMIT(), options.pnn, &uptime);
        if (ret != 0) {
                DEBUG(DEBUG_ERR, ("Unable to get uptime from node %u\n", options.pnn));
@@ -325,7 +359,7 @@ static int control_pnn(struct ctdb_context *ctdb, int argc, const char **argv)
 {
        int mypnn;
 
-       mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE);
+       mypnn = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
        if (mypnn == -1) {
                DEBUG(DEBUG_ERR, ("Unable to get pnn from local node."));
                return -1;
@@ -437,6 +471,44 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv
        return 0;
 }
 
+
+/*
+  display the status of the monitoring scripts
+ */
+static int control_scriptstatus(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       int i, ret;
+       struct ctdb_monitoring_wire *script_status;
+
+       ret = ctdb_ctrl_getscriptstatus(ctdb, TIMELIMIT(), options.pnn, ctdb, &script_status);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, ("Unable to get script status from node %u\n", options.pnn));
+               return ret;
+       }
+
+       printf("%d scripts were executed last monitoring cycle\n", script_status->num_scripts);
+       for (i=0; i<script_status->num_scripts; i++) {
+               printf("%-20s Status:%s    ",
+                       script_status->scripts[i].name,
+                       script_status->scripts[i].timedout?"TIMEDOUT":script_status->scripts[i].status==0?"OK":"ERROR");
+               if (script_status->scripts[i].timedout == 0) {
+                       printf("Duration:%.3lf ",
+                       timeval_delta(&script_status->scripts[i].finished,
+                             &script_status->scripts[i].start));
+               }
+               printf("%s",
+                       ctime(&script_status->scripts[i].start.tv_sec));
+               if ((script_status->scripts[i].timedout != 0)
+               ||  (script_status->scripts[i].status != 0) ) {
+                       printf("   OUTPUT:%s\n",
+                               script_status->scripts[i].output);
+               }
+       }
+
+       return 0;
+}
+       
+
 /*
   display the pnn of the recovery master
  */
@@ -468,7 +540,7 @@ static int control_get_tickles(struct ctdb_context *ctdb, int argc, const char *
                usage();
        }
 
-       if (parse_ip(argv[0], &addr) == 0) {
+       if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
                DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
                return -1;
        }
@@ -540,7 +612,7 @@ static int control_moveip(struct ctdb_context *ctdb, int argc, const char **argv
                usage();
        }
 
-       if (parse_ip(argv[0], &addr) == 0) {
+       if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
                DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
                return -1;
        }
@@ -775,7 +847,7 @@ static int control_addip(struct ctdb_context *ctdb, int argc, const char **argv)
                usage();
        }
 
-       if (!parse_ip_mask(argv[0], &addr, &mask)) {
+       if (!parse_ip_mask(argv[0], argv[1], &addr, &mask)) {
                DEBUG(DEBUG_ERR, ("Badly formed ip/mask : %s\n", argv[0]));
                talloc_free(tmp_ctx);
                return -1;
@@ -916,7 +988,7 @@ static int control_delip(struct ctdb_context *ctdb, int argc, const char **argv)
                usage();
        }
 
-       if (parse_ip(argv[0], &addr) == 0) {
+       if (parse_ip(argv[0], NULL, 0, &addr) == 0) {
                DEBUG(DEBUG_ERR,("Wrongly formed ip address '%s'\n", argv[0]));
                return -1;
        }
@@ -1014,7 +1086,7 @@ static int control_gratious_arp(struct ctdb_context *ctdb, int argc, const char
                usage();
        }
 
-       if (!parse_ip(argv[0], &addr)) {
+       if (!parse_ip(argv[0], NULL, 0, &addr)) {
                DEBUG(DEBUG_ERR, ("Bad IP '%s'\n", argv[0]));
                return -1;
        }
@@ -1326,17 +1398,6 @@ static int control_ban(struct ctdb_context *ctdb, int argc, const char **argv)
                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);
-       if (ret == -1) {
-               DEBUG(DEBUG_ERR,("Can not ban node. Node is not operational.\n"));
-               return -1;
-       }
 
        if (nodemap->nodes[options.pnn].flags & NODE_FLAGS_BANNED) {
                DEBUG(DEBUG_ERR,("Node %u is already banned.\n", options.pnn));
@@ -1382,13 +1443,6 @@ static int control_unban(struct ctdb_context *ctdb, int argc, const char **argv)
        /* record the current generation number */
        generation = get_generation(ctdb);
 
-       /* verify we can access the node */
-       ret = ctdb_ctrl_getpnn(ctdb, TIMELIMIT(), options.pnn);
-       if (ret == -1) {
-               DEBUG(DEBUG_ERR,("Can not unban node. Node is not operational.\n"));
-               return -1;
-       }
-
        data.dptr = (uint8_t *)&options.pnn;
        data.dsize = sizeof(uint32_t);
 
@@ -2631,6 +2685,7 @@ static const struct {
        { "restoredb",        control_restoredb,          false, "restore the database from a file.", "<file>"},
        { "recmaster",        control_recmaster,          false, "show the pnn for the recovery master."},
        { "setflags",        control_setflags,            false, "set flags for a node in the nodemap.", "<node> <flags>"},
+       { "scriptstatus",        control_scriptstatus,    false, "show the status of the monitoring scripts"},
 };
 
 /*
@@ -2747,6 +2802,9 @@ int main(int argc, const char *argv[])
                exit(1);
        }
 
+       /* verify the node exists */
+       verify_node(ctdb);
+
        for (i=0;i<ARRAY_SIZE(ctdb_commands);i++) {
                if (strcmp(control, ctdb_commands[i].name) == 0) {
                        int j;