brintos

brintos / linux-shallow public Read only

0
0
Text · 2.3 KiB · d4fc52d Raw
112 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */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_NEWTIME13# define CLONE_NEWTIME	0x0000008014#endif15 16static int config_posix_timers = true;17static int config_alarm_timers = true;18 19static inline void check_supported_timers(void)20{21	struct timespec ts;22 23	if (timer_create(-1, 0, 0) == -1 && errno == ENOSYS)24		config_posix_timers = false;25 26	if (clock_gettime(CLOCK_BOOTTIME_ALARM, &ts) == -1 && errno == EINVAL)27		config_alarm_timers = false;28}29 30static inline bool check_skip(int clockid)31{32	if (!config_alarm_timers && clockid == CLOCK_BOOTTIME_ALARM) {33		ksft_test_result_skip("CLOCK_BOOTTIME_ALARM isn't supported\n");34		return true;35	}36 37	if (config_posix_timers)38		return false;39 40	switch (clockid) {41	/* Only these clocks are supported without CONFIG_POSIX_TIMERS. */42	case CLOCK_BOOTTIME:43	case CLOCK_MONOTONIC:44	case CLOCK_REALTIME:45		return false;46	default:47		ksft_test_result_skip("Posix Clocks & timers are not supported\n");48		return true;49	}50 51	return false;52}53 54static inline int unshare_timens(void)55{56	if (unshare(CLONE_NEWTIME)) {57		if (errno == EPERM)58			ksft_exit_skip("need to run as root\n");59		return pr_perror("Can't unshare() timens");60	}61	return 0;62}63 64static inline int _settime(clockid_t clk_id, time_t offset)65{66	int fd, len;67	char buf[4096];68 69	if (clk_id == CLOCK_MONOTONIC_COARSE || clk_id == CLOCK_MONOTONIC_RAW)70		clk_id = CLOCK_MONOTONIC;71 72	len = snprintf(buf, sizeof(buf), "%d %ld 0", clk_id, offset);73 74	fd = open("/proc/self/timens_offsets", O_WRONLY);75	if (fd < 0)76		return pr_perror("/proc/self/timens_offsets");77 78	if (write(fd, buf, len) != len)79		return pr_perror("/proc/self/timens_offsets");80 81	close(fd);82 83	return 0;84}85 86static inline int _gettime(clockid_t clk_id, struct timespec *res, bool raw_syscall)87{88	int err;89 90	if (!raw_syscall) {91		if (clock_gettime(clk_id, res)) {92			pr_perror("clock_gettime(%d)", (int)clk_id);93			return -1;94		}95		return 0;96	}97 98	err = syscall(SYS_clock_gettime, clk_id, res);99	if (err)100		pr_perror("syscall(SYS_clock_gettime(%d))", (int)clk_id);101 102	return err;103}104 105static inline void nscheck(void)106{107	if (access("/proc/self/ns/time", F_OK) < 0)108		ksft_exit_skip("Time namespaces are not supported\n");109}110 111#endif112