mirror of
https://github.com/hardkernel/linux.git
synced 2026-04-15 10:00:40 +09:00
[ Upstream commit a6d8a21596 ]
Tests under alignment subdirectory are skipped when executed on previous
generation hardware, but harness still marks them as failed.
test: test_copy_unaligned
tags: git_version:unknown
[SKIP] Test skipped on line 26
skip: test_copy_unaligned
selftests: copy_unaligned [FAIL]
The MAGIC_SKIP_RETURN_VALUE value assigned to rc variable is retained till
the program exit which causes the test to be marked as failed.
This patch resets the value before returning to the main() routine.
With this patch the test o/p is as follows:
test: test_copy_unaligned
tags: git_version:unknown
[SKIP] Test skipped on line 26
skip: test_copy_unaligned
selftests: copy_unaligned [PASS]
Signed-off-by: Sachin Sant <sachinp@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
164 lines
2.6 KiB
C
164 lines
2.6 KiB
C
/*
|
|
* Copyright 2013, Michael Ellerman, IBM Corp.
|
|
* Licensed under GPLv2.
|
|
*/
|
|
|
|
#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>
|
|
#include <elf.h>
|
|
#include <fcntl.h>
|
|
#include <link.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "subunit.h"
|
|
#include "utils.h"
|
|
|
|
#define TIMEOUT 120
|
|
#define KILL_TIMEOUT 5
|
|
|
|
|
|
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) {
|
|
setpgid(0, 0);
|
|
exit(test_function());
|
|
} else if (pid == -1) {
|
|
perror("fork");
|
|
return 1;
|
|
}
|
|
|
|
setpgid(pid, pid);
|
|
|
|
/* Wake us up in timeout seconds */
|
|
alarm(TIMEOUT);
|
|
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);
|
|
kill(-pid, SIGKILL);
|
|
return 1;
|
|
} else {
|
|
printf("!! killing %s\n", name);
|
|
kill(-pid, SIGTERM);
|
|
terminated = true;
|
|
alarm(KILL_TIMEOUT);
|
|
goto wait;
|
|
}
|
|
}
|
|
|
|
/* Kill anything else in the process group that is still running */
|
|
kill(-pid, SIGTERM);
|
|
|
|
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;
|
|
}
|
|
|
|
static void alarm_handler(int signum)
|
|
{
|
|
/* Jut wake us up from waitpid */
|
|
}
|
|
|
|
static struct sigaction alarm_action = {
|
|
.sa_handler = alarm_handler,
|
|
};
|
|
|
|
int test_harness(int (test_function)(void), char *name)
|
|
{
|
|
int rc;
|
|
|
|
test_start(name);
|
|
test_set_git_version(GIT_VERSION);
|
|
|
|
if (sigaction(SIGALRM, &alarm_action, NULL)) {
|
|
perror("sigaction");
|
|
test_error(name);
|
|
return 1;
|
|
}
|
|
|
|
rc = run_test(test_function, name);
|
|
|
|
if (rc == MAGIC_SKIP_RETURN_VALUE) {
|
|
test_skip(name);
|
|
/* so that skipped test is not marked as failed */
|
|
rc = 0;
|
|
} else
|
|
test_finish(name, rc);
|
|
|
|
return rc;
|
|
}
|
|
|
|
static char auxv[4096];
|
|
|
|
void *get_auxv_entry(int type)
|
|
{
|
|
ElfW(auxv_t) *p;
|
|
void *result;
|
|
ssize_t num;
|
|
int fd;
|
|
|
|
fd = open("/proc/self/auxv", O_RDONLY);
|
|
if (fd == -1) {
|
|
perror("open");
|
|
return NULL;
|
|
}
|
|
|
|
result = NULL;
|
|
|
|
num = read(fd, auxv, sizeof(auxv));
|
|
if (num < 0) {
|
|
perror("read");
|
|
goto out;
|
|
}
|
|
|
|
if (num > sizeof(auxv)) {
|
|
printf("Overflowed auxv buffer\n");
|
|
goto out;
|
|
}
|
|
|
|
p = (ElfW(auxv_t) *)auxv;
|
|
|
|
while (p->a_type != AT_NULL) {
|
|
if (p->a_type == type) {
|
|
result = (void *)p->a_un.a_val;
|
|
break;
|
|
}
|
|
|
|
p++;
|
|
}
|
|
out:
|
|
close(fd);
|
|
return result;
|
|
}
|