diff options
author | Amitay Isaacs <amitay@gmail.com> | 2013-12-16 15:40:01 +1100 |
---|---|---|
committer | Martin Schwenke <martin@meltin.net> | 2014-01-16 12:11:37 +1100 |
commit | 69324b61f0669022c7204ee08a4c7104865d4e9b (patch) | |
tree | e394b0db1812cdd02c1c7c95736e360a8abef7e2 /ctdb/server/ctdb_event_helper.c | |
parent | 2879404388ed04af199a7e4451605b4435e8cc23 (diff) | |
download | samba-69324b61f0669022c7204ee08a4c7104865d4e9b.tar.gz samba-69324b61f0669022c7204ee08a4c7104865d4e9b.tar.xz samba-69324b61f0669022c7204ee08a4c7104865d4e9b.zip |
ctdb-daemon: Add helper process to execute event scripts
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'ctdb/server/ctdb_event_helper.c')
-rw-r--r-- | ctdb/server/ctdb_event_helper.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/ctdb/server/ctdb_event_helper.c b/ctdb/server/ctdb_event_helper.c new file mode 100644 index 00000000000..4c62e41af63 --- /dev/null +++ b/ctdb/server/ctdb_event_helper.c @@ -0,0 +1,136 @@ +/* + ctdb event script helper + + Copyright (C) Amitay Isaacs 2013 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/filesys.h" + +static char *progname = NULL; + + +/* CTDB sends SIGTERM, when process must die */ +static void sigterm(int sig) +{ + pid_t pid; + + /* all the child processes are running in the same process group */ + pid = getpgrp(); + if (pid == -1) { + kill(-getpid(), SIGKILL); + } else { + kill(-pid, SIGKILL); + } + _exit(0); +} + +static void set_close_on_exec(int fd) +{ + int v; + + v = fcntl(fd, F_GETFD, 0); + if (v == -1) { + return; + } + fcntl(fd, F_SETFD, v | FD_CLOEXEC); +} + +static int check_executable(const char *path) +{ + struct stat st; + + if (stat(path, &st) != 0) { + fprintf(stderr, "Failed to access '%s' - %s\n", + path, strerror(errno)); + return errno; + } + + if (!(st.st_mode & S_IXUSR)) { + return ENOEXEC; + } + + return 0; +} + +static void usage(void) +{ + fprintf(stderr, "\n"); + fprintf(stderr, "Usage: %s <log-fd> <output-fd> <script_path> <event> [<args>]\n", + progname); +} + +int main(int argc, char *argv[]) +{ + int log_fd, write_fd; + pid_t pid; + int status, output; + + progname = argv[0]; + + if (argc < 5) { + usage(); + exit(1); + } + + log_fd = atoi(argv[1]); + write_fd = atoi(argv[2]); + + set_close_on_exec(write_fd); + + close(STDOUT_FILENO); + close(STDERR_FILENO); + dup2(log_fd, STDOUT_FILENO); + dup2(log_fd, STDERR_FILENO); + close(log_fd); + + if (setpgid(0, 0) != 0) { + fprintf(stderr, "Failed to create process group for event script - %s\n", + strerror(errno)); + exit(1); + } + + signal(SIGTERM, sigterm); + + pid = fork(); + if (pid < 0) { + fprintf(stderr, "Failed to fork - %s\n", strerror(errno)); + exit(errno); + } + + if (pid == 0) { + int save_errno; + + execv(argv[3], &argv[3]); + if (errno == EACCES) { + save_errno = check_executable(argv[3]); + } else { + save_errno = errno; + fprintf(stderr, "Error executing '%s' - %s\n", + argv[3], strerror(errno)); + } + _exit(save_errno); + } + + waitpid(pid, &status, 0); + if (WIFEXITED(status)) { + output = -WEXITSTATUS(status); + write(write_fd, &output, sizeof(output)); + exit(output); + } + + exit(1); +} |