[LTP] [PATCH V7 03/19] syscalls/timer_settime: Add support for time64 tests

Viresh Kumar
2020-06-26T06:22:16Z

This adds support for time64 tests to the existing timer_settime()
syscall tests.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
.../syscalls/timer_settime/timer_settime01.c | 51 ++++++++++----
.../syscalls/timer_settime/timer_settime02.c | 69 ++++++++++++++-----
2 files changed, 88 insertions(+), 32 deletions(-)

diff --git a/testcases/kernel/syscalls/timer_settime/timer_settime01.c b/testcases/kernel/syscalls/timer_settime/timer_settime01.c
index da365d221086..08fb56e4943a 100644
--- a/testcases/kernel/syscalls/timer_settime/timer_settime01.c
+++ b/testcases/kernel/syscalls/timer_settime/timer_settime01.c
@@ -25,15 +25,14 @@
#include <errno.h>
#include <time.h>
#include <signal.h>
-#include "tst_test.h"
-#include "lapi/common_timers.h"
+#include "tst_timer.h"

-static struct timespec timenow;
-static struct itimerspec new_set, old_set;
-static kernel_timer_t timer;
+static struct tst_ts timenow;
+static struct tst_its new_set, old_set;
+static timer_t timer;

static struct testcase {
- struct itimerspec *old_ptr;
+ struct tst_its *old_ptr;
int it_value_tv_sec;
int it_interval_tv_sec;
int flag;
@@ -45,10 +44,28 @@ static struct testcase {
{&old_set, 5, 0, TIMER_ABSTIME, "using absolute time"},
};

+static struct test_variants {
+ int (*gettime)(clockid_t clk_id, void *ts);
+ int (*func)(timer_t timerid, int flags, void *its,
+ void *old_its);
+ enum tst_ts_type type;
+ char *desc;
+} variants[] = {
+#if (__NR_timer_settime != __LTP__NR_INVALID_SYSCALL)
+ { .gettime = sys_clock_gettime, .func = sys_timer_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
+#endif
+
+#if (__NR_timer_settime64 != __LTP__NR_INVALID_SYSCALL)
+ { .gettime = sys_clock_gettime64, .func = sys_timer_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
+#endif
+};
+
static void run(unsigned int n)
{
- unsigned int i;
+ struct test_variants *tv = &variants[tst_variant];
struct testcase *tc = &tcases[n];
+ long long val;
+ unsigned int i;

tst_res(TINFO, "Testing for %s:", tc->description);

@@ -78,21 +95,27 @@ static void run(unsigned int n)
memset(&new_set, 0, sizeof(new_set));
memset(&old_set, 0, sizeof(old_set));

- new_set.it_value.tv_sec = tc->it_value_tv_sec;
- new_set.it_interval.tv_sec = tc->it_interval_tv_sec;
+ new_set.type = old_set.type = tv->type;
+
+ val = tc->it_value_tv_sec;

if (tc->flag & TIMER_ABSTIME) {
- if (clock_gettime(clock, &timenow) < 0) {
+ timenow.type = tv->type;
+ if (tv->gettime(clock, tst_ts_get(&timenow)) < 0) {
tst_res(TFAIL,
"clock_gettime(%s) failed - skipping the test",
get_clock_str(clock));
continue;
}
- new_set.it_value.tv_sec += timenow.tv_sec;
+ val += tst_ts_get_sec(timenow);
}

- TEST(tst_syscall(__NR_timer_settime, timer,
- tc->flag, &new_set, tc->old_ptr));
+ tst_its_set_interval_sec(&new_set, tc->it_interval_tv_sec);
+ tst_its_set_interval_nsec(&new_set, 0);
+ tst_its_set_value_sec(&new_set, val);
+ tst_its_set_value_nsec(&new_set, 0);
+
+ TEST(tv->func(timer, tc->flag, tst_its_get(&new_set), tst_its_get(tc->old_ptr)));

if (TST_RET != 0) {
tst_res(TFAIL | TTERRNO, "%s failed",
@@ -116,6 +139,7 @@ static void sighandler(int sig)

static void setup(void)
{
+ tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
SAFE_SIGNAL(SIGALRM, sighandler);
}

@@ -123,6 +147,7 @@ static struct tst_test test = {
.test = run,
.needs_root = 1,
.tcnt = ARRAY_SIZE(tcases),
+ .test_variants = ARRAY_SIZE(variants),
.setup = setup,
.tags = (const struct tst_tag[]) {
{"linux-git", "f18ddc13af98"},
diff --git a/testcases/kernel/syscalls/timer_settime/timer_settime02.c b/testcases/kernel/syscalls/timer_settime/timer_settime02.c
index bcabb76956f8..e82adddc3189 100644
--- a/testcases/kernel/syscalls/timer_settime/timer_settime02.c
+++ b/testcases/kernel/syscalls/timer_settime/timer_settime02.c
@@ -25,12 +25,13 @@

#include <errno.h>
#include <time.h>
-#include "tst_test.h"
-#include "lapi/common_timers.h"
+#include "tst_timer.h"

-static struct itimerspec new_set, old_set;
-static kernel_timer_t timer;
-static kernel_timer_t timer_inval = -1;
+static struct tst_its new_set, old_set;
+static struct tst_its *pnew_set = &new_set, *pold_set = &old_set, *null_set = NULL;
+static void *faulty_set;
+static timer_t timer;
+static timer_t timer_inval = -1;

/* separate description-array to (hopefully) improve readability */
static const char * const descriptions[] = {
@@ -43,24 +44,47 @@ static const char * const descriptions[] = {
};

static struct testcase {
- kernel_timer_t *timer_id;
- struct itimerspec *new_ptr;
- struct itimerspec *old_ptr;
+ timer_t *timer_id;
+ struct tst_its **new_ptr;
+ struct tst_its **old_ptr;
int it_value_tv_nsec;
int error;
} tcases[] = {
- {&timer, NULL, &old_set, 0, EINVAL},
- {&timer, &new_set, &old_set, -1, EINVAL},
- {&timer, &new_set, &old_set, NSEC_PER_SEC + 1, EINVAL},
- {&timer_inval, &new_set, &old_set, 0, EINVAL},
- {&timer, (struct itimerspec *) -1, &old_set, 0, EFAULT},
- {&timer, &new_set, (struct itimerspec *) -1, 0, EFAULT},
+ {&timer, &null_set, &pold_set, 0, EINVAL},
+ {&timer, &pnew_set, &pold_set, -1, EINVAL},
+ {&timer, &pnew_set, &pold_set, NSEC_PER_SEC + 1, EINVAL},
+ {&timer_inval, &pnew_set, &pold_set, 0, EINVAL},
+ {&timer, (struct tst_its **)&faulty_set, &pold_set, 0, EFAULT},
+ {&timer, &pnew_set, (struct tst_its **)&faulty_set, 0, EFAULT},
};

+static struct test_variants {
+ int (*func)(timer_t timerid, int flags, void *its,
+ void *old_its);
+ enum tst_ts_type type;
+ char *desc;
+} variants[] = {
+#if (__NR_timer_settime != __LTP__NR_INVALID_SYSCALL)
+ { .func = sys_timer_settime, .type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"},
+#endif
+
+#if (__NR_timer_settime64 != __LTP__NR_INVALID_SYSCALL)
+ { .func = sys_timer_settime64, .type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"},
+#endif
+};
+
+static void setup(void)
+{
+ tst_res(TINFO, "Testing variant: %s", variants[tst_variant].desc);
+ faulty_set = tst_get_bad_addr(NULL);
+}
+
static void run(unsigned int n)
{
- unsigned int i;
+ struct test_variants *tv = &variants[tst_variant];
struct testcase *tc = &tcases[n];
+ void *new, *old;
+ unsigned int i;

tst_res(TINFO, "Testing for %s:", descriptions[n]);

@@ -91,11 +115,16 @@ static void run(unsigned int n)
memset(&new_set, 0, sizeof(new_set));
memset(&old_set, 0, sizeof(old_set));

- new_set.it_value.tv_sec = 5;
- new_set.it_value.tv_nsec = tc->it_value_tv_nsec;
+ new_set.type = old_set.type = tv->type;
+ tst_its_set_interval_sec(&new_set, 0);
+ tst_its_set_interval_nsec(&new_set, 0);
+ tst_its_set_value_sec(&new_set, 5);
+ tst_its_set_value_nsec(&new_set, tc->it_value_tv_nsec);
+
+ new = (tc->new_ptr == (struct tst_its **)&faulty_set) ? faulty_set : tst_its_get(*tc->new_ptr);
+ old = (tc->old_ptr == (struct tst_its **)&faulty_set) ? faulty_set : tst_its_get(*tc->old_ptr);

- TEST(tst_syscall(__NR_timer_settime, *tc->timer_id,
- 0, tc->new_ptr, tc->old_ptr));
+ TEST(tv->func(*tc->timer_id, 0, new, old));

if (tc->error != TST_ERR) {
tst_res(TFAIL | TTERRNO,
@@ -119,6 +148,8 @@ static struct tst_test test = {
.test = run,
.needs_root = 1,
.tcnt = ARRAY_SIZE(tcases),
+ .test_variants = ARRAY_SIZE(variants),
+ .setup = setup,
.tags = (const struct tst_tag[]) {
{"linux-git", "f18ddc13af98"},
{}
--
2.25.0.rc1.19.g042ed3e048af