[2/8] stats: save uptime to know when dump had happened

Submitted by Pavel Tikhomirov on Feb. 17, 2018, 5:24 a.m.

Details

Message ID 1518845085-19089-3-git-send-email-ptikhomirov@virtuozzo.com
State New
Series "don't use wrong pagemap (from other task) on pid reuse"
Headers show

Commit Message

Pavel Tikhomirov Feb. 17, 2018, 5:24 a.m.
From: ptikhomirov <ptikhomirov@virtuozzo.com>

We want to use a simple fact: If we have an alive process in a pstree we
want to dump, and a starttime of that process is less than pre-dump's
timestamp, then these exact process existed (100% sure) at the time of
these pre-dump and the process' memory was dumped in images. Thus we
save uptime while in freezed state else these won't work.

https://jira.sw.ru/browse/PSBM-67502

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 criu/cr-dump.c       |  4 ++++
 criu/include/stats.h |  2 ++
 criu/proc_parse.c    |  2 +-
 criu/stats.c         | 22 ++++++++++++++++++++++
 images/stats.proto   |  2 ++
 5 files changed, 31 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/criu/cr-dump.c b/criu/cr-dump.c
index 0f4f438..9e84255 100644
--- a/criu/cr-dump.c
+++ b/criu/cr-dump.c
@@ -1571,6 +1571,8 @@  static int cr_pre_dump_finish(int ret)
 	 */
 	if (arch_set_thread_regs(root_item, false) < 0)
 		goto err;
+	if (timing_uptime(TIME_DUMP_UPTIME))
+		goto err;
 	pstree_switch_state(root_item, TASK_ALIVE);
 
 	timing_stop(TIME_FROZEN);
@@ -1798,6 +1800,8 @@  static int cr_dump_finish(int ret)
 
 	if (arch_set_thread_regs(root_item, true) < 0)
 		return -1;
+	if (timing_uptime(TIME_DUMP_UPTIME))
+		return -1;
 	pstree_switch_state(root_item,
 			    (ret || post_dump_ret) ?
 			    TASK_ALIVE : opts.final_state);
diff --git a/criu/include/stats.h b/criu/include/stats.h
index 07690b8..81775c8 100644
--- a/criu/include/stats.h
+++ b/criu/include/stats.h
@@ -7,6 +7,7 @@  enum {
 	TIME_MEMDUMP,
 	TIME_MEMWRITE,
 	TIME_IRMAP_RESOLVE,
+	TIME_DUMP_UPTIME,
 
 	DUMP_TIME_NR_STATS,
 };
@@ -20,6 +21,7 @@  enum {
 
 extern void timing_start(int t);
 extern void timing_stop(int t);
+extern int timing_uptime(int t);
 
 enum {
 	CNT_PAGES_SCANNED,
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 6614489..1c04f2a 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -2713,7 +2713,7 @@  int parse_children(pid_t pid, pid_t **_c, int *_n)
 	return -1;
 }
 
-__maybe_unused int parse_uptime(struct timeval *_tv)
+int parse_uptime(struct timeval *_tv)
 {
 	unsigned long sec, csec;
 	FILE *f;
diff --git a/criu/stats.c b/criu/stats.c
index 64679b1..2944474 100644
--- a/criu/stats.c
+++ b/criu/stats.c
@@ -9,6 +9,8 @@ 
 #include "stats.h"
 #include "util.h"
 #include "image.h"
+#include "pid.h"
+#include "proc_parse.h"
 #include "images/stats.pb-c.h"
 
 struct timing {
@@ -95,6 +97,14 @@  void timing_stop(int t)
 	timeval_accumulate(&tm->start, &now, &tm->total);
 }
 
+int timing_uptime(int t)
+{
+	struct timing *tm;
+
+	tm = get_timing(t);
+	return parse_uptime(&tm->total);
+}
+
 static void encode_time(int t, u_int32_t *to)
 {
 	struct timing *tm;
@@ -103,6 +113,14 @@  static void encode_time(int t, u_int32_t *to)
 	*to = tm->total.tv_sec * USEC_PER_SEC + tm->total.tv_usec;
 }
 
+static void encode_time_64(int t, u_int64_t *to)
+{
+	struct timing *tm;
+
+	tm = get_timing(t);
+	*to = tm->total.tv_sec * USEC_PER_SEC + tm->total.tv_usec;
+}
+
 static void display_stats(int what, StatsEntry *stats)
 {
 	if (what == DUMP_STATS) {
@@ -113,6 +131,8 @@  static void display_stats(int what, StatsEntry *stats)
 		pr_msg("Memory write time: %d us\n", stats->dump->memwrite_time);
 		if (stats->dump->has_irmap_resolve)
 			pr_msg("IRMAP resolve time: %d us\n", stats->dump->irmap_resolve);
+		if (stats->dump->has_dump_uptime)
+			pr_msg("Memory dump time-stamp: %" PRIu64 " us\n", stats->dump->dump_uptime);
 		pr_msg("Memory pages scanned: %" PRIu64 " (0x%" PRIx64 ")\n", stats->dump->pages_scanned,
 				stats->dump->pages_scanned);
 		pr_msg("Memory pages skipped from parent: %" PRIu64 " (0x%" PRIx64 ")\n",
@@ -155,6 +175,8 @@  void write_stats(int what)
 		encode_time(TIME_MEMWRITE, &ds_entry.memwrite_time);
 		ds_entry.has_irmap_resolve = true;
 		encode_time(TIME_IRMAP_RESOLVE, &ds_entry.irmap_resolve);
+		ds_entry.has_dump_uptime = true;
+		encode_time_64(TIME_DUMP_UPTIME, &ds_entry.dump_uptime);
 
 		ds_entry.pages_scanned = dstats->counts[CNT_PAGES_SCANNED];
 		ds_entry.pages_skipped_parent = dstats->counts[CNT_PAGES_SKIPPED_PARENT];
diff --git a/images/stats.proto b/images/stats.proto
index d765034..85c5008 100644
--- a/images/stats.proto
+++ b/images/stats.proto
@@ -16,6 +16,8 @@  message dump_stats_entry {
 	required uint64			pages_lazy		= 9;
 	optional uint64			page_pipes		= 10;
 	optional uint64			page_pipe_bufs		= 11;
+
+	optional uint64			dump_uptime		= 12;
 }
 
 message restore_stats_entry {