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 {
CTDB_CONTROL_DISABLE_MONITOR = 76,
CTDB_CONTROL_ADD_PUBLIC_IP = 77,
CTDB_CONTROL_DEL_PUBLIC_IP = 78,
+ CTDB_CONTROL_RUN_EVENTSCRIPTS = 79,
};
/*
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);
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);
}
return ctdb->monitor->monitoring_mode;
}
+
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;
+}
+
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
*/
{ "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>"},
};
/*