/* Clocksource change test
 *		by: john stultz (johnstul@us.ibm.com)
 *		(C) Copyright IBM 2012
 *		Licensed under the GPLv2
 *
 *  NOTE: This is a meta-test which quickly changes the clocksource and
 *  then uses other tests to detect problems. Thus this test requires
 *  that the inconsistency-check and nanosleep tests be present in the
 *  same directory it is run from.
 *
 *  To build:
 *	$ gcc clocksource-switch.c -o clocksource-switch -lrt
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 */


#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/timex.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include "../kselftest.h"


int get_clocksources(char list[][30])
{
	int fd, i;
	size_t size;
	char buf[512];
	char *head, *tmp;

	fd = open("/sys/devices/system/clocksource/clocksource0/available_clocksource", O_RDONLY);

	size = read(fd, buf, 512);

	close(fd);

	for (i = 0; i < 10; i++)
		list[i][0] = '\0';

	head = buf;
	i = 0;
	while (head - buf < size) {
		/* Find the next space */
		for (tmp = head; *tmp != ' '; tmp++) {
			if (*tmp == '\n')
				break;
			if (*tmp == '\0')
				break;
		}
		*tmp = '\0';
		strcpy(list[i], head);
		head = tmp + 1;
		i++;
	}

	return i-1;
}

int get_cur_clocksource(char *buf, size_t size)
{
	int fd;

	fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_RDONLY);

	size = read(fd, buf, size);

	return 0;
}

int change_clocksource(char *clocksource)
{
	int fd;
	ssize_t size;

	fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY);

	if (fd < 0)
		return -1;

	size = write(fd, clocksource, strlen(clocksource));

	if (size < 0)
		return -1;

	close(fd);
	return 0;
}


int run_tests(int secs)
{
	int ret;
	char buf[255];

	sprintf(buf, "./inconsistency-check -t %i", secs);
	ret = system(buf);
	if (WIFEXITED(ret) && WEXITSTATUS(ret))
		return WEXITSTATUS(ret);
	ret = system("./nanosleep");
	return WIFEXITED(ret) ? WEXITSTATUS(ret) : 0;
}


char clocksource_list[10][30];

int main(int argc, char **argv)
{
	char orig_clk[512];
	int count, i, status, opt;
	int do_sanity_check = 1;
	int runtime = 60;
	pid_t pid;

	/* Process arguments */
	while ((opt = getopt(argc, argv, "st:")) != -1) {
		switch (opt) {
		case 's':
			do_sanity_check = 0;
			break;
		case 't':
			runtime = atoi(optarg);
			break;
		default:
			printf("Usage: %s [-s] [-t <secs>]\n", argv[0]);
			printf("	-s: skip sanity checks\n");
			printf("	-t: Number of seconds to run\n");
			exit(-1);
		}
	}

	get_cur_clocksource(orig_clk, 512);

	count = get_clocksources(clocksource_list);

	if (change_clocksource(clocksource_list[0])) {
		printf("Error: You probably need to run this as root\n");
		return -1;
	}

	/* Check everything is sane before we start switching asynchronously */
	if (do_sanity_check) {
		for (i = 0; i < count; i++) {
			printf("Validating clocksource %s\n",
				clocksource_list[i]);
			if (change_clocksource(clocksource_list[i])) {
				status = -1;
				goto out;
			}
			if (run_tests(5)) {
				status = -1;
				goto out;
			}
		}
	}

	printf("Running Asynchronous Switching Tests...\n");
	pid = fork();
	if (!pid)
		return run_tests(runtime);

	while (pid != waitpid(pid, &status, WNOHANG))
		for (i = 0; i < count; i++)
			if (change_clocksource(clocksource_list[i])) {
				status = -1;
				goto out;
			}
out:
	change_clocksource(orig_clk);

	/* Print at the end to not mix output with child process */
	ksft_print_header();
	ksft_set_plan(1);
	ksft_test_result(!status, "clocksource-switch\n");
	ksft_exit(!status);
}
