Module: xenomai-head Branch: master Commit: 918be21308120f471be6bbb301a3be4021197710 URL: http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=918be21308120f471be6bbb301a3be4021197710
Author: Gilles Chanteperdrix <[email protected]> Date: Sat Oct 22 01:23:00 2011 +0200 testsuite: various fixes most notably xeno-test-run let latency print histogram before dying. --- src/testsuite/regression/xeno-regression-test.in | 4 +- src/testsuite/xeno-test/dohell | 4 +- src/testsuite/xeno-test/xeno-test-run.c | 153 ++++++++++++++-------- 3 files changed, 104 insertions(+), 57 deletions(-) diff --git a/src/testsuite/regression/xeno-regression-test.in b/src/testsuite/regression/xeno-regression-test.in index a157a0c..919f7a9 100644 --- a/src/testsuite/regression/xeno-regression-test.in +++ b/src/testsuite/regression/xeno-regression-test.in @@ -52,8 +52,8 @@ echo 0 > /proc/xenomai/latency || : start_load -check_alive @testdir@/switchtest ${1+"$@"} -check_alive @testdir@/switchtest -s 1000 ${1+"$@"} +check_alive @testdir@/switchtest +check_alive @testdir@/switchtest -s 1000 check_alive @testdir@/latency ${1+"$@"} wait_load diff --git a/src/testsuite/xeno-test/dohell b/src/testsuite/xeno-test/dohell index 9423270..918da8a 100644 --- a/src/testsuite/xeno-test/dohell +++ b/src/testsuite/xeno-test/dohell @@ -92,5 +92,5 @@ fi kill $pids > /dev/null 2>&1 sleep 5 -killall -KILL -q cat $nc dd hackbench ls ps -killall -KILL -q `basename $0` sleep +killall -KILL cat $nc dd hackbench ls ps > /dev/null 2>&1 +killall -KILL `basename $0` sleep > /dev/null 2>&1 diff --git a/src/testsuite/xeno-test/xeno-test-run.c b/src/testsuite/xeno-test/xeno-test-run.c index 8964e3f..7025dd8 100644 --- a/src/testsuite/xeno-test/xeno-test-run.c +++ b/src/testsuite/xeno-test/xeno-test-run.c @@ -2,6 +2,7 @@ #include <stdlib.h> #include <string.h> #include <errno.h> +#include <ctype.h> #include <sys/types.h> #include <sys/fcntl.h> @@ -34,6 +35,7 @@ struct child { static const char *scriptname; static volatile int sigexit; +static time_t termload_start, sigexit_start = 0; static sigset_t sigchld_mask; static struct child *first_child; static char *loadcmd = "exec dohell 900"; @@ -110,6 +112,9 @@ int child_initv(struct child *child, int type, char *argv[]) break; } + /* Detach child from terminal, to avoid child catching SIGINT */ + setsid(); + err = execvp(argv[0], argv); if (err < 0) { fail_fprintf(stderr, "execvp(%s): %m", argv[0]); @@ -170,10 +175,35 @@ int child_initv(struct child *child, int type, char *argv[]) int child_init(struct child *child, int type, char *cmdline) { - char *argv[] = { - getenv("SHELL") ?: "sh" , "-c", cmdline, NULL - }; - return child_initv(child, type, argv); + char **argv = malloc(sizeof(*argv)); + unsigned argc = 0; + int rc; + + if (!argv) + return -ENOMEM; + + do { + char **new_argv = realloc(argv, sizeof(*argv) * (argc + 2)); + if (!new_argv) { + free(argv); + return -ENOMEM; + } + argv = new_argv; + + argv[argc++] = cmdline; + cmdline = strpbrk(cmdline, " \t"); + if (cmdline) + do { + *cmdline++ = '\0'; + } while (isspace(*cmdline)); + } while (cmdline && *cmdline); + argv[argc] = NULL; + + rc = child_initv(child, type, argv); + + free(argv); + + return rc; } void child_cleanup(struct child *child) @@ -195,7 +225,7 @@ void child_cleanup(struct child *child) close(child->in); } -struct child *child_search(pid_t pid) +struct child *child_search_pid(pid_t pid) { struct child *child; @@ -206,6 +236,17 @@ struct child *child_search(pid_t pid) return child; } +struct child *child_search_type(int type) +{ + struct child *child; + + for (child = first_child; child; child = child->next) + if (child->type == type) + return child; + + return NULL; +} + int children_done_p(int type) { struct child *child; @@ -217,31 +258,20 @@ int children_done_p(int type) return 1; } -int children_term(int type) +int children_kill(int type, int sig) { struct child *child; struct timespec ts; - for (child = first_child; child; child = child->next) - if (type == CHILD_ANY || child->type == type) - kill(child->pid, SIGTERM); - - ts.tv_sec = 5; - ts.tv_nsec = 0; - do { - if (children_done_p(type)) - return 1; - } while (nanosleep(&ts, &ts) == -1 && errno == EINTR); + if (children_done_p(type)) + return 1; for (child = first_child; child; child = child->next) if ((type == CHILD_ANY || child->type == type) - && !child->dead) { - fail_fprintf(stderr, "child %d would not die, sending " - "SIGKILL\n", child->pid); - kill(child->pid, SIGKILL); - } + && !child->dead) + kill(child->pid, sig); - return 0; + return children_done_p(type); } void sigchld_handler(int sig) @@ -251,7 +281,7 @@ void sigchld_handler(int sig) pid_t pid; while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { - child = child_search(pid); + child = child_search_pid(pid); if (!child) { fail_fprintf(stderr, "dead child %d not found!\n", pid); exit(EXIT_FAILURE); @@ -264,14 +294,15 @@ void sigchld_handler(int sig) void cleanup(void) { - if (!children_term(CHILD_ANY)) - _exit(EXIT_FAILURE); + children_kill(CHILD_ANY, SIGKILL); } void termsig(int sig) { sigexit = sig; - cleanup(); + sigexit_start = time(NULL); + children_kill(CHILD_ANY, SIGTERM); + signal(sig, SIG_DFL); } void copy(int from, int to) @@ -315,7 +346,7 @@ void handle_checked_child(struct child *child, fd_set *fds) /* A checked child died, this may be abnormal if no termination signal was sent. */ if (WIFEXITED(status)) { - if (sigexit) + if (sigexit || termload_start) goto cleanup; fail_fprintf(stderr, "child %d exited with status %d\n", @@ -323,7 +354,7 @@ void handle_checked_child(struct child *child, fd_set *fds) } if (WIFSIGNALED(status)) { - if (sigexit && WTERMSIG(status) == SIGTERM) { + if (sigexit || termload_start) { cleanup: child_cleanup(child); free(child); @@ -355,8 +386,10 @@ void handle_script_child(struct child *child, fd_set *fds) ssize_t sz; int rc; - if (child->dead) - exit(child->exit_status); + if (child->dead) { + child_cleanup(child); + return; + } if (!FD_ISSET(child->out, fds)) return; @@ -386,7 +419,6 @@ void handle_script_child(struct child *child, fd_set *fds) " script is already running.\n"); exit(EXIT_FAILURE); } - rc = child_init(&load, CHILD_LOAD, loadcmd); if (rc) { fail_perror("child_init"); @@ -411,28 +443,38 @@ void handle_load_child(struct child *child, fd_set *fds) copy(child->out, STDOUT_FILENO); if (child->dead) { - child_cleanup(child); - if (sigexit) - return; + time_t now = time(NULL); - sigexit = SIGTERM; + if (!termload_start) { + if (sigexit) { + child_cleanup(child); + return; + } - fprintf(stderr, "Load script terminated, " - "terminating checked scripts\n"); + fprintf(stderr, "Load script terminated, " + "terminating checked scripts\n"); - if (!children_term(CHILD_CHECKED)) - exit(EXIT_FAILURE); + children_kill(CHILD_CHECKED, SIGTERM); + termload_start = now; + } else { + if (child_search_type(CHILD_CHECKED) + && now < termload_start + 30) + return; - for (child = first_child; child; child = child->next) - if (child->type == CHILD_CHECKED) { - child_cleanup(child); - free(child); + if (now >= termload_start + 30) { + fail_fprintf(stderr, "timeout waiting for " + "checked children, " + "sending SIGKILL\n"); + children_kill(CHILD_ANY, SIGKILL); } - sigexit = 0; + child_cleanup(child); + if (sigexit) + return; - write(script.in, "0\n", 2); - return; + write(script.in, "0\n", 2); + termload_start = 0; + } } } @@ -527,7 +569,7 @@ int main(int argc, char *argv[]) } maxfd = script.out; - for (;;) { + while (first_child) { struct child *child, *next; struct timeval tv; fd_set in; @@ -556,12 +598,17 @@ int main(int argc, char *argv[]) child->handle(child, &in); } - if (children_done_p(CHILD_ANY)) { - if (sigexit) { - signal(sigexit, SIG_DFL); - raise(sigexit); - } - exit(EXIT_SUCCESS); + if (sigexit_start && time(NULL) >= sigexit_start + 30) { + fail_fprintf(stderr, "timeout waiting for all " + "children, sending SIGKILL\n"); + children_kill(CHILD_ANY, SIGKILL); + sigexit_start = 0; } } + + if (sigexit) { + signal(sigexit, SIG_DFL); + raise(sigexit); + } + exit(EXIT_SUCCESS); } _______________________________________________ Xenomai-git mailing list [email protected] https://mail.gna.org/listinfo/xenomai-git
