ctdb-daemon: Improve error handling for running event scripts
authorAmitay Isaacs <amitay@gmail.com>
Thu, 13 Nov 2014 00:02:26 +0000 (11:02 +1100)
committerMartin Schwenke <martins@samba.org>
Fri, 14 Nov 2014 02:06:12 +0000 (03:06 +0100)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Autobuild-User(master): Martin Schwenke <martins@samba.org>
Autobuild-Date(master): Fri Nov 14 03:06:12 CET 2014 on sn-devel-104

ctdb/server/ctdb_event_helper.c
ctdb/server/eventscript.c

index 9ff763c538adadb3741b281ea3e12c946555ad1e..f14e336f25cfe7d88f1fcba884c4a9ba54e7b294 100644 (file)
@@ -67,7 +67,7 @@ int main(int argc, char *argv[])
 {
        int log_fd, write_fd;
        pid_t pid;
-       int status, output;
+       int status, output, ret;
 
        progname = argv[0];
 
@@ -99,33 +99,47 @@ int main(int argc, char *argv[])
 
        pid = fork();
        if (pid < 0) {
+               int save_errno = errno;
                fprintf(stderr, "Failed to fork - %s\n", strerror(errno));
-               exit(errno);
+               sys_write(write_fd, &save_errno, sizeof(save_errno));
+               exit(1);
        }
 
        if (pid == 0) {
-               int save_errno;
-
-               execv(argv[3], &argv[3]);
-               if (errno == EACCES) {
-                       save_errno = check_executable(argv[3]);
-               } else {
-                       save_errno = errno;
+               ret = check_executable(argv[3]);
+               if (ret != 0) {
+                       _exit(ret);
+               }
+               ret = execv(argv[3], &argv[3]);
+               if (ret != 0) {
+                       int save_errno = errno;
                        fprintf(stderr, "Error executing '%s' - %s\n",
-                               argv[3], strerror(errno));
+                               argv[3], strerror(save_errno));
                }
-               _exit(save_errno);
+               /* This should never happen */
+               _exit(ENOEXEC);
        }
 
-       waitpid(pid, &status, 0);
+       ret = waitpid(pid, &status, 0);
+       if (ret == -1) {
+               output = -errno;
+               fprintf(stderr, "waitpid() failed - %s\n", strerror(errno));
+               sys_write(write_fd, &output, sizeof(output));
+               exit(1);
+       }
        if (WIFEXITED(status)) {
-               output = WEXITSTATUS(status);
-               if (output == ENOENT || output == ENOEXEC) {
-                       output = -output;
-               }
+               output = -WEXITSTATUS(status);
+               sys_write(write_fd, &output, sizeof(output));
+               exit(0);
+       }
+       if (WIFSIGNALED(status)) {
+               output = -EINTR;
+               fprintf(stderr, "Process terminated with signal - %d\n",
+                       WTERMSIG(status));
                sys_write(write_fd, &output, sizeof(output));
-               exit(output);
+               exit(0);
        }
 
+       fprintf(stderr, "waitpid() status=%d\n", status);
        exit(1);
 }
index 28bbb545b2fa6f3a2f23eeec81e419b667219594..eaa6a20d31a82097d5f343008be8a8d70f5a1cf8 100644 (file)
@@ -367,6 +367,8 @@ static void ctdb_event_script_handler(struct event_context *ev, struct fd_event
        r = sys_read(state->fd[0], &current->status, sizeof(current->status));
        if (r < 0) {
                current->status = -errno;
+       } else if (r == 0) {
+               current->status = -EINTR;
        } else if (r != sizeof(current->status)) {
                current->status = -EIO;
        }
@@ -384,8 +386,12 @@ static void ctdb_event_script_handler(struct event_context *ev, struct fd_event
 
        /* Aborted or finished all scripts?  We're done. */
        if (status != 0 || state->current+1 == state->scripts->num_scripts) {
-               DEBUG(DEBUG_INFO,(__location__ " Eventscript %s %s finished with state %d\n",
-                                 ctdb_eventscript_call_names[state->call], state->options, status));
+               if (status != 0) {
+                       DEBUG(DEBUG_INFO,
+                             ("Eventscript %s %s finished with state %d\n",
+                              ctdb_eventscript_call_names[state->call],
+                              state->options, status));
+               }
 
                ctdb->event_script_timeouts = 0;
                talloc_free(state);