[Devel] [PATCH rh7] ve: Add interface for @start_timespec and @real_start_timespec adjustmen

Cyrill Gorcunov gorcunov at virtuozzo.com
Mon Feb 8 00:32:12 PST 2016


This two members represent monotonic and bootbased clocks for
container's uptime. When container is in suspended state (or
moving to another node) we trest monotonic and bootbased
clocks as being stopped so we need to account delta time
on restore and adjust the members in subject.

Moreover this timestamps are involved into posix-timers
setup so once application tries to setup monotonic clocks
after the restore (with absolute time specification) we
adjust the values as well.

The application which migrate a container must fetch
the current settings from /sys/fs/cgroup/ve/$VE/ve.real_start_timespec
and /sys/fs/cgroup/ve/$VE/ve.start_timespec, then write them
back on the restore.

https://jira.sw.ru/browse/PSBM-41311
https://jira.sw.ru/browse/PSBM-41406

Original-by: Andrew Vagin <avagin at openvz.org>
Signed-off-by: Cyrill Gorcunov <gorcunov at virtuozzo.com>
CC: Vasily Averin <vvs at virtuozzo.com>
CC: Andrey Vagin <avagin at virtuozzo.com>
CC: Pavel Emelianov <xemul at virtuozzo.com>
CC: Vladimir Davydov <vdavydov at virtuozzo.com>
CC: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 kernel/ve/ve.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

Index: linux-pcs7.git/kernel/ve/ve.c
===================================================================
--- linux-pcs7.git.orig/kernel/ve/ve.c
+++ linux-pcs7.git/kernel/ve/ve.c
@@ -1141,8 +1141,57 @@ enum {
 	VE_CF_FEATURES,
 	VE_CF_IPTABLES_MASK,
 	VE_CF_PSEUDOSUPER,
+	VE_CF_START_TIMESPEC,
+	VE_CF_REAL_START_TIMESPEC
 };
 
+static int ve_ts_read(struct cgroup *cg, struct cftype *cft, struct seq_file *m)
+{
+	struct ve_struct *ve = cgroup_ve(cg);
+	struct timespec ts, *delta;
+
+	do_posix_clock_monotonic_gettime(&ts);
+	if (cft->private == VE_CF_START_TIMESPEC) {
+		delta = &ve->start_timespec;
+	} else if (cft->private == VE_CF_REAL_START_TIMESPEC) {
+		delta = &ve->real_start_timespec;
+		monotonic_to_bootbased(&ts);
+	} else {
+		delta = &ts;
+		memset(&ts, 0, sizeof(ts));
+		WARN_ON_ONCE(1);
+	}
+
+	set_normalized_timespec(&ts, ts.tv_sec - delta->tv_sec,
+				ts.tv_nsec - delta->tv_nsec);
+	seq_printf(m, "%ld %ld", ts.tv_sec, ts.tv_nsec);
+	return 0;
+}
+
+static int ve_ts_write(struct cgroup *cg, struct cftype *cft, const char *buffer)
+{
+	struct ve_struct *ve = cgroup_ve(cg);
+	struct timespec ts, delta, *target;
+
+	if (sscanf(buffer, "%ld %ld", &delta.tv_sec, &delta.tv_nsec) != 2)
+		return -EINVAL;
+
+	do_posix_clock_monotonic_gettime(&ts);
+	if (cft->private == VE_CF_START_TIMESPEC) {
+		target = &ve->start_timespec;
+	} else if (cft->private == VE_CF_REAL_START_TIMESPEC) {
+		target = &ve->real_start_timespec;
+		monotonic_to_bootbased(&ts);
+	} else {
+		WARN_ON_ONCE(1);
+		return -EINVAL;
+	}
+
+	set_normalized_timespec(target, ts.tv_sec - delta.tv_sec,
+				ts.tv_nsec - delta.tv_nsec);
+	return 0;
+}
+
 static u64 ve_read_u64(struct cgroup *cg, struct cftype *cft)
 {
 	if (cft->private == VE_CF_FEATURES)
@@ -1258,6 +1307,20 @@ static struct cftype ve_cftypes[] = {
 		.write_u64		= ve_write_pseudosuper,
 		.private		= VE_CF_PSEUDOSUPER,
 	},
+	{
+		.name			= "start_timespec",
+		.flags			= CFTYPE_NOT_ON_ROOT,
+		.read_seq_string	= ve_ts_read,
+		.write_string		= ve_ts_write,
+		.private		= VE_CF_START_TIMESPEC,
+	},
+	{
+		.name			= "real_start_timespec",
+		.flags			= CFTYPE_NOT_ON_ROOT,
+		.read_seq_string	= ve_ts_read,
+		.write_string		= ve_ts_write,
+		.private		= VE_CF_REAL_START_TIMESPEC,
+	},
 	{ }
 };
 


More information about the Devel mailing list