diff options
author | Dmitry Safonov <dima@arista.com> | 2019-11-12 01:27:17 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2020-01-14 12:21:00 +0100 |
commit | 61c57676035df29a0a61991f4389e884ba0b68d7 (patch) | |
tree | 3124d5cc777473a03c406deb4c3aa9ffc57e6409 /tools/testing/selftests/timens/timens.h | |
parent | fs/proc: Introduce /proc/pid/timens_offsets (diff) | |
download | linux-dev-61c57676035df29a0a61991f4389e884ba0b68d7.tar.xz linux-dev-61c57676035df29a0a61991f4389e884ba0b68d7.zip |
selftests/timens: Add Time Namespace test for supported clocks
A test to check that all supported clocks work on host and inside
a new time namespace. Use both ways to get time: through VDSO and
by entering the kernel with implicit syscall.
Introduce a new timens directory in selftests framework for
the next timens tests.
Output on success:
1..10
ok 1 Passed for CLOCK_BOOTTIME (syscall)
ok 2 Passed for CLOCK_BOOTTIME (vdso)
ok 3 Passed for CLOCK_BOOTTIME_ALARM (syscall)
ok 4 Passed for CLOCK_BOOTTIME_ALARM (vdso)
ok 5 Passed for CLOCK_MONOTONIC (syscall)
ok 6 Passed for CLOCK_MONOTONIC (vdso)
ok 7 Passed for CLOCK_MONOTONIC_COARSE (syscall)
ok 8 Passed for CLOCK_MONOTONIC_COARSE (vdso)
ok 9 Passed for CLOCK_MONOTONIC_RAW (syscall)
ok 10 Passed for CLOCK_MONOTONIC_RAW (vdso)
# Pass 10 Fail 0 Xfail 0 Xpass 0 Skip 0 Error 0
Output with lack of permissions:
1..10
not ok 1 # SKIP need to run as root
Output without support of time namespaces:
1..10
not ok 1 # SKIP Time namespaces are not supported
Co-developed-by: Andrei Vagin <avagin@openvz.org>
Signed-off-by: Andrei Vagin <avagin@gmail.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-29-dima@arista.com
Diffstat (limited to 'tools/testing/selftests/timens/timens.h')
-rw-r--r-- | tools/testing/selftests/timens/timens.h | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/tools/testing/selftests/timens/timens.h b/tools/testing/selftests/timens/timens.h new file mode 100644 index 000000000000..e09e7e39bc52 --- /dev/null +++ b/tools/testing/selftests/timens/timens.h @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __TIMENS_H__ +#define __TIMENS_H__ + +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdbool.h> + +#include "../kselftest.h" + +#ifndef CLONE_NEWTIME +# define CLONE_NEWTIME 0x00000080 +#endif + +static int config_posix_timers = true; + +static inline void check_config_posix_timers(void) +{ + if (timer_create(-1, 0, 0) == -1 && errno == ENOSYS) + config_posix_timers = false; +} + +static inline bool check_skip(int clockid) +{ + if (config_posix_timers) + return false; + + switch (clockid) { + /* Only these clocks are supported without CONFIG_POSIX_TIMERS. */ + case CLOCK_BOOTTIME: + case CLOCK_MONOTONIC: + case CLOCK_REALTIME: + return false; + default: + ksft_test_result_skip("Posix Clocks & timers are not supported\n"); + return true; + } + + return false; +} + +static inline int unshare_timens(void) +{ + if (unshare(CLONE_NEWTIME)) { + if (errno == EPERM) + ksft_exit_skip("need to run as root\n"); + return pr_perror("Can't unshare() timens"); + } + return 0; +} + +static inline int _settime(clockid_t clk_id, time_t offset) +{ + int fd, len; + char buf[4096]; + + if (clk_id == CLOCK_MONOTONIC_COARSE || clk_id == CLOCK_MONOTONIC_RAW) + clk_id = CLOCK_MONOTONIC; + + len = snprintf(buf, sizeof(buf), "%d %ld 0", clk_id, offset); + + 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); + + return 0; +} + +static inline int _gettime(clockid_t clk_id, struct timespec *res, bool raw_syscall) +{ + int err; + + if (!raw_syscall) { + if (clock_gettime(clk_id, res)) { + pr_perror("clock_gettime(%d)", (int)clk_id); + return -1; + } + return 0; + } + + err = syscall(SYS_clock_gettime, clk_id, res); + if (err) + pr_perror("syscall(SYS_clock_gettime(%d))", (int)clk_id); + + return err; +} + +static inline void nscheck(void) +{ + if (access("/proc/self/ns/time", F_OK) < 0) + ksft_exit_skip("Time namespaces are not supported\n"); +} + +#endif |