[Devel] [PATCH] ve: add ability to set offset for monotonic time

Andrew Vagin avagin at openvz.org
Mon Nov 30 07:16:08 PST 2015


Monotonic time can't be changed by users, can't go back and it starts with
zero when a kernel starts.

When we migrate a container on another host, we need to save consistancy
of monotonic time, so we have a per-ve offset.

This patch adds the ability to set this offset. When a container is
migrated, the value from ve.start_timespec on a source host should be
written in the same file on a destination host.

https://jira.sw.ru/browse/PSBM-41311?jql=text%20~%20%22of%20persia%22

Cc: Cyrill Gorcunov <gorcunov at openvz.org>
Signed-off-by: Andrew Vagin <avagin at openvz.org>
---
 include/linux/ve.h    |    3 +++
 kernel/posix-timers.c |   41 +++++++++++++++++++++++++++++++++++++++++
 kernel/ve/ve.c        |   36 ++++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 0 deletions(-)

diff --git a/include/linux/ve.h b/include/linux/ve.h
index 86b95c3..5f972aa 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -222,6 +222,9 @@ extern struct tty_driver *vtty_console_driver(int *index);
 extern int vtty_open_master(envid_t veid, int idx);
 #endif /* CONFIG_TTY */
 
+extern int get_ve_monotonic_time(struct ve_struct *ve, struct timespec *tp);
+extern int set_ve_monotonic_time(struct ve_struct *ve, struct timespec *tp);
+
 #else	/* CONFIG_VE */
 
 #define ve_uevent_seqnum uevent_seqnum
diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c
index a4b1ca7..25ff0ca 100644
--- a/kernel/posix-timers.c
+++ b/kernel/posix-timers.c
@@ -1053,6 +1053,47 @@ SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock,
 	return kc->clock_set(which_clock, &new_tp);
 }
 
+#ifdef CONFIG_VE
+int get_ve_monotonic_time(struct ve_struct *ve, struct timespec *tp)
+{
+	struct k_clock *kc = clockid_to_kclock(CLOCK_MONOTONIC);
+	int error;
+
+	if (!kc)
+		return -EINVAL;
+
+	error = kc->clock_get(CLOCK_MONOTONIC, tp);
+	if (error)
+		return error;
+
+	set_normalized_timespec(tp,
+			tp->tv_sec - ve->start_timespec.tv_sec,
+			tp->tv_nsec - ve->start_timespec.tv_nsec);
+
+	return 0;
+}
+
+int set_ve_monotonic_time(struct ve_struct *ve, struct timespec *tp)
+{
+	struct timespec kernel_tp;
+	struct k_clock *kc = clockid_to_kclock(CLOCK_MONOTONIC);
+	int error;
+
+	if (!kc)
+		return -EINVAL;
+
+	error = kc->clock_get(CLOCK_MONOTONIC, &kernel_tp);
+	if (error)
+		return error;
+
+	set_normalized_timespec(&ve->start_timespec,
+			kernel_tp.tv_sec - tp->tv_sec,
+			kernel_tp.tv_nsec - tp->tv_nsec);
+
+	return 0;
+}
+#endif
+
 SYSCALL_DEFINE2(clock_gettime, const clockid_t, which_clock,
 		struct timespec __user *,tp)
 {
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index e9219e6..eafef1c 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -768,6 +768,24 @@ static void ve_attach(struct cgroup *cg, struct cgroup_taskset *tset)
 	on_each_cpu(ve_update_cpuid_faulting, NULL, 1);
 }
 
+static int ve_start_timespec_read(struct cgroup *cg, struct cftype *cft,
+			 struct seq_file *m)
+{
+	struct ve_struct *ve = cgroup_ve(cg);
+	struct timespec tp;
+	char str[42];
+	int error;
+
+	error = get_ve_monotonic_time(ve, &tp);
+	if (error)
+		return error;
+
+	snprintf(str, sizeof(str), "%ld %ld", tp.tv_sec, tp.tv_nsec);
+	seq_puts(m, str);
+
+	return 0;
+}
+
 static int ve_state_read(struct cgroup *cg, struct cftype *cft,
 			 struct seq_file *m)
 {
@@ -810,6 +828,18 @@ static void ve_start_work(struct callback_head *head)
 	kfree(work);
 }
 
+static int ve_start_timespec_write(struct cgroup *cg, struct cftype *cft,
+			  const char *buffer)
+{
+	struct ve_struct *ve = cgroup_ve(cg);
+	struct timespec tp;
+
+	if (sscanf(buffer, "%ld %ld\n", &tp.tv_sec, &tp.tv_nsec) != 2)
+		return -EINVAL;
+
+	return set_ve_monotonic_time(ve, &tp);
+}
+
 static int ve_state_write(struct cgroup *cg, struct cftype *cft,
 			  const char *buffer)
 {
@@ -1214,6 +1244,12 @@ static struct cftype ve_cftypes[] = {
 		.write_u64		= ve_write_u64,
 		.private		= VE_CF_IPTABLES_MASK,
 	},
+	{
+		.name			= "start_timespec",
+		.flags			= CFTYPE_NOT_ON_ROOT,
+		.read_seq_string	= ve_start_timespec_read,
+		.write_string		= ve_start_timespec_write,
+	},
 	{ }
 };
 
-- 
1.7.1



More information about the Devel mailing list