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 <[email protected]> Signed-off-by: Andrew Vagin <[email protected]> --- 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 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
