Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #define _GNU_SOURCE
0003 #include <sched.h>
0004 
0005 #include <sys/syscall.h>
0006 #include <sys/types.h>
0007 #include <sys/wait.h>
0008 #include <time.h>
0009 #include <unistd.h>
0010 #include <stdlib.h>
0011 #include <stdio.h>
0012 #include <stdint.h>
0013 #include <signal.h>
0014 
0015 #include "log.h"
0016 #include "timens.h"
0017 
0018 int run_test(int clockid, struct timespec now)
0019 {
0020     struct itimerspec new_value;
0021     long long elapsed;
0022     timer_t fd;
0023     int i;
0024 
0025     if (check_skip(clockid))
0026         return 0;
0027 
0028     for (i = 0; i < 2; i++) {
0029         struct sigevent sevp = {.sigev_notify = SIGEV_NONE};
0030         int flags = 0;
0031 
0032         new_value.it_value.tv_sec = 3600;
0033         new_value.it_value.tv_nsec = 0;
0034         new_value.it_interval.tv_sec = 1;
0035         new_value.it_interval.tv_nsec = 0;
0036 
0037         if (i == 1) {
0038             new_value.it_value.tv_sec += now.tv_sec;
0039             new_value.it_value.tv_nsec += now.tv_nsec;
0040         }
0041 
0042         if (timer_create(clockid, &sevp, &fd) == -1) {
0043             if (errno == ENOSYS) {
0044                 ksft_test_result_skip("Posix Clocks & timers are supported\n");
0045                 return 0;
0046             }
0047             return pr_perror("timerfd_create");
0048         }
0049 
0050         if (i == 1)
0051             flags |= TIMER_ABSTIME;
0052         if (timer_settime(fd, flags, &new_value, NULL) == -1)
0053             return pr_perror("timerfd_settime");
0054 
0055         if (timer_gettime(fd, &new_value) == -1)
0056             return pr_perror("timerfd_gettime");
0057 
0058         elapsed = new_value.it_value.tv_sec;
0059         if (abs(elapsed - 3600) > 60) {
0060             ksft_test_result_fail("clockid: %d elapsed: %lld\n",
0061                           clockid, elapsed);
0062             return 1;
0063         }
0064     }
0065 
0066     ksft_test_result_pass("clockid=%d\n", clockid);
0067 
0068     return 0;
0069 }
0070 
0071 int main(int argc, char *argv[])
0072 {
0073     int ret, status, len, fd;
0074     char buf[4096];
0075     pid_t pid;
0076     struct timespec btime_now, mtime_now;
0077 
0078     nscheck();
0079 
0080     check_supported_timers();
0081 
0082     ksft_set_plan(3);
0083 
0084     clock_gettime(CLOCK_MONOTONIC, &mtime_now);
0085     clock_gettime(CLOCK_BOOTTIME, &btime_now);
0086 
0087     if (unshare_timens())
0088         return 1;
0089 
0090     len = snprintf(buf, sizeof(buf), "%d %d 0\n%d %d 0",
0091             CLOCK_MONOTONIC, 70 * 24 * 3600,
0092             CLOCK_BOOTTIME, 9 * 24 * 3600);
0093     fd = open("/proc/self/timens_offsets", O_WRONLY);
0094     if (fd < 0)
0095         return pr_perror("/proc/self/timens_offsets");
0096 
0097     if (write(fd, buf, len) != len)
0098         return pr_perror("/proc/self/timens_offsets");
0099 
0100     close(fd);
0101     mtime_now.tv_sec += 70 * 24 * 3600;
0102     btime_now.tv_sec += 9 * 24 * 3600;
0103 
0104     pid = fork();
0105     if (pid < 0)
0106         return pr_perror("Unable to fork");
0107     if (pid == 0) {
0108         ret = 0;
0109         ret |= run_test(CLOCK_BOOTTIME, btime_now);
0110         ret |= run_test(CLOCK_MONOTONIC, mtime_now);
0111         ret |= run_test(CLOCK_BOOTTIME_ALARM, btime_now);
0112 
0113         if (ret)
0114             ksft_exit_fail();
0115         ksft_exit_pass();
0116         return ret;
0117     }
0118 
0119     if (waitpid(pid, &status, 0) != pid)
0120         return pr_perror("Unable to wait the child process");
0121 
0122     if (WIFEXITED(status))
0123         return WEXITSTATUS(status);
0124 
0125     return 1;
0126 }