// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <string.h>

#include "log.h"
#include "timens.h"

/*
 * Test shouldn't be run for a day, so add 10 days to child
 * time and check parent's time to be in the same day.
 */
#define DAY_IN_SEC			(60*60*24)
#define TEN_DAYS_IN_SEC			(10*DAY_IN_SEC)

struct test_clock {
	clockid_t id;
	char *name;
	/*
	 * off_id is -1 if a clock has own offset, or it contains an index
	 * which contains a right offset of this clock.
	 */
	int off_id;
	time_t offset;
};

#define ct(clock, off_id)	{ clock, #clock, off_id }
static struct test_clock clocks[] = {
	ct(CLOCK_BOOTTIME, -1),
	ct(CLOCK_BOOTTIME_ALARM, 1),
	ct(CLOCK_MONOTONIC, -1),
	ct(CLOCK_MONOTONIC_COARSE, 1),
	ct(CLOCK_MONOTONIC_RAW, 1),
};
#undef ct

static int child_ns, parent_ns = -1;

static int switch_ns(int fd)
{
	if (setns(fd, CLONE_NEWTIME)) {
		pr_perror("setns()");
		return -1;
	}

	return 0;
}

static int init_namespaces(void)
{
	char path[] = "/proc/self/ns/time_for_children";
	struct stat st1, st2;

	if (parent_ns == -1) {
		parent_ns = open(path, O_RDONLY);
		if (parent_ns <= 0)
			return pr_perror("Unable to open %s", path);
	}

	if (fstat(parent_ns, &st1))
		return pr_perror("Unable to stat the parent timens");

	if (unshare_timens())
		return  -1;

	child_ns = open(path, O_RDONLY);
	if (child_ns <= 0)
		return pr_perror("Unable to open %s", path);

	if (fstat(child_ns, &st2))
		return pr_perror("Unable to stat the timens");

	if (st1.st_ino == st2.st_ino)
		return pr_perror("The same child_ns after CLONE_NEWTIME");

	return 0;
}

static int test_gettime(clockid_t clock_index, bool raw_syscall, time_t offset)
{
	struct timespec child_ts_new, parent_ts_old, cur_ts;
	char *entry = raw_syscall ? "syscall" : "vdso";
	double precision = 0.0;

	if (check_skip(clocks[clock_index].id))
		return 0;

	switch (clocks[clock_index].id) {
	case CLOCK_MONOTONIC_COARSE:
	case CLOCK_MONOTONIC_RAW:
		precision = -2.0;
		break;
	}

	if (switch_ns(parent_ns))
		return pr_err("switch_ns(%d)", child_ns);

	if (_gettime(clocks[clock_index].id, &parent_ts_old, raw_syscall))
		return -1;

	child_ts_new.tv_nsec = parent_ts_old.tv_nsec;
	child_ts_new.tv_sec = parent_ts_old.tv_sec + offset;

	if (switch_ns(child_ns))
		return pr_err("switch_ns(%d)", child_ns);

	if (_gettime(clocks[clock_index].id, &cur_ts, raw_syscall))
		return -1;

	if (difftime(cur_ts.tv_sec, child_ts_new.tv_sec) < precision) {
		ksft_test_result_fail(
			"Child's %s (%s) time has not changed: %lu -> %lu [%lu]\n",
			clocks[clock_index].name, entry, parent_ts_old.tv_sec,
			child_ts_new.tv_sec, cur_ts.tv_sec);
		return -1;
	}

	if (switch_ns(parent_ns))
		return pr_err("switch_ns(%d)", parent_ns);

	if (_gettime(clocks[clock_index].id, &cur_ts, raw_syscall))
		return -1;

	if (difftime(cur_ts.tv_sec, parent_ts_old.tv_sec) > DAY_IN_SEC) {
		ksft_test_result_fail(
			"Parent's %s (%s) time has changed: %lu -> %lu [%lu]\n",
			clocks[clock_index].name, entry, parent_ts_old.tv_sec,
			child_ts_new.tv_sec, cur_ts.tv_sec);
		/* Let's play nice and put it closer to original */
		clock_settime(clocks[clock_index].id, &cur_ts);
		return -1;
	}

	ksft_test_result_pass("Passed for %s (%s)\n",
				clocks[clock_index].name, entry);
	return 0;
}

int main(int argc, char *argv[])
{
	unsigned int i;
	time_t offset;
	int ret = 0;

	nscheck();

	check_supported_timers();

	ksft_set_plan(ARRAY_SIZE(clocks) * 2);

	if (init_namespaces())
		return 1;

	/* Offsets have to be set before tasks enter the namespace. */
	for (i = 0; i < ARRAY_SIZE(clocks); i++) {
		if (clocks[i].off_id != -1)
			continue;
		offset = TEN_DAYS_IN_SEC + i * 1000;
		clocks[i].offset = offset;
		if (_settime(clocks[i].id, offset))
			return 1;
	}

	for (i = 0; i < ARRAY_SIZE(clocks); i++) {
		if (clocks[i].off_id != -1)
			offset = clocks[clocks[i].off_id].offset;
		else
			offset = clocks[i].offset;
		ret |= test_gettime(i, true, offset);
		ret |= test_gettime(i, false, offset);
	}

	if (ret)
		ksft_exit_fail();

	ksft_exit_pass();
	return !!ret;
}
