mirror of
https://github.com/samba-team/samba.git
synced 2025-03-24 10:50:22 +03:00
change the eventscript handling to allow EventScriptTimeout for each individual script isntead of for the entire set of scripts
restructure the talloc hierarchy to allow this (This used to be ctdb commit 64da4402c6ad485f1d0a604878a7b0c01a0ea5f0)
This commit is contained in:
parent
3526bc830d
commit
e07ca41886
@ -450,8 +450,8 @@ struct ctdb_context {
|
||||
TALLOC_CTX *eventscripts_ctx; /* a context to hold data for the RUN_EVENTSCRIPTS control */
|
||||
uint32_t *recd_ping_count;
|
||||
TALLOC_CTX *release_ips_ctx; /* a context used to automatically drop all IPs if we fail to recover the node */
|
||||
TALLOC_CTX *script_monitoring_ctx; /* a context where we store results while running the monitor event */
|
||||
TALLOC_CTX *last_monitoring_ctx;
|
||||
TALLOC_CTX *script_monitor_ctx; /* a context where we store results while running the monitor event */
|
||||
TALLOC_CTX *last_monitor_ctx;
|
||||
TALLOC_CTX *banning_ctx;
|
||||
};
|
||||
|
||||
|
@ -194,7 +194,7 @@ static void ctdb_startup_callback(struct ctdb_context *ctdb, int status, void *p
|
||||
} else if (status == 0) {
|
||||
DEBUG(DEBUG_NOTICE,("startup event OK - enabling monitoring\n"));
|
||||
ctdb->done_startup = true;
|
||||
ctdb->monitor->next_interval = 1;
|
||||
ctdb->monitor->next_interval = 5;
|
||||
ctdb_run_notification_script(ctdb, "startup");
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ static void ctdb_check_health(struct event_context *ev, struct timed_event *te,
|
||||
struct timeval t, void *private_data)
|
||||
{
|
||||
struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL ||
|
||||
(ctdb->monitor->monitoring_mode == CTDB_MONITORING_DISABLED && ctdb->done_startup)) {
|
||||
@ -223,7 +223,7 @@ static void ctdb_check_health(struct event_context *ev, struct timed_event *te,
|
||||
|
||||
if (!ctdb->done_startup) {
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
ctdb->monitor->monitor_context, ctdb_startup_callback,
|
||||
ctdb, "startup");
|
||||
} else {
|
||||
@ -241,26 +241,26 @@ static void ctdb_check_health(struct event_context *ev, struct timed_event *te,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (skip_monitoring) {
|
||||
if (skip_monitoring != 0) {
|
||||
event_add_timed(ctdb->ev, ctdb->monitor->monitor_context,
|
||||
timeval_current_ofs(ctdb->monitor->next_interval, 0),
|
||||
ctdb_check_health, ctdb);
|
||||
return;
|
||||
} else {
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
ctdb->monitor->monitor_context, ctdb_health_callback,
|
||||
ctdb, "monitor");
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
ctdb->monitor->monitor_context, ctdb_health_callback,
|
||||
ctdb, "monitor");
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
DEBUG(DEBUG_ERR,("Unable to launch monitor event script\n"));
|
||||
ctdb->monitor->next_interval = 1;
|
||||
ctdb->monitor->next_interval = 5;
|
||||
event_add_timed(ctdb->ev, ctdb->monitor->monitor_context,
|
||||
timeval_current_ofs(1, 0),
|
||||
ctdb_check_health, ctdb);
|
||||
}
|
||||
timeval_current_ofs(5, 0),
|
||||
ctdb_check_health, ctdb);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -279,7 +279,7 @@ void ctdb_disable_monitoring(struct ctdb_context *ctdb)
|
||||
void ctdb_enable_monitoring(struct ctdb_context *ctdb)
|
||||
{
|
||||
ctdb->monitor->monitoring_mode = CTDB_MONITORING_ACTIVE;
|
||||
ctdb->monitor->next_interval = 2;
|
||||
ctdb->monitor->next_interval = 5;
|
||||
DEBUG(DEBUG_INFO,("Monitoring has been enabled\n"));
|
||||
}
|
||||
|
||||
@ -292,7 +292,7 @@ void ctdb_stop_monitoring(struct ctdb_context *ctdb)
|
||||
ctdb->monitor->monitor_context = NULL;
|
||||
|
||||
ctdb->monitor->monitoring_mode = CTDB_MONITORING_DISABLED;
|
||||
ctdb->monitor->next_interval = 1;
|
||||
ctdb->monitor->next_interval = 5;
|
||||
DEBUG(DEBUG_NOTICE,("Monitoring has been stopped\n"));
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ void ctdb_start_monitoring(struct ctdb_context *ctdb)
|
||||
ctdb->monitor = talloc(ctdb, struct ctdb_monitor_state);
|
||||
CTDB_NO_MEMORY_FATAL(ctdb, ctdb->monitor);
|
||||
|
||||
ctdb->monitor->next_interval = 1;
|
||||
ctdb->monitor->next_interval = 5;
|
||||
|
||||
ctdb->monitor->monitor_context = talloc_new(ctdb->monitor);
|
||||
CTDB_NO_MEMORY_FATAL(ctdb, ctdb->monitor->monitor_context);
|
||||
|
@ -963,7 +963,7 @@ int32_t ctdb_control_end_recovery(struct ctdb_context *ctdb,
|
||||
ctdb_disable_monitoring(ctdb);
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
state,
|
||||
ctdb_end_recovery_callback,
|
||||
state, "recovered");
|
||||
@ -1017,7 +1017,7 @@ int32_t ctdb_control_start_recovery(struct ctdb_context *ctdb,
|
||||
ctdb_disable_monitoring(ctdb);
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
state,
|
||||
ctdb_start_recovery_callback,
|
||||
state, "startrecovery");
|
||||
@ -1231,7 +1231,7 @@ int32_t ctdb_control_stop_node(struct ctdb_context *ctdb, struct ctdb_req_contro
|
||||
ctdb_disable_monitoring(ctdb);
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
state,
|
||||
ctdb_stop_node_callback,
|
||||
state, "stopped");
|
||||
|
@ -235,7 +235,7 @@ int32_t ctdb_control_takeover_ip(struct ctdb_context *ctdb,
|
||||
vnn->iface));
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
state, takeover_ip_callback, state,
|
||||
"takeip %s %s %u",
|
||||
vnn->iface,
|
||||
@ -391,7 +391,7 @@ int32_t ctdb_control_release_ip(struct ctdb_context *ctdb,
|
||||
state->vnn = vnn;
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
state, release_ip_callback, state,
|
||||
"releaseip %s %s %u",
|
||||
vnn->iface,
|
||||
@ -2094,7 +2094,7 @@ int32_t ctdb_control_del_public_address(struct ctdb_context *ctdb, TDB_DATA inda
|
||||
DLIST_REMOVE(ctdb->vnn, vnn);
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
mem_ctx, delete_ip_callback, mem_ctx,
|
||||
"releaseip %s %s %u",
|
||||
vnn->iface,
|
||||
|
@ -32,6 +32,8 @@ static struct {
|
||||
const char *script_running;
|
||||
} child_state;
|
||||
|
||||
static void ctdb_event_script_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *p);
|
||||
|
||||
/*
|
||||
ctdbd sends us a SIGTERM when we should time out the current script
|
||||
*/
|
||||
@ -63,6 +65,8 @@ struct ctdb_event_script_state {
|
||||
int fd[2];
|
||||
void *private_data;
|
||||
const char *options;
|
||||
struct timed_event *te;
|
||||
struct timeval timeout;
|
||||
};
|
||||
|
||||
|
||||
@ -77,11 +81,12 @@ struct ctdb_monitor_script_status {
|
||||
char *output;
|
||||
};
|
||||
|
||||
struct ctdb_monitoring_status {
|
||||
struct ctdb_monitor_status {
|
||||
struct timeval start;
|
||||
struct timeval finished;
|
||||
int32_t status;
|
||||
struct ctdb_monitor_script_status *scripts;
|
||||
struct ctdb_event_script_state *state;
|
||||
};
|
||||
|
||||
|
||||
@ -90,9 +95,7 @@ struct ctdb_monitoring_status {
|
||||
*/
|
||||
int ctdb_log_event_script_output(struct ctdb_context *ctdb, char *str, uint16_t len)
|
||||
{
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->script_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
struct ctdb_monitor_script_status *script;
|
||||
|
||||
if (monitoring_status == NULL) {
|
||||
@ -118,21 +121,15 @@ int ctdb_log_event_script_output(struct ctdb_context *ctdb, char *str, uint16_t
|
||||
*/
|
||||
int32_t ctdb_control_event_script_init(struct ctdb_context *ctdb)
|
||||
{
|
||||
struct ctdb_monitoring_status *monitoring_status;
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
|
||||
DEBUG(DEBUG_INFO, ("event script init called\n"));
|
||||
if (ctdb->script_monitoring_ctx != NULL) {
|
||||
talloc_free(ctdb->script_monitoring_ctx);
|
||||
ctdb->script_monitoring_ctx = NULL;
|
||||
}
|
||||
|
||||
monitoring_status = talloc_zero(ctdb, struct ctdb_monitoring_status);
|
||||
if (monitoring_status == NULL) {
|
||||
DEBUG(DEBUG_ERR, (__location__ " ERROR: Failed to talloc script_monitoring context\n"));
|
||||
return -1;
|
||||
DEBUG(DEBUG_ERR,(__location__ " Init called when context is NULL\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctdb->script_monitoring_ctx = monitoring_status;
|
||||
monitoring_status->start = timeval_current();
|
||||
|
||||
return 0;
|
||||
@ -145,9 +142,8 @@ int32_t ctdb_control_event_script_init(struct ctdb_context *ctdb)
|
||||
int32_t ctdb_control_event_script_start(struct ctdb_context *ctdb, TDB_DATA indata)
|
||||
{
|
||||
const char *name = (const char *)indata.dptr;
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->script_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
struct ctdb_event_script_state *state;
|
||||
struct ctdb_monitor_script_status *script;
|
||||
|
||||
DEBUG(DEBUG_INFO, ("event script start called : %s\n", name));
|
||||
@ -169,6 +165,19 @@ int32_t ctdb_control_event_script_start(struct ctdb_context *ctdb, TDB_DATA inda
|
||||
script->start = timeval_current();
|
||||
monitoring_status->scripts = script;
|
||||
|
||||
state = monitoring_status->state;
|
||||
if (state != NULL) {
|
||||
/* reset the timeout for the next eventscript */
|
||||
if (!timeval_is_zero(&state->timeout)) {
|
||||
if (state->te != NULL) {
|
||||
talloc_free(state->te);
|
||||
state->te = NULL;
|
||||
}
|
||||
state->te = event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -178,9 +187,7 @@ int32_t ctdb_control_event_script_start(struct ctdb_context *ctdb, TDB_DATA inda
|
||||
int32_t ctdb_control_event_script_stop(struct ctdb_context *ctdb, TDB_DATA indata)
|
||||
{
|
||||
int32_t res = *((int32_t *)indata.dptr);
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->script_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
struct ctdb_monitor_script_status *script;
|
||||
|
||||
if (monitoring_status == NULL) {
|
||||
@ -207,9 +214,7 @@ int32_t ctdb_control_event_script_stop(struct ctdb_context *ctdb, TDB_DATA indat
|
||||
int32_t ctdb_control_event_script_disabled(struct ctdb_context *ctdb, TDB_DATA indata)
|
||||
{
|
||||
const char *name = (const char *)indata.dptr;
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->script_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
struct ctdb_monitor_script_status *script;
|
||||
|
||||
DEBUG(DEBUG_INFO, ("event script disabed called for script %s\n", name));
|
||||
@ -237,9 +242,7 @@ int32_t ctdb_control_event_script_disabled(struct ctdb_context *ctdb, TDB_DATA i
|
||||
*/
|
||||
int32_t ctdb_control_event_script_finished(struct ctdb_context *ctdb)
|
||||
{
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->script_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
|
||||
DEBUG(DEBUG_INFO, ("event script finished called\n"));
|
||||
|
||||
@ -250,11 +253,13 @@ int32_t ctdb_control_event_script_finished(struct ctdb_context *ctdb)
|
||||
|
||||
monitoring_status->finished = timeval_current();
|
||||
monitoring_status->status = MONITOR_SCRIPT_OK;
|
||||
if (ctdb->last_monitoring_ctx) {
|
||||
talloc_free(ctdb->last_monitoring_ctx);
|
||||
|
||||
if (ctdb->last_monitor_ctx) {
|
||||
talloc_free(ctdb->last_monitor_ctx);
|
||||
ctdb->last_monitor_ctx = NULL;
|
||||
}
|
||||
ctdb->last_monitoring_ctx = ctdb->script_monitoring_ctx;
|
||||
ctdb->script_monitoring_ctx = NULL;
|
||||
ctdb->last_monitor_ctx = talloc_steal(ctdb, ctdb->script_monitor_ctx);
|
||||
ctdb->script_monitor_ctx = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -298,9 +303,7 @@ static struct ctdb_monitoring_wire *marshall_monitoring_scripts(TALLOC_CTX *mem_
|
||||
|
||||
int32_t ctdb_control_get_event_script_status(struct ctdb_context *ctdb, TDB_DATA *outdata)
|
||||
{
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->last_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->last_monitor_ctx;
|
||||
struct ctdb_monitoring_wire *monitoring_scripts;
|
||||
|
||||
if (monitoring_status == NULL) {
|
||||
@ -627,8 +630,6 @@ static void ctdb_event_script_handler(struct event_context *ev, struct fd_event
|
||||
{
|
||||
struct ctdb_event_script_state *state =
|
||||
talloc_get_type(p, struct ctdb_event_script_state);
|
||||
void (*callback)(struct ctdb_context *, int, void *) = state->callback;
|
||||
void *private_data = state->private_data;
|
||||
struct ctdb_context *ctdb = state->ctdb;
|
||||
signed char rt = -1;
|
||||
|
||||
@ -636,10 +637,13 @@ static void ctdb_event_script_handler(struct event_context *ev, struct fd_event
|
||||
|
||||
DEBUG(DEBUG_INFO,(__location__ " Eventscript %s finished with state %d\n", state->options, rt));
|
||||
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, rt, state->private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
|
||||
talloc_set_destructor(state, NULL);
|
||||
talloc_free(state);
|
||||
callback(ctdb, rt, private_data);
|
||||
|
||||
ctdb->event_script_timeouts = 0;
|
||||
}
|
||||
|
||||
@ -663,19 +667,20 @@ static void ctdb_event_script_timeout(struct event_context *ev, struct timed_eve
|
||||
struct timeval t, void *p)
|
||||
{
|
||||
struct ctdb_event_script_state *state = talloc_get_type(p, struct ctdb_event_script_state);
|
||||
void (*callback)(struct ctdb_context *, int, void *) = state->callback;
|
||||
void *private_data = state->private_data;
|
||||
struct ctdb_context *ctdb = state->ctdb;
|
||||
char *options;
|
||||
struct ctdb_monitoring_status *monitoring_status =
|
||||
talloc_get_type(ctdb->script_monitoring_ctx,
|
||||
struct ctdb_monitoring_status);
|
||||
struct ctdb_monitor_status *monitoring_status = (struct ctdb_monitor_status *)ctdb->script_monitor_ctx;
|
||||
|
||||
state->te = NULL;
|
||||
|
||||
DEBUG(DEBUG_ERR,("Event script timed out : %s count : %u pid : %d\n", state->options, ctdb->event_script_timeouts, state->child));
|
||||
if (kill(state->child, 0) != 0) {
|
||||
DEBUG(DEBUG_ERR,("Event script child process already dead, errno %s(%d)\n", strerror(errno), errno));
|
||||
callback(ctdb, 0, private_data);
|
||||
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, 0, private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
talloc_set_destructor(state, NULL);
|
||||
talloc_free(state);
|
||||
return;
|
||||
@ -696,24 +701,39 @@ static void ctdb_event_script_timeout(struct event_context *ev, struct timed_eve
|
||||
if (ctdb->event_script_timeouts > ctdb->tunable.script_ban_count) {
|
||||
if (ctdb->tunable.script_unhealthy_on_timeout != 0) {
|
||||
DEBUG(DEBUG_ERR, ("Maximum timeout count %u reached for eventscript. Making node unhealthy\n", ctdb->tunable.script_ban_count));
|
||||
callback(ctdb, -ETIME, private_data);
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, -ETIME, private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
} else {
|
||||
ctdb->event_script_timeouts = 0;
|
||||
DEBUG(DEBUG_ERR, ("Maximum timeout count %u reached for eventscript. Banning self for %d seconds\n", ctdb->tunable.script_ban_count, ctdb->tunable.recovery_ban_period));
|
||||
ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
|
||||
callback(ctdb, -1, private_data);
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, -1, private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
callback(ctdb, 0, private_data);
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, 0, private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(options, "startup")) {
|
||||
DEBUG(DEBUG_ERR, (__location__ " eventscript for startup event timedout.\n"));
|
||||
callback(ctdb, -1, private_data);
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, -1, private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
} else {
|
||||
/* if it is not a monitor event we ban ourself immediately */
|
||||
DEBUG(DEBUG_ERR, (__location__ " eventscript for NON-monitor/NON-startup event timedout. Immediately banning ourself for %d seconds\n", ctdb->tunable.recovery_ban_period));
|
||||
ctdb_ban_self(ctdb, ctdb->tunable.recovery_ban_period);
|
||||
callback(ctdb, -1, private_data);
|
||||
if (state->callback) {
|
||||
state->callback(ctdb, -1, private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (monitoring_status != NULL) {
|
||||
@ -724,11 +744,12 @@ static void ctdb_event_script_timeout(struct event_context *ev, struct timed_eve
|
||||
script->timedout = 1;
|
||||
}
|
||||
monitoring_status->status = MONITOR_SCRIPT_TIMEOUT;
|
||||
if (ctdb->last_monitoring_ctx) {
|
||||
talloc_free(ctdb->last_monitoring_ctx);
|
||||
ctdb->last_monitoring_ctx = ctdb->script_monitoring_ctx;
|
||||
ctdb->script_monitoring_ctx = NULL;
|
||||
if (ctdb->last_monitor_ctx) {
|
||||
talloc_free(ctdb->last_monitor_ctx);
|
||||
ctdb->last_monitor_ctx = NULL;
|
||||
}
|
||||
ctdb->last_monitor_ctx = talloc_steal(ctdb, ctdb->script_monitor_ctx);
|
||||
ctdb->script_monitor_ctx = NULL;
|
||||
}
|
||||
|
||||
talloc_free(options);
|
||||
@ -741,6 +762,11 @@ static int event_script_destructor(struct ctdb_event_script_state *state)
|
||||
{
|
||||
DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
|
||||
|
||||
if (state->callback) {
|
||||
state->callback(state->ctdb, -1, state->private_data);
|
||||
state->callback = NULL;
|
||||
}
|
||||
|
||||
if (kill(state->child, SIGTERM) != 0) {
|
||||
DEBUG(DEBUG_ERR,("Failed to kill child process for eventscript, errno %s(%d)\n", strerror(errno), errno));
|
||||
}
|
||||
@ -754,28 +780,49 @@ static int event_script_destructor(struct ctdb_event_script_state *state)
|
||||
*/
|
||||
static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
|
||||
struct timeval timeout,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
void (*callback)(struct ctdb_context *, int, void *),
|
||||
void *private_data,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
struct ctdb_monitor_status *monitoring_status;
|
||||
struct ctdb_event_script_state *state;
|
||||
int ret;
|
||||
|
||||
state = talloc(mem_ctx, struct ctdb_event_script_state);
|
||||
CTDB_NO_MEMORY(ctdb, state);
|
||||
if (ctdb->script_monitor_ctx != NULL) {
|
||||
talloc_free(ctdb->script_monitor_ctx);
|
||||
ctdb->script_monitor_ctx = NULL;
|
||||
}
|
||||
monitoring_status = talloc_zero(ctdb, struct ctdb_monitor_status);
|
||||
if (monitoring_status == NULL) {
|
||||
DEBUG(DEBUG_ERR, (__location__ " ERROR: Failed to talloc script_monitoring context\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
state = talloc(monitoring_status, struct ctdb_event_script_state);
|
||||
if (state == NULL) {
|
||||
DEBUG(DEBUG_ERR,(__location__ " could not allocate state\n"));
|
||||
talloc_free(monitoring_status);
|
||||
return -1;
|
||||
}
|
||||
monitoring_status->state = state;
|
||||
|
||||
state->ctdb = ctdb;
|
||||
state->callback = callback;
|
||||
state->private_data = private_data;
|
||||
state->options = talloc_vasprintf(state, fmt, ap);
|
||||
CTDB_NO_MEMORY(ctdb, state->options);
|
||||
state->timeout = timeout;
|
||||
state->te = NULL;
|
||||
if (state->options == NULL) {
|
||||
DEBUG(DEBUG_ERR, (__location__ " could not allocate state->options\n"));
|
||||
talloc_free(monitoring_status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
DEBUG(DEBUG_INFO,(__location__ " Starting eventscript %s\n", state->options));
|
||||
|
||||
ret = pipe(state->fd);
|
||||
if (ret != 0) {
|
||||
talloc_free(state);
|
||||
talloc_free(monitoring_status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -784,7 +831,7 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
|
||||
if (state->child == (pid_t)-1) {
|
||||
close(state->fd[0]);
|
||||
close(state->fd[1]);
|
||||
talloc_free(state);
|
||||
talloc_free(monitoring_status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -803,6 +850,7 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
|
||||
}
|
||||
|
||||
talloc_set_destructor(state, event_script_destructor);
|
||||
ctdb->script_monitor_ctx = monitoring_status;
|
||||
|
||||
close(state->fd[1]);
|
||||
set_close_on_exec(state->fd[0]);
|
||||
@ -812,8 +860,8 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
|
||||
event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ|EVENT_FD_AUTOCLOSE,
|
||||
ctdb_event_script_handler, state);
|
||||
|
||||
if (!timeval_is_zero(&timeout)) {
|
||||
event_add_timed(ctdb->ev, state, timeout, ctdb_event_script_timeout, state);
|
||||
if (!timeval_is_zero(&state->timeout)) {
|
||||
state->te = event_add_timed(ctdb->ev, state, timeval_current_ofs(state->timeout.tv_sec, state->timeout.tv_usec), ctdb_event_script_timeout, state);
|
||||
} else {
|
||||
DEBUG(DEBUG_ERR, (__location__ " eventscript %s called with no timeout\n", state->options));
|
||||
}
|
||||
@ -837,7 +885,7 @@ int ctdb_event_script_callback(struct ctdb_context *ctdb,
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = ctdb_event_script_callback_v(ctdb, timeout, mem_ctx, callback, private_data, fmt, ap);
|
||||
ret = ctdb_event_script_callback_v(ctdb, timeout, callback, private_data, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
@ -867,17 +915,15 @@ int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
|
||||
struct callback_status status;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = ctdb_event_script_callback_v(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
tmp_ctx, event_script_callback, &status, fmt, ap);
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
event_script_callback, &status, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret != 0) {
|
||||
talloc_free(tmp_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -886,8 +932,6 @@ int ctdb_event_script(struct ctdb_context *ctdb, const char *fmt, ...)
|
||||
|
||||
while (status.done == false && event_loop_once(ctdb->ev) == 0) /* noop */;
|
||||
|
||||
talloc_free(tmp_ctx);
|
||||
|
||||
return status.status;
|
||||
}
|
||||
|
||||
@ -952,7 +996,7 @@ int32_t ctdb_run_eventscripts(struct ctdb_context *ctdb,
|
||||
ctdb_disable_monitoring(ctdb);
|
||||
|
||||
ret = ctdb_event_script_callback(ctdb,
|
||||
timeval_current_ofs(ctdb->tunable.script_timeout, 0),
|
||||
timeval_set(ctdb->tunable.script_timeout, 0),
|
||||
state, run_eventscripts_callback, state,
|
||||
"%s", (const char *)indata.dptr);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user