_exit(1);
}
+/*
+ ctdbd sends us a SIGABRT when we should abort the current script.
+ we abort any active monitor script any time a different event is generated.
+ */
+static void sigabrt(int sig)
+{
+ /* all the child processes will be running in the same process group */
+ kill(-getpgrp(), SIGKILL);
+ _exit(1);
+}
+
struct ctdb_event_script_state {
struct ctdb_context *ctdb;
pid_t child;
int fd[2];
void *private_data;
bool from_user;
+ bool aborted;
enum ctdb_eventscript_call call;
const char *options;
struct timeval timeout;
}
signal(SIGTERM, sigterm);
+ signal(SIGABRT, sigabrt);
return 0;
}
int status;
if (state->child) {
- DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
+ if (state->aborted != True) {
+ DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
- if (kill(state->child, SIGTERM) != 0) {
- DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
+ if (kill(state->child, SIGTERM) != 0) {
+ DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
+ }
+ } else {
+ DEBUG(DEBUG_INFO,(__location__ " Sending SIGABRT to script child pid:%d\n", state->child));
+ if (kill(state->child, SIGABRT) != 0) {
+ DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
+ }
}
}
state->callback = callback;
state->private_data = private_data;
state->from_user = from_user;
+ state->aborted = False;
state->call = call;
state->options = talloc_vasprintf(state, fmt, ap);
state->timeout = timeval_set(ctdb->tunable.script_timeout, 0);
/* Kill off any running monitor events to run this event. */
if (ctdb->current_monitor) {
/* Discard script status so we don't save to last_status */
+ ctdb->current_monitor->aborted = True;
talloc_free(ctdb->current_monitor->scripts);
ctdb->current_monitor->scripts = NULL;
talloc_free(ctdb->current_monitor);