7e7c9f
From 016f8f9305a5584d718579f90ee537398dfed33b Mon Sep 17 00:00:00 2001
7e7c9f
From: Lennart Poettering <lennart@poettering.net>
7e7c9f
Date: Thu, 14 Sep 2017 18:26:10 +0200
7e7c9f
Subject: [PATCH] timer: don't use persietent file timestamps from the future
7e7c9f
 (#6823)
7e7c9f
7e7c9f
Also, use the mtime rather than the atime of the timestamp file. While
7e7c9f
the atime is not completely wrong, the mtime appears more appropriate
7e7c9f
as that's what we actually explicitly change, and is not effected by
7e7c9f
mere reading.
7e7c9f
7e7c9f
Fixes: #6821
7e7c9f
(cherry picked from commit 77542a7905520f1d637912bf47bddb4855506e41)
7e7c9f
7e7c9f
Resolves: #1769923
7e7c9f
---
7e7c9f
 src/core/timer.c | 20 +++++++++++++++++---
7e7c9f
 1 file changed, 17 insertions(+), 3 deletions(-)
7e7c9f
7e7c9f
diff --git a/src/core/timer.c b/src/core/timer.c
7e7c9f
index 1d4868643a..fb192d558a 100644
7e7c9f
--- a/src/core/timer.c
7e7c9f
+++ b/src/core/timer.c
7e7c9f
@@ -595,9 +595,23 @@ static int timer_start(Unit *u) {
7e7c9f
         if (t->stamp_path) {
7e7c9f
                 struct stat st;
7e7c9f
 
7e7c9f
-                if (stat(t->stamp_path, &st) >= 0)
7e7c9f
-                        t->last_trigger.realtime = timespec_load(&st.st_atim);
7e7c9f
-                else if (errno == ENOENT)
7e7c9f
+                if (stat(t->stamp_path, &st) >= 0) {
7e7c9f
+                        usec_t ft;
7e7c9f
+
7e7c9f
+                        /* Load the file timestamp, but only if it is actually in the past. If it is in the future,
7e7c9f
+                         * something is wrong with the system clock. */
7e7c9f
+
7e7c9f
+                        ft = timespec_load(&st.st_mtim);
7e7c9f
+                        if (ft < now(CLOCK_REALTIME))
7e7c9f
+                                t->last_trigger.realtime = ft;
7e7c9f
+                        else {
7e7c9f
+                                char z[FORMAT_TIMESTAMP_MAX];
7e7c9f
+
7e7c9f
+                                log_unit_warning(u->id, "%s not using persistent file timestamp %s as it is in the future.",
7e7c9f
+                                                 u->id, format_timestamp(z, sizeof(z), ft));
7e7c9f
+                        }
7e7c9f
+
7e7c9f
+                } else if (errno == ENOENT)
7e7c9f
                         /* The timer has never run before,
7e7c9f
                          * make sure a stamp file exists.
7e7c9f
                          */