summaryrefslogtreecommitdiffstats
path: root/ctdb/server/eventscript.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronniesahlberg@gmail.com>2008-07-08 03:48:11 +1000
committerRonnie Sahlberg <ronniesahlberg@gmail.com>2008-07-08 03:48:11 +1000
commitd67de4a7d2587510ad5ad3d813e9700970751c03 (patch)
tree1def77dc23e2b68476ec828cb70277c87c1afe99 /ctdb/server/eventscript.c
parent6bfbec28a4f5366bd449fccfb7178b0d473614f6 (diff)
downloadsamba-d67de4a7d2587510ad5ad3d813e9700970751c03.tar.gz
samba-d67de4a7d2587510ad5ad3d813e9700970751c03.tar.xz
samba-d67de4a7d2587510ad5ad3d813e9700970751c03.zip
waitpid() can block if it takes a long time before the child terminates
so we should not call it from the main daemon. 1, set SIGCHLD to SIG_DFL to make sure we ignore this signal 2, get rid of all waitpid() calls 3, change reporting of event script status code from _exit()/waitpid() to write()/read() one byte across the pipe. (This used to be ctdb commit bfba5c7249eff8a10a43b53c1b89dd44b625fd10)
Diffstat (limited to 'ctdb/server/eventscript.c')
-rw-r--r--ctdb/server/eventscript.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/ctdb/server/eventscript.c b/ctdb/server/eventscript.c
index 54d914b35c..9002007143 100644
--- a/ctdb/server/eventscript.c
+++ b/ctdb/server/eventscript.c
@@ -210,18 +210,20 @@ 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);
- int status = -1;
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;
+ int ret;
- waitpid(state->child, &status, 0);
- if (status != -1) {
- status = WEXITSTATUS(status);
+ ret = read(state->fd[0], &rt, sizeof(rt));
+ if (ret != sizeof(rt)) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed to read from pipe to eventscript child.\n"));
}
+
talloc_set_destructor(state, NULL);
talloc_free(state);
- callback(ctdb, status, private_data);
+ callback(ctdb, rt, private_data);
ctdb->event_script_timeouts = 0;
}
@@ -293,7 +295,6 @@ static int event_script_destructor(struct ctdb_event_script_state *state)
{
DEBUG(DEBUG_ERR,(__location__ " Sending SIGTERM to child pid:%d\n", state->child));
kill(state->child, SIGTERM);
- waitpid(state->child, NULL, 0);
return 0;
}
@@ -336,13 +337,22 @@ static int ctdb_event_script_callback_v(struct ctdb_context *ctdb,
}
if (state->child == 0) {
+ signed char rt;
+
close(state->fd[0]);
if (ctdb->do_setsched) {
ctdb_restore_scheduler(ctdb);
}
set_close_on_exec(state->fd[1]);
- ret = ctdb_event_script_v(ctdb, state->options);
- _exit(ret);
+ rt = ctdb_event_script_v(ctdb, state->options);
+ do {
+ ret = write(state->fd[1], &rt, sizeof(rt));
+ if (ret != sizeof(rt)) {
+ DEBUG(DEBUG_ERR, (__location__ " Failed to write to pipe from eventscript child. Trying again in one second\n"));
+ sleep(1);
+ }
+ } while (ret != sizeof(rt));
+ _exit(rt);
}
talloc_set_destructor(state, event_script_destructor);