From d86662a925a072eb0374ad7743f4cf95c447bebb Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Tue, 17 Dec 2013 19:19:51 +1100 Subject: [PATCH] ctdb-daemon: Replace ctdb_fork_with_logging with ctdb_vfork_with_logging (part 1) Use ctdb_event_helper to run eventscripts. Signed-off-by: Amitay Isaacs Reviewed-by: Martin Schwenke --- ctdb/server/eventscript.c | 110 +++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 20 deletions(-) diff --git a/ctdb/server/eventscript.c b/ctdb/server/eventscript.c index 61406010221b..2c5a61271512 100644 --- a/ctdb/server/eventscript.c +++ b/ctdb/server/eventscript.c @@ -354,15 +354,91 @@ out: return ret; } +/* There cannot be more than 10 arguments to command helper. */ +#define MAX_HELPER_ARGS (10) + +static bool child_helper_args(TALLOC_CTX *mem_ctx, struct ctdb_context *ctdb, + enum ctdb_eventscript_call call, + const char *options, + struct ctdb_script_wire *current, int fd, + int *argc, const char ***argv) +{ + const char **tmp; + int n, i; + char *t, *saveptr, *opt; + + tmp = talloc_array(mem_ctx, const char *, 10+1); + if (tmp == NULL) goto failed; + + tmp[0] = talloc_asprintf(tmp, "%d", fd); + tmp[1] = talloc_asprintf(tmp, "%s/%s", ctdb->event_script_dir, current->name); + tmp[2] = talloc_asprintf(tmp, "%s", ctdb_eventscript_call_names[call]); + n = 3; + + /* Split options into individual arguments */ + opt = talloc_strdup(mem_ctx, options); + if (opt == NULL) { + goto failed; + } + + t = strtok_r(opt, " ", &saveptr); + while (t != NULL) { + tmp[n++] = talloc_strdup(tmp, t); + if (n > MAX_HELPER_ARGS) { + goto args_failed; + } + t = strtok_r(NULL, " ", &saveptr); + } + + for (i=0; istart = timeval_current(); @@ -372,38 +448,32 @@ static int fork_child_for_script(struct ctdb_context *ctdb, return -errno; } - if (!ctdb_fork_with_logging(state, ctdb, current->name, log_event_script_output, - state, &state->child)) { - r = -errno; + /* Arguments for helper */ + if (!child_helper_args(state, ctdb, state->call, state->options, current, + state->fd[1], &argc, &argv)) { + DEBUG(DEBUG_ERR, (__location__ " failed to create arguments for eventscript helper\n")); + r = -ENOMEM; close(state->fd[0]); close(state->fd[1]); return r; } - /* If we are the child, do the work. */ - if (state->child == 0) { - int rt; - - debug_extra = talloc_asprintf(NULL, "eventscript-%s-%s:", - current->name, - ctdb_eventscript_call_names[state->call]); + if (!ctdb_vfork_with_logging(state, ctdb, current->name, + helper_prog, argc, argv, + log_event_script_output, + state, &state->child)) { + talloc_free(argv); + r = -errno; close(state->fd[0]); - set_close_on_exec(state->fd[1]); - ctdb_set_process_name("ctdb_eventscript"); - - rt = child_run_script(ctdb, state->call, state->options, current); - /* We must be able to write PIPEBUF bytes at least; if this - somehow fails, the read above will be short. */ - write(state->fd[1], &rt, sizeof(rt)); close(state->fd[1]); - _exit(rt); + return r; } + talloc_free(argv); + close(state->fd[1]); set_close_on_exec(state->fd[0]); - DEBUG(DEBUG_DEBUG, (__location__ " Created PIPE FD:%d to child eventscript process\n", state->fd[0])); - /* Set ourselves up to be called when that's done. */ fde = event_add_fd(ctdb->ev, state, state->fd[0], EVENT_FD_READ, ctdb_event_script_handler, state); -- 2.34.1