diff mbox series

[v2,7/9] syscalls/clock_gettime03: Add basic time namespace test

Message ID 20200318153801.3529-8-chrubis@suse.cz
State Accepted
Headers show
Series Add basic time namespace testcases | expand

Commit Message

Cyril Hrubis March 18, 2020, 3:37 p.m. UTC
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
 runtest/containers                            |   1 +
 runtest/syscalls                              |   1 +
 .../kernel/syscalls/clock_gettime/.gitignore  |   1 +
 .../syscalls/clock_gettime/clock_gettime03.c  | 112 ++++++++++++++++++
 4 files changed, 115 insertions(+)
 create mode 100644 testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
diff mbox series

Patch

diff --git a/runtest/containers b/runtest/containers
index 8100cd2bc..1006d8d35 100644
--- a/runtest/containers
+++ b/runtest/containers
@@ -89,3 +89,4 @@  userns07 userns07
 # time namespaces
 sysinfo03 sysinfo03
 clock_nanosleep03 clock_nanosleep03
+clock_gettime03 clock_gettime03
diff --git a/runtest/syscalls b/runtest/syscalls
index eac4eeffc..4949b5d36 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -91,6 +91,7 @@  clock_nanosleep03 clock_nanosleep03
 
 clock_gettime01 clock_gettime01
 clock_gettime02 clock_gettime02
+clock_gettime03 clock_gettime03
 leapsec01 leapsec01
 
 clock_settime01 clock_settime01
diff --git a/testcases/kernel/syscalls/clock_gettime/.gitignore b/testcases/kernel/syscalls/clock_gettime/.gitignore
index ba471c859..9d06613b6 100644
--- a/testcases/kernel/syscalls/clock_gettime/.gitignore
+++ b/testcases/kernel/syscalls/clock_gettime/.gitignore
@@ -1,3 +1,4 @@ 
 clock_gettime01
 clock_gettime02
+clock_gettime03
 leapsec01
diff --git a/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c b/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
new file mode 100644
index 000000000..8b8613ed1
--- /dev/null
+++ b/testcases/kernel/syscalls/clock_gettime/clock_gettime03.c
@@ -0,0 +1,112 @@ 
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+
+  Copyright (c) 2020 Cyril Hrubis <chrubis@suse.cz>
+
+ */
+/*
+
+  Basic test for timer namespaces.
+
+  After a call to unshare(CLONE_NEWTIME) a new timer namespace is created, the
+  process that has called the unshare() can adjust offsets for CLOCK_MONOTONIC
+  and CLOCK_BOOTTIME for its children by writing to the '/proc/self/timens_offsets'.
+
+  The child processes also switch to the initial parent namespace and checks
+  that the offset is set to 0.
+
+ */
+
+#define _GNU_SOURCE
+#include "tst_safe_clocks.h"
+#include "tst_timer.h"
+#include "lapi/namespaces_constants.h"
+#include "tst_test.h"
+
+static struct tcase {
+	int clk_id;
+	int clk_off;
+	int off;
+} tcases[] = {
+	{CLOCK_MONOTONIC, CLOCK_MONOTONIC, 10},
+	{CLOCK_BOOTTIME, CLOCK_BOOTTIME, 10},
+
+	{CLOCK_MONOTONIC, CLOCK_MONOTONIC, -10},
+	{CLOCK_BOOTTIME, CLOCK_BOOTTIME, -10},
+
+	{CLOCK_MONOTONIC_RAW, CLOCK_MONOTONIC, 100},
+	{CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC, 100},
+};
+
+static struct timespec now;
+static int parent_ns;
+
+static void child(struct tcase *tc)
+{
+	struct timespec then;
+	struct timespec parent_then;
+	long long diff;
+
+	SAFE_CLOCK_GETTIME(tc->clk_id, &then);
+
+	SAFE_SETNS(parent_ns, CLONE_NEWTIME);
+
+	SAFE_CLOCK_GETTIME(tc->clk_id, &parent_then);
+
+	diff = tst_timespec_diff_ms(then, now);
+
+	if (diff/1000 != tc->off) {
+		tst_res(TFAIL, "Wrong offset (%s) read %llims",
+		        tst_clock_name(tc->clk_id), diff);
+	} else {
+		tst_res(TPASS, "Offset (%s) is correct %llims",
+		        tst_clock_name(tc->clk_id), diff);
+	}
+
+	diff = tst_timespec_diff_ms(parent_then, now);
+
+	if (diff/1000) {
+		tst_res(TFAIL, "Wrong offset (%s) read %llims",
+		        tst_clock_name(tc->clk_id), diff);
+	} else {
+		tst_res(TPASS, "Offset (%s) is correct %llims",
+		        tst_clock_name(tc->clk_id), diff);
+	}
+}
+
+static void verify_ns_clock(unsigned int n)
+{
+	struct tcase *tc = &tcases[n];
+
+	SAFE_UNSHARE(CLONE_NEWTIME);
+
+	SAFE_FILE_PRINTF("/proc/self/timens_offsets", "%d %d 0",
+	                 tc->clk_off, tc->off);
+
+	SAFE_CLOCK_GETTIME(tc->clk_id, &now);
+
+	if (!SAFE_FORK())
+		child(tc);
+}
+
+static void setup(void)
+{
+	parent_ns = SAFE_OPEN("/proc/self/ns/time_for_children", O_RDONLY);
+}
+
+static void cleanup(void)
+{
+	SAFE_CLOSE(parent_ns);
+}
+
+static struct tst_test test = {
+	.setup = setup,
+	.cleanup = cleanup,
+	.tcnt = ARRAY_SIZE(tcases),
+	.test = verify_ns_clock,
+	.needs_root = 1,
+	.forks_child = 1,
+	.needs_kconfigs = (const char *[]) {
+		"CONFIG_TIME_NS=y"
+	}
+};