18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#define _GNU_SOURCE 38c2ecf20Sopenharmony_ci#include <errno.h> 48c2ecf20Sopenharmony_ci#include <fcntl.h> 58c2ecf20Sopenharmony_ci#include <sched.h> 68c2ecf20Sopenharmony_ci#include <stdio.h> 78c2ecf20Sopenharmony_ci#include <stdbool.h> 88c2ecf20Sopenharmony_ci#include <sys/stat.h> 98c2ecf20Sopenharmony_ci#include <sys/syscall.h> 108c2ecf20Sopenharmony_ci#include <sys/types.h> 118c2ecf20Sopenharmony_ci#include <sys/wait.h> 128c2ecf20Sopenharmony_ci#include <time.h> 138c2ecf20Sopenharmony_ci#include <unistd.h> 148c2ecf20Sopenharmony_ci#include <string.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "log.h" 178c2ecf20Sopenharmony_ci#include "timens.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define OFFSET (36000) 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ciint main(int argc, char *argv[]) 228c2ecf20Sopenharmony_ci{ 238c2ecf20Sopenharmony_ci struct timespec now, tst; 248c2ecf20Sopenharmony_ci int status, i; 258c2ecf20Sopenharmony_ci pid_t pid; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci if (argc > 1) { 288c2ecf20Sopenharmony_ci if (sscanf(argv[1], "%ld", &now.tv_sec) != 1) 298c2ecf20Sopenharmony_ci return pr_perror("sscanf"); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci for (i = 0; i < 2; i++) { 328c2ecf20Sopenharmony_ci _gettime(CLOCK_MONOTONIC, &tst, i); 338c2ecf20Sopenharmony_ci if (abs(tst.tv_sec - now.tv_sec) > 5) 348c2ecf20Sopenharmony_ci return pr_fail("%ld %ld\n", now.tv_sec, tst.tv_sec); 358c2ecf20Sopenharmony_ci } 368c2ecf20Sopenharmony_ci return 0; 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci nscheck(); 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci ksft_set_plan(1); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &now); 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci if (unshare_timens()) 468c2ecf20Sopenharmony_ci return 1; 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci if (_settime(CLOCK_MONOTONIC, OFFSET)) 498c2ecf20Sopenharmony_ci return 1; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci for (i = 0; i < 2; i++) { 528c2ecf20Sopenharmony_ci _gettime(CLOCK_MONOTONIC, &tst, i); 538c2ecf20Sopenharmony_ci if (abs(tst.tv_sec - now.tv_sec) > 5) 548c2ecf20Sopenharmony_ci return pr_fail("%ld %ld\n", 558c2ecf20Sopenharmony_ci now.tv_sec, tst.tv_sec); 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci if (argc > 1) 598c2ecf20Sopenharmony_ci return 0; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci pid = fork(); 628c2ecf20Sopenharmony_ci if (pid < 0) 638c2ecf20Sopenharmony_ci return pr_perror("fork"); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci if (pid == 0) { 668c2ecf20Sopenharmony_ci char now_str[64]; 678c2ecf20Sopenharmony_ci char *cargv[] = {"exec", now_str, NULL}; 688c2ecf20Sopenharmony_ci char *cenv[] = {NULL}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci /* Check that a child process is in the new timens. */ 718c2ecf20Sopenharmony_ci for (i = 0; i < 2; i++) { 728c2ecf20Sopenharmony_ci _gettime(CLOCK_MONOTONIC, &tst, i); 738c2ecf20Sopenharmony_ci if (abs(tst.tv_sec - now.tv_sec - OFFSET) > 5) 748c2ecf20Sopenharmony_ci return pr_fail("%ld %ld\n", 758c2ecf20Sopenharmony_ci now.tv_sec + OFFSET, tst.tv_sec); 768c2ecf20Sopenharmony_ci } 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci /* Check for proper vvar offsets after execve. */ 798c2ecf20Sopenharmony_ci snprintf(now_str, sizeof(now_str), "%ld", now.tv_sec + OFFSET); 808c2ecf20Sopenharmony_ci execve("/proc/self/exe", cargv, cenv); 818c2ecf20Sopenharmony_ci return pr_perror("execve"); 828c2ecf20Sopenharmony_ci } 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci if (waitpid(pid, &status, 0) != pid) 858c2ecf20Sopenharmony_ci return pr_perror("waitpid"); 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci if (status) 888c2ecf20Sopenharmony_ci ksft_exit_fail(); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci ksft_test_result_pass("exec\n"); 918c2ecf20Sopenharmony_ci ksft_exit_pass(); 928c2ecf20Sopenharmony_ci return 0; 938c2ecf20Sopenharmony_ci} 94