Skip to content

Commit a750c74

Browse files
avaginKAGA-KOKO
authored andcommitted
selftests/timens: Check for right timens offsets after fork and exec
Output on success: 1..1 ok 1 exec # Pass 1 Fail 0 Xfail 0 Xpass 0 Skip 0 Error 0 Output on failure: 1..1 not ok 1 36016 16 Bail out! Output with lack of permissions: 1..1 not ok 1 # SKIP need to run as root Output without support of time namespaces: 1..1 not ok 1 # SKIP Time namespaces are not supported Co-developed-by: Dmitry Safonov <dima@arista.com> Signed-off-by: Andrei Vagin <avagin@gmail.com> Signed-off-by: Dmitry Safonov <dima@arista.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20191112012724.250792-35-dima@arista.com
1 parent 1854b97 commit a750c74

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed

tools/testing/selftests/timens/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
clock_nanosleep
2+
exec
23
gettime_perf
34
gettime_perf_cold
45
procfs

tools/testing/selftests/timens/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs
1+
TEST_GEN_PROGS := timens timerfd timer clock_nanosleep procfs exec
22
TEST_GEN_PROGS_EXTENDED := gettime_perf
33

44
CFLAGS := -Wall -Werror -pthread
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#define _GNU_SOURCE
3+
#include <errno.h>
4+
#include <fcntl.h>
5+
#include <sched.h>
6+
#include <stdio.h>
7+
#include <stdbool.h>
8+
#include <sys/stat.h>
9+
#include <sys/syscall.h>
10+
#include <sys/types.h>
11+
#include <sys/wait.h>
12+
#include <time.h>
13+
#include <unistd.h>
14+
#include <time.h>
15+
#include <string.h>
16+
17+
#include "log.h"
18+
#include "timens.h"
19+
20+
#define OFFSET (36000)
21+
22+
int main(int argc, char *argv[])
23+
{
24+
struct timespec now, tst;
25+
int status, i;
26+
pid_t pid;
27+
28+
if (argc > 1) {
29+
if (sscanf(argv[1], "%ld", &now.tv_sec) != 1)
30+
return pr_perror("sscanf");
31+
32+
for (i = 0; i < 2; i++) {
33+
_gettime(CLOCK_MONOTONIC, &tst, i);
34+
if (abs(tst.tv_sec - now.tv_sec) > 5)
35+
return pr_fail("%ld %ld\n", now.tv_sec, tst.tv_sec);
36+
}
37+
return 0;
38+
}
39+
40+
nscheck();
41+
42+
ksft_set_plan(1);
43+
44+
clock_gettime(CLOCK_MONOTONIC, &now);
45+
46+
if (unshare_timens())
47+
return 1;
48+
49+
if (_settime(CLOCK_MONOTONIC, OFFSET))
50+
return 1;
51+
52+
for (i = 0; i < 2; i++) {
53+
_gettime(CLOCK_MONOTONIC, &tst, i);
54+
if (abs(tst.tv_sec - now.tv_sec) > 5)
55+
return pr_fail("%ld %ld\n",
56+
now.tv_sec, tst.tv_sec);
57+
}
58+
59+
if (argc > 1)
60+
return 0;
61+
62+
pid = fork();
63+
if (pid < 0)
64+
return pr_perror("fork");
65+
66+
if (pid == 0) {
67+
char now_str[64];
68+
char *cargv[] = {"exec", now_str, NULL};
69+
char *cenv[] = {NULL};
70+
71+
/* Check that a child process is in the new timens. */
72+
for (i = 0; i < 2; i++) {
73+
_gettime(CLOCK_MONOTONIC, &tst, i);
74+
if (abs(tst.tv_sec - now.tv_sec - OFFSET) > 5)
75+
return pr_fail("%ld %ld\n",
76+
now.tv_sec + OFFSET, tst.tv_sec);
77+
}
78+
79+
/* Check for proper vvar offsets after execve. */
80+
snprintf(now_str, sizeof(now_str), "%ld", now.tv_sec + OFFSET);
81+
execve("/proc/self/exe", cargv, cenv);
82+
return pr_perror("execve");
83+
}
84+
85+
if (waitpid(pid, &status, 0) != pid)
86+
return pr_perror("waitpid");
87+
88+
if (status)
89+
ksft_exit_fail();
90+
91+
ksft_test_result_pass("exec\n");
92+
ksft_exit_pass();
93+
return 0;
94+
}

0 commit comments

Comments
 (0)