Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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         /* Check that a child process is in the new timens. */
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         /* Check for proper vvar offsets after execve. */
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 }