1
2#ifndef __TIMENS_H__
3#define __TIMENS_H__
4
5#include <fcntl.h>
6#include <unistd.h>
7#include <stdlib.h>
8#include <stdbool.h>
9
10#include "../kselftest.h"
11
12#ifndef CLONE_NEWTIME
13# define CLONE_NEWTIME 0x00000080
14#endif
15
16static int config_posix_timers = true;
17
18static inline void check_config_posix_timers(void)
19{
20 if (timer_create(-1, 0, 0) == -1 && errno == ENOSYS)
21 config_posix_timers = false;
22}
23
24static inline bool check_skip(int clockid)
25{
26 if (config_posix_timers)
27 return false;
28
29 switch (clockid) {
30
31 case CLOCK_BOOTTIME:
32 case CLOCK_MONOTONIC:
33 case CLOCK_REALTIME:
34 return false;
35 default:
36 ksft_test_result_skip("Posix Clocks & timers are not supported\n");
37 return true;
38 }
39
40 return false;
41}
42
43static inline int unshare_timens(void)
44{
45 if (unshare(CLONE_NEWTIME)) {
46 if (errno == EPERM)
47 ksft_exit_skip("need to run as root\n");
48 return pr_perror("Can't unshare() timens");
49 }
50 return 0;
51}
52
53static inline int _settime(clockid_t clk_id, time_t offset)
54{
55 int fd, len;
56 char buf[4096];
57
58 if (clk_id == CLOCK_MONOTONIC_COARSE || clk_id == CLOCK_MONOTONIC_RAW)
59 clk_id = CLOCK_MONOTONIC;
60
61 len = snprintf(buf, sizeof(buf), "%d %ld 0", clk_id, offset);
62
63 fd = open("/proc/self/timens_offsets", O_WRONLY);
64 if (fd < 0)
65 return pr_perror("/proc/self/timens_offsets");
66
67 if (write(fd, buf, len) != len)
68 return pr_perror("/proc/self/timens_offsets");
69
70 close(fd);
71
72 return 0;
73}
74
75static inline int _gettime(clockid_t clk_id, struct timespec *res, bool raw_syscall)
76{
77 int err;
78
79 if (!raw_syscall) {
80 if (clock_gettime(clk_id, res)) {
81 pr_perror("clock_gettime(%d)", (int)clk_id);
82 return -1;
83 }
84 return 0;
85 }
86
87 err = syscall(SYS_clock_gettime, clk_id, res);
88 if (err)
89 pr_perror("syscall(SYS_clock_gettime(%d))", (int)clk_id);
90
91 return err;
92}
93
94static inline void nscheck(void)
95{
96 if (access("/proc/self/ns/time", F_OK) < 0)
97 ksft_exit_skip("Time namespaces are not supported\n");
98}
99
100#endif
101