add a mechanism to force a node to run the eventscripts with arbitrary arguments
authorRonnie Sahlberg <sahlberg@samba.org>
Wed, 2 Apr 2008 00:13:30 +0000 (11:13 +1100)
committerRonnie Sahlberg <sahlberg@samba.org>
Wed, 2 Apr 2008 00:13:30 +0000 (11:13 +1100)
ctdb eventscript "command argument argument ..."

include/ctdb_private.h
server/ctdb_control.c
server/ctdb_monitor.c
server/eventscript.c
tools/ctdb.c

index b0b1f524054b081a77ff4cefebf92233195504a4..2435b0f4a95fdb8d64f8ecac2e5fff298ee26f60 100644 (file)
@@ -386,6 +386,7 @@ struct ctdb_context {
        struct ctdb_monitor_state *monitor;
        struct ctdb_log_state *log;
        int start_as_disabled;
+       TALLOC_CTX *eventscripts_ctx; /* a context to hold data for the RUN_EVENTSCRIPTS control */
 };
 
 struct ctdb_db_context {
@@ -511,6 +512,7 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS          = 0,
                    CTDB_CONTROL_DISABLE_MONITOR         = 76,
                    CTDB_CONTROL_ADD_PUBLIC_IP           = 77,
                    CTDB_CONTROL_DEL_PUBLIC_IP           = 78,
+                   CTDB_CONTROL_RUN_EVENTSCRIPTS        = 79,
 };     
 
 /*
@@ -1092,6 +1094,8 @@ void ctdb_start_tcp_tickle_update(struct ctdb_context *ctdb);
 void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode);
 void ctdb_start_keepalive(struct ctdb_context *ctdb);
 void ctdb_stop_keepalive(struct ctdb_context *ctdb);
+int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb, struct ctdb_req_control *c, TDB_DATA data, bool *async_reply);
+
 
 void ctdb_daemon_cancel_controls(struct ctdb_context *ctdb, struct ctdb_node *node);
 void ctdb_call_resend_all(struct ctdb_context *ctdb);
index bad1a3795c93a09d5067c68b4d6a0cdb9b8e9f50..9097854e36cd602b3b6c21a1dbfc0f52ee147d9e 100644 (file)
@@ -263,6 +263,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                ctdb_enable_monitoring(ctdb);
                return 0;
        
+       case CTDB_CONTROL_RUN_EVENTSCRIPTS: 
+               return ctdb_run_eventscripts(ctdb, c, indata, async_reply);
+
        case CTDB_CONTROL_DISABLE_MONITOR: 
                CHECK_CONTROL_DATA_SIZE(0);
                ctdb_disable_monitoring(ctdb);
index 523d0ec5c8cf853711ef3c5d69360be6d6a636a8..05e6643af8cccdf10b9919015c80261d57410992 100644 (file)
@@ -268,3 +268,4 @@ int32_t ctdb_monitoring_mode(struct ctdb_context *ctdb)
        }
        return ctdb->monitor->monitoring_mode;
 }
+
index 705cb4b9a658f47e997dff7feaff8b246f54293c..f6afd47800de60154c67f27f99319db8ecdea251 100644 (file)
@@ -367,3 +367,77 @@ int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
 
        return status.status;
 }
+
+
+struct eventscript_callback_state {
+       struct ctdb_req_control *c;
+};
+
+/*
+  called when takeip event finishes
+ */
+static void run_eventscripts_callback(struct ctdb_context *ctdb, int status, 
+                                void *private_data)
+{
+       struct eventscript_callback_state *state = 
+               talloc_get_type(private_data, struct eventscript_callback_state);
+
+       ctdb_enable_monitoring(ctdb);
+
+       if (status != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " Failed to forcibly run eventscripts\n"));
+               ctdb_request_control_reply(ctdb, state->c, NULL, status, NULL);
+               talloc_free(state);
+               return;
+       }
+
+       /* the control succeeded */
+       ctdb_request_control_reply(ctdb, state->c, NULL, 0, NULL);
+       talloc_free(state);
+       return;
+}
+
+/*
+  A control to force running of the eventscripts from the ctdb client tool
+*/
+int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
+               struct ctdb_req_control *c,
+               TDB_DATA indata, bool *async_reply)
+{
+       int ret;
+       struct eventscript_callback_state *state;
+
+       /* kill off any previous invokations of forced eventscripts */
+       if (ctdb->eventscripts_ctx) {
+               talloc_free(ctdb->eventscripts_ctx);
+       }
+       ctdb->eventscripts_ctx = talloc_new(ctdb);
+       CTDB_NO_MEMORY(ctdb, ctdb->eventscripts_ctx);
+
+       state = talloc(ctdb->eventscripts_ctx, struct eventscript_callback_state);
+       CTDB_NO_MEMORY(ctdb, state);
+
+       state->c = talloc_steal(ctdb, c);
+
+       DEBUG(DEBUG_NOTICE,("Forced running of eventscripts with arguments %s\n", indata.dptr));
+
+       ctdb_disable_monitoring(ctdb);
+
+       ret = ctdb_event_script_callback(ctdb, 
+                        timeval_current_ofs(ctdb->tunable.script_timeout, 0),
+                        state, run_eventscripts_callback, state,
+                        (const char *)indata.dptr);
+
+       if (ret != 0) {
+               ctdb_enable_monitoring(ctdb);
+               DEBUG(DEBUG_ERR,(__location__ " Failed to run eventscripts with arguments %s\n", indata.dptr));
+               talloc_free(state);
+               return -1;
+       }
+
+       /* tell ctdb_control.c that we will be replying asynchronously */
+       *async_reply = true;
+
+       return 0;
+}
+
index 537723026d04f1076f74568f1392384426a0d605..df4b703a786e32d1cae26fbaf47fc57c9df8fdad 100644 (file)
@@ -1385,6 +1385,38 @@ static int control_attach(struct ctdb_context *ctdb, int argc, const char **argv
        return 0;
 }
 
+/*
+  dump memory usage
+ */
+static int control_eventscript(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       TDB_DATA data;
+       int ret;
+       int32_t res;
+       char *errmsg;
+       TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+
+       if (argc != 1) {
+               DEBUG(DEBUG_ERR,("Invalid arguments\n"));
+               return -1;
+       }
+
+       data.dptr = (unsigned char *)discard_const(argv[0]);
+       data.dsize = strlen((char *)data.dptr) + 1;
+
+       DEBUG(DEBUG_ERR, ("Running eventscripts with arguments \"%s\" on node %u\n", data.dptr, options.pnn));
+
+       ret = ctdb_control(ctdb, options.pnn, 0, CTDB_CONTROL_RUN_EVENTSCRIPTS,
+                          0, data, tmp_ctx, NULL, &res, NULL, &errmsg);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,("Failed to run eventscripts - %s\n", errmsg));
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+       talloc_free(tmp_ctx);
+       return 0;
+}
+
 /*
   dump memory usage
  */
@@ -1576,6 +1608,7 @@ static const struct {
        { "moveip",          control_moveip,            false, "move/failover an ip address to another node", "<ip> <node>"},
        { "addip",           control_addip,             false, "add a ip address to a node", "<ip/mask> <iface>"},
        { "delip",           control_delip,             false, "delete an ip address from a node", "<ip>"},
+       { "eventscript",     control_eventscript,       false, "run the eventscript with the given parameters on a node", "<arguments>"},
 };
 
 /*