This would allow a sysadmin to set up ctdb to send an email/snmptrap/... when the status of the node changes.
[ -z "$CTDB_EVENT_SCRIPT_DIR" ] || CTDB_OPTIONS="$CTDB_OPTIONS --event-script-dir $CTDB_EVENT_SCRIPT_DIR"
[ -z "$CTDB_TRANSPORT" ] || CTDB_OPTIONS="$CTDB_OPTIONS --transport $CTDB_TRANSPORT"
[ -z "$CTDB_DEBUGLEVEL" ] || CTDB_OPTIONS="$CTDB_OPTIONS -d $CTDB_DEBUGLEVEL"
+[ -z "$CTDB_NOTIFY_SCRIPT" ] || CTDB_OPTIONS="$CTDB_OPTIONS --notification-script=$CTDB_NOTIFY_SCRIPT"
[ -z "$CTDB_START_AS_DISABLED" ] || [ "$CTDB_START_AS_DISABLED" != "yes" ] || {
CTDB_OPTIONS="$CTDB_OPTIONS --start-as-disabled"
}
# defaults to /etc/ctdb/nodes
# CTDB_NODES=/etc/ctdb/nodes
+# a script to run when node health changes
+# CTDB_NOTIFY_SCRIPT=/etc/ctdb/notify.sh
+
# the directory to put the local ctdb database files in
# defaults to /var/ctdb
# CTDB_DBDIR=/var/ctdb
void *saved_scheduler_param;
struct _trbt_tree_t *server_ids;
const char *event_script_dir;
+ const char *notification_script;
const char *default_public_interface;
pid_t ctdbd_pid;
pid_t recoverd_pid;
int ctdb_set_public_addresses(struct ctdb_context *ctdb, const char *alist);
int ctdb_set_event_script(struct ctdb_context *ctdb, const char *script);
int ctdb_set_event_script_dir(struct ctdb_context *ctdb, const char *script_dir);
+int ctdb_set_notification_script(struct ctdb_context *ctdb, const char *script);
int ctdb_takeover_run(struct ctdb_context *ctdb, struct ctdb_node_map *nodemap);
int32_t ctdb_control_tcp_client(struct ctdb_context *ctdb, uint32_t client_id,
static void ctdb_check_health(struct event_context *ev, struct timed_event *te,
struct timeval t, void *private_data);
+/*
+ setup the notification script
+*/
+int ctdb_set_notification_script(struct ctdb_context *ctdb, const char *script)
+{
+ ctdb->notification_script = talloc_strdup(ctdb, script);
+ CTDB_NO_MEMORY(ctdb, ctdb->notification_script);
+ return 0;
+}
+
+static int ctdb_run_notification_script_child(struct ctdb_context *ctdb, const char *event)
+{
+ struct stat st;
+ int ret;
+ char *cmd;
+
+ if (stat(ctdb->notification_script, &st) != 0) {
+ DEBUG(DEBUG_ERR,("Could not stat notification script %s. Can not send notifications.\n", ctdb->notification_script));
+ return -1;
+ }
+ if (!(st.st_mode & S_IXUSR)) {
+ DEBUG(DEBUG_ERR,("Notification script %s is not executable.\n", ctdb->notification_script));
+ return -1;
+ }
+
+ cmd = talloc_asprintf(ctdb, "%s %s\n", ctdb->notification_script, event);
+ CTDB_NO_MEMORY(ctdb, cmd);
+
+ ret = system(cmd);
+ /* if the system() call was successful, translate ret into the
+ return code from the command
+ */
+ if (ret != -1) {
+ ret = WEXITSTATUS(ret);
+ }
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,("Notification script \"%s\" failed with error %d\n", cmd, ret));
+ }
+
+ return ret;
+}
+
+static void ctdb_run_notification_script(struct ctdb_context *ctdb, const char *event)
+{
+ pid_t child;
+
+ if (ctdb->notification_script == NULL) {
+ return;
+ }
+
+ child = fork();
+ if (child == (pid_t)-1) {
+ DEBUG(DEBUG_ERR,("Failed to fork() a notification child process\n"));
+ return;
+ }
+ if (child == 0) {
+ int ret;
+
+ ret = ctdb_run_notification_script_child(ctdb, event);
+ if (ret != 0) {
+ DEBUG(DEBUG_ERR,(__location__ " Notification script failed\n"));
+ }
+ _exit(0);
+ }
+
+ return;
+}
+
/*
called when a health monitoring event script finishes
*/
node->flags |= NODE_FLAGS_DISABLED;
}
+ ctdb_run_notification_script(ctdb, "unhealthy");
} else if (status == 0 && (node->flags & NODE_FLAGS_UNHEALTHY)) {
DEBUG(DEBUG_NOTICE,("monitor event OK - node re-enabled\n"));
node->flags &= ~NODE_FLAGS_UNHEALTHY;
ctdb->monitor->next_interval = 1;
+
+ ctdb_run_notification_script(ctdb, "healthy");
}
next_interval = ctdb->monitor->next_interval;
const char *myaddress;
const char *public_address_list;
const char *event_script_dir;
+ const char *notification_script;
const char *logfile;
const char *recovery_lock_file;
const char *db_dir;
{ "logfile", 0, POPT_ARG_STRING, &options.logfile, 0, "log file location", "filename" },
{ "nlist", 0, POPT_ARG_STRING, &options.nlist, 0, "node list file", "filename" },
{ "node-ip", 0, POPT_ARG_STRING, &options.node_ip, 0, "node ip", "ip-address"},
+ { "notification-script", 0, POPT_ARG_STRING, &options.notification_script, 0, "notification script", "filename" },
{ "listen", 0, POPT_ARG_STRING, &options.myaddress, 0, "address to listen on", "address" },
{ "transport", 0, POPT_ARG_STRING, &options.transport, 0, "protocol transport", NULL },
{ "dbdir", 0, POPT_ARG_STRING, &options.db_dir, 0, "directory for the tdb files", NULL },
exit(1);
}
+ if (options.notification_script != NULL) {
+ ret = ctdb_set_notification_script(ctdb, options.notification_script);
+ if (ret == -1) {
+ DEBUG(DEBUG_ALERT,("Unable to setup notification script\n"));
+ exit(1);
+ }
+ }
+
ctdb->do_setsched = !options.no_setsched;
ctdb->do_checkpublicip = !options.no_publicipcheck;