dryang / rpms / systemd

Forked from rpms/systemd a year ago
Clone
Blob Blame History Raw
From 016f8f9305a5584d718579f90ee537398dfed33b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Thu, 14 Sep 2017 18:26:10 +0200
Subject: [PATCH] timer: don't use persietent file timestamps from the future
 (#6823)

Also, use the mtime rather than the atime of the timestamp file. While
the atime is not completely wrong, the mtime appears more appropriate
as that's what we actually explicitly change, and is not effected by
mere reading.

Fixes: #6821
(cherry picked from commit 77542a7905520f1d637912bf47bddb4855506e41)

Resolves: #1769923
---
 src/core/timer.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/src/core/timer.c b/src/core/timer.c
index 1d4868643a..fb192d558a 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -595,9 +595,23 @@ static int timer_start(Unit *u) {
         if (t->stamp_path) {
                 struct stat st;
 
-                if (stat(t->stamp_path, &st) >= 0)
-                        t->last_trigger.realtime = timespec_load(&st.st_atim);
-                else if (errno == ENOENT)
+                if (stat(t->stamp_path, &st) >= 0) {
+                        usec_t ft;
+
+                        /* Load the file timestamp, but only if it is actually in the past. If it is in the future,
+                         * something is wrong with the system clock. */
+
+                        ft = timespec_load(&st.st_mtim);
+                        if (ft < now(CLOCK_REALTIME))
+                                t->last_trigger.realtime = ft;
+                        else {
+                                char z[FORMAT_TIMESTAMP_MAX];
+
+                                log_unit_warning(u->id, "%s not using persistent file timestamp %s as it is in the future.",
+                                                 u->id, format_timestamp(z, sizeof(z), ft));
+                        }
+
+                } else if (errno == ENOENT)
                         /* The timer has never run before,
                          * make sure a stamp file exists.
                          */