rteval-loads/SOURCES/0004-stress-sem-sysv-exerci...

266 lines
7.4 KiB
Diff

From 02fe57f97b44220c55c599aaa700607664c37382 Mon Sep 17 00:00:00 2001
From: Colin Ian King <colin.king@canonical.com>
Date: Mon, 18 May 2020 00:01:27 +0100
Subject: [PATCH 04/28] stress-sem-sysv: exercise some invalid options to get
more kernel coverage
Exercise some of the invalid argument checking to exercise more kernel
paths.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
stress-sem-sysv.c | 122 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 105 insertions(+), 17 deletions(-)
diff --git a/stress-sem-sysv.c b/stress-sem-sysv.c
index 8c5fd1c95640..3c62d065b4de 100644
--- a/stress-sem-sysv.c
+++ b/stress-sem-sysv.c
@@ -139,12 +139,13 @@ static void stress_semaphore_sysv_get_procinfo(bool *get_procinfo)
* stress_semaphore_sysv_thrash()
* exercise the semaphore
*/
-static void stress_semaphore_sysv_thrash(const stress_args_t *args)
+static int stress_semaphore_sysv_thrash(const stress_args_t *args)
{
const int sem_id = g_shared->sem_sysv.sem_id;
+ int rc = EXIT_SUCCESS;
do {
- int i;
+ int i, ret;
#if defined(__linux__)
bool get_procinfo = true;
#endif
@@ -155,7 +156,7 @@ static void stress_semaphore_sysv_thrash(const stress_args_t *args)
if (clock_gettime(CLOCK_REALTIME, &timeout) < 0) {
pr_fail("%s: clock_gettime failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
- return;
+ return EXIT_NO_RESOURCE;
}
timeout.tv_sec++;
#endif
@@ -184,15 +185,19 @@ static void stress_semaphore_sysv_thrash(const stress_args_t *args)
#endif
if (errno == EAGAIN)
goto timed_out;
- if (errno != EINTR)
+ if (errno != EINTR) {
pr_fail("%s: semop wait failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
break;
}
if (semop(sem_id, &semsignal, 1) < 0) {
- if (errno != EINTR)
+ if (errno != EINTR) {
pr_fail("%s: semop signal failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
break;
}
timed_out:
@@ -208,9 +213,11 @@ timed_out:
memset(&ds, 0, sizeof(ds));
s.buf = &ds;
- if (semctl(sem_id, 0, IPC_STAT, &s) < 0)
+ if (semctl(sem_id, 0, IPC_STAT, &s) < 0) {
pr_fail("%s: semctl IPC_STAT failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
#if defined(GETALL)
/* Avoid zero array size allocation */
@@ -221,11 +228,13 @@ timed_out:
if (semctl(sem_id, 0, GETALL, s) < 0) {
pr_fail("%s: semctl GETALL failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
}
#if defined(SETALL)
if (semctl(sem_id, 0, SETALL, s) < 0) {
pr_fail("%s: semctl SETALL failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
}
#endif
free(s.array);
@@ -239,9 +248,11 @@ timed_out:
stress_semun_t s;
s.buf = &ds;
- if (semctl(sem_id, 0, SEM_STAT, &s) < 0)
+ if (semctl(sem_id, 0, SEM_STAT, &s) < 0) {
pr_fail("%s: semctl SET_STAT failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
}
#endif
#if defined(IPC_INFO) && defined(__linux__)
@@ -250,9 +261,11 @@ timed_out:
stress_semun_t s;
s.__buf = &si;
- if (semctl(sem_id, 0, IPC_INFO, &s) < 0)
+ if (semctl(sem_id, 0, IPC_INFO, &s) < 0) {
pr_fail("%s: semctl IPC_INFO failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
}
#endif
#if defined(SEM_INFO) && defined(__linux__)
@@ -261,32 +274,103 @@ timed_out:
stress_semun_t s;
s.__buf = &si;
- if (semctl(sem_id, 0, SEM_INFO, &s) < 0)
+ if (semctl(sem_id, 0, SEM_INFO, &s) < 0) {
pr_fail("%s: semctl SEM_INFO failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
}
#endif
#if defined(GETVAL)
- if (semctl(sem_id, 0, GETVAL) < 0)
+ if (semctl(sem_id, 0, GETVAL) < 0) {
pr_fail("%s: semctl GETVAL failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
#endif
#if defined(GETPID)
- if (semctl(sem_id, 0, GETPID) < 0)
+ if (semctl(sem_id, 0, GETPID) < 0) {
pr_fail("%s: semctl GETPID failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
#endif
#if defined(GETNCNT)
- if (semctl(sem_id, 0, GETNCNT) < 0)
+ if (semctl(sem_id, 0, GETNCNT) < 0) {
pr_fail("%s: semctl GETNCNT failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
#endif
#if defined(GETZCNT)
- if (semctl(sem_id, 0, GETZCNT) < 0)
+ if (semctl(sem_id, 0, GETZCNT) < 0) {
pr_fail("%s: semctl GETZCNT failed, errno=%d (%s)\n",
args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
+#endif
+ /*
+ * Now exercise invalid options and arguments
+ */
+ ret = semctl(sem_id, -1, SETVAL, 0);
+ if ((ret == 0) || ((ret < 0) && (errno != EINVAL))) {
+ pr_fail("%s: semctl SETVAL with semnum = -1 did not fail with EINVAL as expected, errno=%d (%s)\n",
+ args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
+#if defined(GETVAL)
+ ret = semctl(sem_id, -1, GETVAL);
+ if ((ret == 0) || ((ret < 0) && (errno != EINVAL))) {
+ pr_fail("%s: semctl GETVAL with semnum = -1 did not fail with EINVAL as expected, errno=%d (%s)\n",
+ args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
+#endif
+#if defined(HAVE_SEMTIMEDOP) && \
+ defined(HAVE_CLOCK_GETTIME)
+ {
+ /*
+ * Exercise illegal timeout
+ */
+ struct sembuf semwait;
+
+ timeout.tv_sec = -1;
+ timeout.tv_nsec = -1;
+ semwait.sem_num = 0;
+ semwait.sem_op = -1;
+ semwait.sem_flg = SEM_UNDO;
+
+ ret = semtimedop(sem_id, &semwait, 1, &timeout);
+ if ((ret == 0) || ((ret < 0) && (errno != EINVAL))) {
+ pr_fail("%s: semtimedop with invalid timeout did not fail with EINVAL as expected, errno=%d (%s)\n",
+ args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
+ }
#endif
- } while (keep_stressing());
+ /*
+ * Exercise illegal semwait
+ */
+ {
+ struct sembuf semwait;
+
+ semwait.sem_num = -1;
+ semwait.sem_op = -1;
+ semwait.sem_flg = SEM_UNDO;
+
+ ret = semop(sem_id, &semwait, 1);
+ if ((ret == 0) || ((ret < 0) && (errno != EFBIG))) {
+ pr_fail("%s: semop with invalid sem_num did not fail with EFBIG as expected, errno=%d (%s)\n",
+ args->name, errno, strerror(errno));
+ rc = EXIT_FAILURE;
+ }
+ }
+ } while ((rc == EXIT_SUCCESS) && keep_stressing());
+
+ if (rc == EXIT_FAILURE)
+ kill(getppid(), SIGALRM);
+
+ return rc;
}
/*
@@ -308,8 +392,7 @@ again:
(void)setpgid(0, g_pgrp);
stress_parent_died_alarm();
- stress_semaphore_sysv_thrash(args);
- _exit(EXIT_SUCCESS);
+ _exit(stress_semaphore_sysv_thrash(args));
}
(void)setpgid(pid, g_pgrp);
return pid;
@@ -324,6 +407,7 @@ static int stress_sem_sysv(const stress_args_t *args)
pid_t pids[MAX_SEMAPHORE_PROCS];
uint64_t i;
uint64_t semaphore_sysv_procs = DEFAULT_SEMAPHORE_PROCS;
+ int rc = EXIT_SUCCESS;
if (!stress_get_setting("sem-sysv-procs", &semaphore_sysv_procs)) {
if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
@@ -356,10 +440,14 @@ reap:
int status;
(void)shim_waitpid(pids[i], &status, 0);
+ if (WIFEXITED(status) &&
+ (WEXITSTATUS(status) != EXIT_SUCCESS)) {
+ rc = EXIT_FAILURE;
+ }
}
}
- return EXIT_SUCCESS;
+ return rc;
}
stressor_info_t stress_sem_sysv_info = {
--
2.21.3