0001
0002 #define _GNU_SOURCE
0003 #include <sched.h>
0004
0005 #include <sys/timerfd.h>
0006 #include <sys/syscall.h>
0007 #include <time.h>
0008 #include <unistd.h>
0009 #include <stdlib.h>
0010 #include <stdio.h>
0011 #include <stdint.h>
0012 #include <pthread.h>
0013 #include <signal.h>
0014 #include <string.h>
0015
0016 #include "log.h"
0017 #include "timens.h"
0018
0019 void test_sig(int sig)
0020 {
0021 if (sig == SIGUSR2)
0022 pthread_exit(NULL);
0023 }
0024
0025 struct thread_args {
0026 struct timespec *now, *rem;
0027 pthread_mutex_t *lock;
0028 int clockid;
0029 int abs;
0030 };
0031
0032 void *call_nanosleep(void *_args)
0033 {
0034 struct thread_args *args = _args;
0035
0036 clock_nanosleep(args->clockid, args->abs ? TIMER_ABSTIME : 0, args->now, args->rem);
0037 pthread_mutex_unlock(args->lock);
0038 return NULL;
0039 }
0040
0041 int run_test(int clockid, int abs)
0042 {
0043 struct timespec now = {}, rem;
0044 struct thread_args args = { .now = &now, .rem = &rem, .clockid = clockid};
0045 struct timespec start;
0046 pthread_mutex_t lock;
0047 pthread_t thread;
0048 int j, ok, ret;
0049
0050 signal(SIGUSR1, test_sig);
0051 signal(SIGUSR2, test_sig);
0052
0053 pthread_mutex_init(&lock, NULL);
0054 pthread_mutex_lock(&lock);
0055
0056 if (clock_gettime(clockid, &start) == -1) {
0057 if (errno == EINVAL && check_skip(clockid))
0058 return 0;
0059 return pr_perror("clock_gettime");
0060 }
0061
0062
0063 if (abs) {
0064 now.tv_sec = start.tv_sec;
0065 now.tv_nsec = start.tv_nsec;
0066 }
0067
0068 now.tv_sec += 3600;
0069 args.abs = abs;
0070 args.lock = &lock;
0071 ret = pthread_create(&thread, NULL, call_nanosleep, &args);
0072 if (ret != 0) {
0073 pr_err("Unable to create a thread: %s", strerror(ret));
0074 return 1;
0075 }
0076
0077
0078 ok = 0;
0079 for (j = 0; j < 8; j++) {
0080
0081 usleep(10000 << j);
0082
0083
0084 pthread_kill(thread, SIGUSR1);
0085
0086 usleep(10000 << j);
0087
0088 if (pthread_mutex_trylock(&lock) == 0) {
0089
0090 ok = 1;
0091 break;
0092 }
0093 }
0094 if (!ok)
0095 pthread_kill(thread, SIGUSR2);
0096 pthread_join(thread, NULL);
0097 pthread_mutex_destroy(&lock);
0098
0099 if (!ok) {
0100 ksft_test_result_pass("clockid: %d abs:%d timeout\n", clockid, abs);
0101 return 1;
0102 }
0103
0104 if (rem.tv_sec < 3300 || rem.tv_sec > 3900) {
0105 pr_fail("clockid: %d abs: %d remain: %ld\n",
0106 clockid, abs, rem.tv_sec);
0107 return 1;
0108 }
0109 ksft_test_result_pass("clockid: %d abs:%d\n", clockid, abs);
0110
0111 return 0;
0112 }
0113
0114 int main(int argc, char *argv[])
0115 {
0116 int ret, nsfd;
0117
0118 nscheck();
0119
0120 ksft_set_plan(4);
0121
0122 check_supported_timers();
0123
0124 if (unshare_timens())
0125 return 1;
0126
0127 if (_settime(CLOCK_MONOTONIC, 7 * 24 * 3600))
0128 return 1;
0129 if (_settime(CLOCK_BOOTTIME, 9 * 24 * 3600))
0130 return 1;
0131
0132 nsfd = open("/proc/self/ns/time_for_children", O_RDONLY);
0133 if (nsfd < 0)
0134 return pr_perror("Unable to open timens_for_children");
0135
0136 if (setns(nsfd, CLONE_NEWTIME))
0137 return pr_perror("Unable to set timens");
0138
0139 ret = 0;
0140 ret |= run_test(CLOCK_MONOTONIC, 0);
0141 ret |= run_test(CLOCK_MONOTONIC, 1);
0142 ret |= run_test(CLOCK_BOOTTIME_ALARM, 0);
0143 ret |= run_test(CLOCK_BOOTTIME_ALARM, 1);
0144
0145 if (ret)
0146 ksft_exit_fail();
0147 ksft_exit_pass();
0148 return ret;
0149 }