0001
0002 #define _GNU_SOURCE
0003 #include <errno.h>
0004 #include <fcntl.h>
0005 #include <sched.h>
0006 #include <stdio.h>
0007 #include <stdbool.h>
0008 #include <sys/stat.h>
0009 #include <sys/syscall.h>
0010 #include <sys/types.h>
0011 #include <sys/wait.h>
0012 #include <time.h>
0013 #include <unistd.h>
0014 #include <string.h>
0015
0016 #include "log.h"
0017 #include "timens.h"
0018
0019 #define OFFSET (36000)
0020
0021 int main(int argc, char *argv[])
0022 {
0023 struct timespec now, tst;
0024 int status, i;
0025 pid_t pid;
0026
0027 if (argc > 1) {
0028 if (sscanf(argv[1], "%ld", &now.tv_sec) != 1)
0029 return pr_perror("sscanf");
0030
0031 for (i = 0; i < 2; i++) {
0032 _gettime(CLOCK_MONOTONIC, &tst, i);
0033 if (abs(tst.tv_sec - now.tv_sec) > 5)
0034 return pr_fail("%ld %ld\n", now.tv_sec, tst.tv_sec);
0035 }
0036 return 0;
0037 }
0038
0039 nscheck();
0040
0041 ksft_set_plan(1);
0042
0043 clock_gettime(CLOCK_MONOTONIC, &now);
0044
0045 if (unshare_timens())
0046 return 1;
0047
0048 if (_settime(CLOCK_MONOTONIC, OFFSET))
0049 return 1;
0050
0051 for (i = 0; i < 2; i++) {
0052 _gettime(CLOCK_MONOTONIC, &tst, i);
0053 if (abs(tst.tv_sec - now.tv_sec) > 5)
0054 return pr_fail("%ld %ld\n",
0055 now.tv_sec, tst.tv_sec);
0056 }
0057
0058 if (argc > 1)
0059 return 0;
0060
0061 pid = fork();
0062 if (pid < 0)
0063 return pr_perror("fork");
0064
0065 if (pid == 0) {
0066 char now_str[64];
0067 char *cargv[] = {"exec", now_str, NULL};
0068 char *cenv[] = {NULL};
0069
0070
0071 for (i = 0; i < 2; i++) {
0072 _gettime(CLOCK_MONOTONIC, &tst, i);
0073 if (abs(tst.tv_sec - now.tv_sec - OFFSET) > 5)
0074 return pr_fail("%ld %ld\n",
0075 now.tv_sec + OFFSET, tst.tv_sec);
0076 }
0077
0078
0079 snprintf(now_str, sizeof(now_str), "%ld", now.tv_sec + OFFSET);
0080 execve("/proc/self/exe", cargv, cenv);
0081 return pr_perror("execve");
0082 }
0083
0084 if (waitpid(pid, &status, 0) != pid)
0085 return pr_perror("waitpid");
0086
0087 if (status)
0088 ksft_exit_fail();
0089
0090 ksft_test_result_pass("exec\n");
0091 ksft_exit_pass();
0092 return 0;
0093 }