diff options
author | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2008-07-08 03:48:11 +1000 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2008-07-08 03:48:11 +1000 |
commit | d67de4a7d2587510ad5ad3d813e9700970751c03 (patch) | |
tree | 1def77dc23e2b68476ec828cb70277c87c1afe99 /ctdb/server/eventscript.c | |
parent | 6bfbec28a4f5366bd449fccfb7178b0d473614f6 (diff) | |
download | samba-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.c | 26 |
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); |