0001
0002 #define _GNU_SOURCE
0003 #include <sched.h>
0004
0005 #include <linux/unistd.h>
0006 #include <linux/futex.h>
0007 #include <stdio.h>
0008 #include <string.h>
0009 #include <sys/syscall.h>
0010 #include <sys/types.h>
0011 #include <sys/wait.h>
0012 #include <time.h>
0013 #include <unistd.h>
0014
0015 #include "log.h"
0016 #include "timens.h"
0017
0018 #define NSEC_PER_SEC 1000000000ULL
0019
0020 static int run_test(int clockid)
0021 {
0022 int futex_op = FUTEX_WAIT_BITSET;
0023 struct timespec timeout, end;
0024 int val = 0;
0025
0026 if (clockid == CLOCK_REALTIME)
0027 futex_op |= FUTEX_CLOCK_REALTIME;
0028
0029 clock_gettime(clockid, &timeout);
0030 timeout.tv_nsec += NSEC_PER_SEC / 10;
0031 if (timeout.tv_nsec > NSEC_PER_SEC) {
0032 timeout.tv_sec++;
0033 timeout.tv_nsec -= NSEC_PER_SEC;
0034 }
0035
0036 if (syscall(__NR_futex, &val, futex_op, 0,
0037 &timeout, 0, FUTEX_BITSET_MATCH_ANY) >= 0) {
0038 ksft_test_result_fail("futex didn't return ETIMEDOUT\n");
0039 return 1;
0040 }
0041
0042 if (errno != ETIMEDOUT) {
0043 ksft_test_result_fail("futex didn't return ETIMEDOUT: %s\n",
0044 strerror(errno));
0045 return 1;
0046 }
0047
0048 clock_gettime(clockid, &end);
0049
0050 if (end.tv_sec < timeout.tv_sec ||
0051 (end.tv_sec == timeout.tv_sec && end.tv_nsec < timeout.tv_nsec)) {
0052 ksft_test_result_fail("futex slept less than 100ms\n");
0053 return 1;
0054 }
0055
0056
0057 ksft_test_result_pass("futex with the %d clockid\n", clockid);
0058
0059 return 0;
0060 }
0061
0062 int main(int argc, char *argv[])
0063 {
0064 int status, len, fd;
0065 char buf[4096];
0066 pid_t pid;
0067 struct timespec mtime_now;
0068
0069 nscheck();
0070
0071 ksft_set_plan(2);
0072
0073 clock_gettime(CLOCK_MONOTONIC, &mtime_now);
0074
0075 if (unshare_timens())
0076 return 1;
0077
0078 len = snprintf(buf, sizeof(buf), "%d %d 0",
0079 CLOCK_MONOTONIC, 70 * 24 * 3600);
0080 fd = open("/proc/self/timens_offsets", O_WRONLY);
0081 if (fd < 0)
0082 return pr_perror("/proc/self/timens_offsets");
0083
0084 if (write(fd, buf, len) != len)
0085 return pr_perror("/proc/self/timens_offsets");
0086
0087 close(fd);
0088
0089 pid = fork();
0090 if (pid < 0)
0091 return pr_perror("Unable to fork");
0092 if (pid == 0) {
0093 int ret = 0;
0094
0095 ret |= run_test(CLOCK_REALTIME);
0096 ret |= run_test(CLOCK_MONOTONIC);
0097 if (ret)
0098 ksft_exit_fail();
0099 ksft_exit_pass();
0100 return 0;
0101 }
0102
0103 if (waitpid(pid, &status, 0) != pid)
0104 return pr_perror("Unable to wait the child process");
0105
0106 if (WIFEXITED(status))
0107 return WEXITSTATUS(status);
0108
0109 return 1;
0110 }