0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <fcntl.h>
0027 #include <stdio.h>
0028 #include <stdlib.h>
0029 #include <string.h>
0030 #include <sys/stat.h>
0031 #include <sys/time.h>
0032 #include <sys/timex.h>
0033 #include <sys/types.h>
0034 #include <sys/wait.h>
0035 #include <time.h>
0036 #include <unistd.h>
0037 #include "../kselftest.h"
0038
0039
0040 int get_clocksources(char list[][30])
0041 {
0042 int fd, i;
0043 size_t size;
0044 char buf[512];
0045 char *head, *tmp;
0046
0047 fd = open("/sys/devices/system/clocksource/clocksource0/available_clocksource", O_RDONLY);
0048
0049 size = read(fd, buf, 512);
0050
0051 close(fd);
0052
0053 for (i = 0; i < 10; i++)
0054 list[i][0] = '\0';
0055
0056 head = buf;
0057 i = 0;
0058 while (head - buf < size) {
0059
0060 for (tmp = head; *tmp != ' '; tmp++) {
0061 if (*tmp == '\n')
0062 break;
0063 if (*tmp == '\0')
0064 break;
0065 }
0066 *tmp = '\0';
0067 strcpy(list[i], head);
0068 head = tmp + 1;
0069 i++;
0070 }
0071
0072 return i-1;
0073 }
0074
0075 int get_cur_clocksource(char *buf, size_t size)
0076 {
0077 int fd;
0078
0079 fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_RDONLY);
0080
0081 size = read(fd, buf, size);
0082
0083 return 0;
0084 }
0085
0086 int change_clocksource(char *clocksource)
0087 {
0088 int fd;
0089 ssize_t size;
0090
0091 fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY);
0092
0093 if (fd < 0)
0094 return -1;
0095
0096 size = write(fd, clocksource, strlen(clocksource));
0097
0098 if (size < 0)
0099 return -1;
0100
0101 close(fd);
0102 return 0;
0103 }
0104
0105
0106 int run_tests(int secs)
0107 {
0108 int ret;
0109 char buf[255];
0110
0111 sprintf(buf, "./inconsistency-check -t %i", secs);
0112 ret = system(buf);
0113 if (WIFEXITED(ret) && WEXITSTATUS(ret))
0114 return WEXITSTATUS(ret);
0115 ret = system("./nanosleep");
0116 return WIFEXITED(ret) ? WEXITSTATUS(ret) : 0;
0117 }
0118
0119
0120 char clocksource_list[10][30];
0121
0122 int main(int argc, char **argv)
0123 {
0124 char orig_clk[512];
0125 int count, i, status, opt;
0126 int do_sanity_check = 1;
0127 int runtime = 60;
0128 pid_t pid;
0129
0130
0131 while ((opt = getopt(argc, argv, "st:")) != -1) {
0132 switch (opt) {
0133 case 's':
0134 do_sanity_check = 0;
0135 break;
0136 case 't':
0137 runtime = atoi(optarg);
0138 break;
0139 default:
0140 printf("Usage: %s [-s] [-t <secs>]\n", argv[0]);
0141 printf(" -s: skip sanity checks\n");
0142 printf(" -t: Number of seconds to run\n");
0143 exit(-1);
0144 }
0145 }
0146
0147 get_cur_clocksource(orig_clk, 512);
0148
0149 count = get_clocksources(clocksource_list);
0150
0151 if (change_clocksource(clocksource_list[0])) {
0152 printf("Error: You probably need to run this as root\n");
0153 return -1;
0154 }
0155
0156
0157 if (do_sanity_check) {
0158 for (i = 0; i < count; i++) {
0159 printf("Validating clocksource %s\n",
0160 clocksource_list[i]);
0161 if (change_clocksource(clocksource_list[i])) {
0162 status = -1;
0163 goto out;
0164 }
0165 if (run_tests(5)) {
0166 status = -1;
0167 goto out;
0168 }
0169 }
0170 }
0171
0172 printf("Running Asynchronous Switching Tests...\n");
0173 pid = fork();
0174 if (!pid)
0175 return run_tests(runtime);
0176
0177 while (pid != waitpid(pid, &status, WNOHANG))
0178 for (i = 0; i < count; i++)
0179 if (change_clocksource(clocksource_list[i])) {
0180 status = -1;
0181 goto out;
0182 }
0183 out:
0184 change_clocksource(orig_clk);
0185
0186
0187 ksft_print_header();
0188 ksft_set_plan(1);
0189 ksft_test_result(!status, "clocksource-switch\n");
0190 ksft_exit(!status);
0191 }