lkml.org 
[lkml]   [2019]   [Jul]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCHv5 35/37] selftest/timens: Add timer offsets test
    Date
    From: Andrei Vagin <avagin@openvz.org>

    Check that timer_create() takes into account clock offsets.

    Signed-off-by: Andrei Vagin <avagin@gmail.com>
    Co-developed-by: Dmitry Safonov <dima@arista.com>
    Signed-off-by: Dmitry Safonov <dima@arista.com>
    ---
    tools/testing/selftests/timens/.gitignore | 1 +
    tools/testing/selftests/timens/Makefile | 3 +-
    tools/testing/selftests/timens/timer.c | 118 ++++++++++++++++++++++
    3 files changed, 121 insertions(+), 1 deletion(-)
    create mode 100644 tools/testing/selftests/timens/timer.c

    diff --git a/tools/testing/selftests/timens/.gitignore b/tools/testing/selftests/timens/.gitignore
    index 94ffdd9cead7..3b7eda8f35ce 100644
    --- a/tools/testing/selftests/timens/.gitignore
    +++ b/tools/testing/selftests/timens/.gitignore
    @@ -1,4 +1,5 @@
    clock_nanosleep
    procfs
    timens
    +timer
    timerfd
    diff --git a/tools/testing/selftests/timens/Makefile b/tools/testing/selftests/timens/Makefile
    index f96f50d1fef8..ae1ffd24cc43 100644
    --- a/tools/testing/selftests/timens/Makefile
    +++ b/tools/testing/selftests/timens/Makefile
    @@ -1,5 +1,6 @@
    -TEST_GEN_PROGS := timens timerfd clock_nanosleep procfs
    +TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs

    CFLAGS := -Wall -Werror
    +LDFLAGS := -lrt

    include ../lib.mk
    diff --git a/tools/testing/selftests/timens/timer.c b/tools/testing/selftests/timens/timer.c
    new file mode 100644
    index 000000000000..45a9dd3cbb12
    --- /dev/null
    +++ b/tools/testing/selftests/timens/timer.c
    @@ -0,0 +1,118 @@
    +// SPDX-License-Identifier: GPL-2.0
    +#define _GNU_SOURCE
    +#include <sched.h>
    +
    +#include <sys/syscall.h>
    +#include <sys/types.h>
    +#include <sys/wait.h>
    +#include <time.h>
    +#include <unistd.h>
    +#include <stdlib.h>
    +#include <stdio.h>
    +#include <stdint.h>
    +#include <signal.h>
    +#include <time.h>
    +
    +#include "log.h"
    +#include "timens.h"
    +
    +int run_test(int clockid, struct timespec now)
    +{
    + struct itimerspec new_value;
    + long long elapsed;
    + timer_t fd;
    + int i;
    +
    + for (i = 0; i < 2; i++) {
    + struct sigevent sevp = {.sigev_notify = SIGEV_NONE};
    + int flags = 0;
    +
    + new_value.it_value.tv_sec = 3600;
    + new_value.it_value.tv_nsec = 0;
    + new_value.it_interval.tv_sec = 1;
    + new_value.it_interval.tv_nsec = 0;
    +
    + if (i == 1) {
    + new_value.it_value.tv_sec += now.tv_sec;
    + new_value.it_value.tv_nsec += now.tv_nsec;
    + }
    +
    + if (timer_create(clockid, &sevp, &fd) == -1)
    + return pr_perror("timerfd_create");
    +
    + if (i == 1)
    + flags |= TIMER_ABSTIME;
    + if (timer_settime(fd, flags, &new_value, NULL) == -1)
    + return pr_perror("timerfd_settime");
    +
    + if (timer_gettime(fd, &new_value) == -1)
    + return pr_perror("timerfd_gettime");
    +
    + elapsed = new_value.it_value.tv_sec;
    + if (abs(elapsed - 3600) > 60) {
    + ksft_test_result_fail("clockid: %d elapsed: %lld\n",
    + clockid, elapsed);
    + return 1;
    + }
    + }
    +
    + ksft_test_result_pass("clockid=%d\n", clockid);
    +
    + return 0;
    +}
    +
    +int main(int argc, char *argv[])
    +{
    + int ret, status, len, fd;
    + char buf[4096];
    + pid_t pid;
    + struct timespec btime_now, mtime_now;
    +
    + nscheck();
    +
    + ksft_set_plan(3);
    +
    + clock_gettime(CLOCK_MONOTONIC, &mtime_now);
    + clock_gettime(CLOCK_BOOTTIME, &btime_now);
    +
    + if (unshare(CLONE_NEWTIME))
    + return pr_perror("unshare");
    +
    + len = snprintf(buf, sizeof(buf), "%d %d 0\n%d %d 0",
    + CLOCK_MONOTONIC, 70 * 24 * 3600,
    + CLOCK_BOOTTIME, 9 * 24 * 3600);
    + fd = open("/proc/self/timens_offsets", O_WRONLY);
    + if (fd < 0)
    + return pr_perror("/proc/self/timens_offsets");
    +
    + if (write(fd, buf, len) != len)
    + return pr_perror("/proc/self/timens_offsets");
    +
    + close(fd);
    + mtime_now.tv_sec += 70 * 24 * 3600;
    + btime_now.tv_sec += 9 * 24 * 3600;
    +
    + pid = fork();
    + if (pid < 0)
    + return pr_perror("Unable to fork");
    + if (pid == 0) {
    + ret = 0;
    + ret |= run_test(CLOCK_BOOTTIME, btime_now);
    + ret |= run_test(CLOCK_MONOTONIC, mtime_now);
    + ret |= run_test(CLOCK_BOOTTIME_ALARM, btime_now);
    +
    + if (ret)
    + ksft_exit_fail();
    + ksft_exit_pass();
    + return ret;
    + }
    +
    + if (waitpid(pid, &status, 0) != pid)
    + return pr_perror("Unable to wait the child process");
    +
    + if (WIFEXITED(status))
    + return WEXITSTATUS(status);
    +
    + return 1;
    +}
    +
    --
    2.22.0
    \
     
     \ /
      Last update: 2019-07-30 00:09    [W:4.034 / U:0.268 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site