2019-05-29 00:57:18 +08:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2013-08-06 15:42:36 +08:00
|
|
|
/*
|
|
|
|
* Copyright 2013, Michael Ellerman, IBM Corp.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <unistd.h>
|
2015-04-10 12:16:48 +08:00
|
|
|
#include <elf.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <link.h>
|
|
|
|
#include <sys/stat.h>
|
2013-08-06 15:42:36 +08:00
|
|
|
|
|
|
|
#include "subunit.h"
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
#define KILL_TIMEOUT 5
|
|
|
|
|
selftests/powerpc: Add a signal fuzzer selftest
This is a new selftest that raises SIGUSR1 signals and handles it in a
set of different ways, trying to create different scenario for testing
purpose.
This test works raising a signal and calling sigreturn interleaved
with TM operations, as starting, suspending and terminating a
transaction. The test depends on random numbers, and, based on them,
it sets different TM states.
Other than that, the test fills out the user context struct that is
passed to the sigreturn system call with random data, in order to make
sure that the signal handler syscall can handle different and invalid
states properly.
This selftest has command line parameters to control what kind of
tests the user wants to run, as for example, if a transaction should
be started prior to signal being raised, or, after the signal being
raised and before the sigreturn. If no parameter is given, the default
is enabling all options.
This test does not check if the user context is being read and set
properly by the kernel. Its purpose, at this time, is basically
guaranteeing that the kernel does not crash on invalid scenarios.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2019-01-18 01:01:54 +08:00
|
|
|
/* Setting timeout to -1 disables the alarm */
|
2016-09-23 14:18:17 +08:00
|
|
|
static uint64_t timeout = 120;
|
2013-08-06 15:42:36 +08:00
|
|
|
|
|
|
|
int run_test(int (test_function)(void), char *name)
|
|
|
|
{
|
|
|
|
bool terminated;
|
|
|
|
int rc, status;
|
|
|
|
pid_t pid;
|
|
|
|
|
|
|
|
/* Make sure output is flushed before forking */
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
pid = fork();
|
|
|
|
if (pid == 0) {
|
2014-06-10 20:23:08 +08:00
|
|
|
setpgid(0, 0);
|
2013-08-06 15:42:36 +08:00
|
|
|
exit(test_function());
|
|
|
|
} else if (pid == -1) {
|
|
|
|
perror("fork");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2014-06-10 20:23:08 +08:00
|
|
|
setpgid(pid, pid);
|
|
|
|
|
selftests/powerpc: Add a signal fuzzer selftest
This is a new selftest that raises SIGUSR1 signals and handles it in a
set of different ways, trying to create different scenario for testing
purpose.
This test works raising a signal and calling sigreturn interleaved
with TM operations, as starting, suspending and terminating a
transaction. The test depends on random numbers, and, based on them,
it sets different TM states.
Other than that, the test fills out the user context struct that is
passed to the sigreturn system call with random data, in order to make
sure that the signal handler syscall can handle different and invalid
states properly.
This selftest has command line parameters to control what kind of
tests the user wants to run, as for example, if a transaction should
be started prior to signal being raised, or, after the signal being
raised and before the sigreturn. If no parameter is given, the default
is enabling all options.
This test does not check if the user context is being read and set
properly by the kernel. Its purpose, at this time, is basically
guaranteeing that the kernel does not crash on invalid scenarios.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2019-01-18 01:01:54 +08:00
|
|
|
if (timeout != -1)
|
|
|
|
/* Wake us up in timeout seconds */
|
|
|
|
alarm(timeout);
|
2013-08-06 15:42:36 +08:00
|
|
|
terminated = false;
|
|
|
|
|
|
|
|
wait:
|
|
|
|
rc = waitpid(pid, &status, 0);
|
|
|
|
if (rc == -1) {
|
|
|
|
if (errno != EINTR) {
|
|
|
|
printf("unknown error from waitpid\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (terminated) {
|
|
|
|
printf("!! force killing %s\n", name);
|
2014-06-10 20:23:08 +08:00
|
|
|
kill(-pid, SIGKILL);
|
2013-08-06 15:42:36 +08:00
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
printf("!! killing %s\n", name);
|
2014-06-10 20:23:08 +08:00
|
|
|
kill(-pid, SIGTERM);
|
2013-08-06 15:42:36 +08:00
|
|
|
terminated = true;
|
|
|
|
alarm(KILL_TIMEOUT);
|
|
|
|
goto wait;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-10 20:23:08 +08:00
|
|
|
/* Kill anything else in the process group that is still running */
|
|
|
|
kill(-pid, SIGTERM);
|
|
|
|
|
2013-08-06 15:42:36 +08:00
|
|
|
if (WIFEXITED(status))
|
|
|
|
status = WEXITSTATUS(status);
|
|
|
|
else {
|
|
|
|
if (WIFSIGNALED(status))
|
|
|
|
printf("!! child died by signal %d\n", WTERMSIG(status));
|
|
|
|
else
|
|
|
|
printf("!! child died by unknown cause\n");
|
|
|
|
|
|
|
|
status = 1; /* Signal or other */
|
|
|
|
}
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
selftests/powerpc: Kill child processes on SIGINT
There are some powerpc selftests, as tm/tm-unavailable, that run for a long
period (>120 seconds), and if it is interrupted, as pressing CRTL-C
(SIGINT), the foreground process (harness) dies but the child process and
threads continue to execute (with PPID = 1 now) in background.
In this case, you'd think the whole test exited, but there are remaining
threads and processes being executed in background. Sometimes these
zombies processes are doing annoying things, as consuming the whole CPU or
dumping things to STDOUT.
This patch fixes this problem by attaching an empty signal handler to
SIGINT in the harness process. This handler will interrupt (EINTR) the
parent process waitpid() call, letting the code to follow through the
normal flow, which will kill all the processes in the child process group.
This patch also fixes a typo.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-08-07 22:15:39 +08:00
|
|
|
static void sig_handler(int signum)
|
2013-08-06 15:42:36 +08:00
|
|
|
{
|
selftests/powerpc: Kill child processes on SIGINT
There are some powerpc selftests, as tm/tm-unavailable, that run for a long
period (>120 seconds), and if it is interrupted, as pressing CRTL-C
(SIGINT), the foreground process (harness) dies but the child process and
threads continue to execute (with PPID = 1 now) in background.
In this case, you'd think the whole test exited, but there are remaining
threads and processes being executed in background. Sometimes these
zombies processes are doing annoying things, as consuming the whole CPU or
dumping things to STDOUT.
This patch fixes this problem by attaching an empty signal handler to
SIGINT in the harness process. This handler will interrupt (EINTR) the
parent process waitpid() call, letting the code to follow through the
normal flow, which will kill all the processes in the child process group.
This patch also fixes a typo.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-08-07 22:15:39 +08:00
|
|
|
/* Just wake us up from waitpid */
|
2013-08-06 15:42:36 +08:00
|
|
|
}
|
|
|
|
|
selftests/powerpc: Kill child processes on SIGINT
There are some powerpc selftests, as tm/tm-unavailable, that run for a long
period (>120 seconds), and if it is interrupted, as pressing CRTL-C
(SIGINT), the foreground process (harness) dies but the child process and
threads continue to execute (with PPID = 1 now) in background.
In this case, you'd think the whole test exited, but there are remaining
threads and processes being executed in background. Sometimes these
zombies processes are doing annoying things, as consuming the whole CPU or
dumping things to STDOUT.
This patch fixes this problem by attaching an empty signal handler to
SIGINT in the harness process. This handler will interrupt (EINTR) the
parent process waitpid() call, letting the code to follow through the
normal flow, which will kill all the processes in the child process group.
This patch also fixes a typo.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-08-07 22:15:39 +08:00
|
|
|
static struct sigaction sig_action = {
|
|
|
|
.sa_handler = sig_handler,
|
2013-08-06 15:42:36 +08:00
|
|
|
};
|
|
|
|
|
2016-09-23 14:18:17 +08:00
|
|
|
void test_harness_set_timeout(uint64_t time)
|
|
|
|
{
|
|
|
|
timeout = time;
|
|
|
|
}
|
|
|
|
|
2013-08-06 15:42:36 +08:00
|
|
|
int test_harness(int (test_function)(void), char *name)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
test_start(name);
|
|
|
|
test_set_git_version(GIT_VERSION);
|
|
|
|
|
selftests/powerpc: Kill child processes on SIGINT
There are some powerpc selftests, as tm/tm-unavailable, that run for a long
period (>120 seconds), and if it is interrupted, as pressing CRTL-C
(SIGINT), the foreground process (harness) dies but the child process and
threads continue to execute (with PPID = 1 now) in background.
In this case, you'd think the whole test exited, but there are remaining
threads and processes being executed in background. Sometimes these
zombies processes are doing annoying things, as consuming the whole CPU or
dumping things to STDOUT.
This patch fixes this problem by attaching an empty signal handler to
SIGINT in the harness process. This handler will interrupt (EINTR) the
parent process waitpid() call, letting the code to follow through the
normal flow, which will kill all the processes in the child process group.
This patch also fixes a typo.
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Gustavo Romero <gromero@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-08-07 22:15:39 +08:00
|
|
|
if (sigaction(SIGINT, &sig_action, NULL)) {
|
|
|
|
perror("sigaction (sigint)");
|
|
|
|
test_error(name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sigaction(SIGALRM, &sig_action, NULL)) {
|
|
|
|
perror("sigaction (sigalrm)");
|
2013-08-06 15:42:36 +08:00
|
|
|
test_error(name);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = run_test(test_function, name);
|
|
|
|
|
2017-02-26 14:08:39 +08:00
|
|
|
if (rc == MAGIC_SKIP_RETURN_VALUE) {
|
2014-06-10 20:23:09 +08:00
|
|
|
test_skip(name);
|
2017-02-26 14:08:39 +08:00
|
|
|
/* so that skipped test is not marked as failed */
|
|
|
|
rc = 0;
|
|
|
|
} else
|
2014-06-10 20:23:09 +08:00
|
|
|
test_finish(name, rc);
|
2013-08-06 15:42:36 +08:00
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|