summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2024-06-05 12:50:52 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2024-06-15 16:20:12 +0200
commited23f7cbcb5457be32a5fc133280fb56bfe043d2 (patch)
tree6e01016cb5040d503a6fdc68e86e757becc7baa9 /src
parentshared/clock-util: small modernization (diff)
downloadsystemd-ed23f7cbcb5457be32a5fc133280fb56bfe043d2.tar.xz
systemd-ed23f7cbcb5457be32a5fc133280fb56bfe043d2.zip
manager: use max of: compile epoch, epoch file, timesyncd file
Previously systemd would not use /var/lib/systemd/timesync/clock. This means that even if /var/ is mounted when systemd is started and the file is available, we would potentially make one time jump and than another time jump. From a user's POV, this doesn't seem useful at all. Also, we would always let /usr/lib/clock-epoch take priority over the built-in epoch. But there is no guarantee that this file is actually fresh. In particular, a user may touch /usr/lib/clock-epoch to work around a broken clock during installation (as recommended in [1]), and then this file will grow stale over time. So just load the three timestamps and use the highest one as the epoch. [1] https://discussion.fedoraproject.org/t/f38-to-f39-40-dnf-system-upgrade-can-fail-on-raspberry-pi/92403
Diffstat (limited to 'src')
-rw-r--r--src/core/clock-warp.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/src/core/clock-warp.c b/src/core/clock-warp.c
index d4dcc0440f..eff06ea1b8 100644
--- a/src/core/clock-warp.c
+++ b/src/core/clock-warp.c
@@ -19,18 +19,28 @@ int clock_reset_timewarp(void) {
}
void clock_apply_epoch(void) {
- usec_t epoch_usec;
+ usec_t epoch_usec = 0, timesyncd_usec = 0;
struct stat st;
int r;
+ r = RET_NERRNO(stat(TIMESYNCD_CLOCK_FILE, &st));
+ if (r >= 0)
+ epoch_usec = timespec_load(&st.st_mtim);
+ else if (r != -ENOENT)
+ log_warning_errno(r, "Could not stat %s, ignoring: %m", TIMESYNCD_CLOCK_FILE);
+
r = RET_NERRNO(stat(EPOCH_CLOCK_FILE, &st));
- if (r < 0) {
- if (r != -ENOENT)
- log_warning_errno(r, "Cannot stat " EPOCH_CLOCK_FILE ": %m");
+ if (r >= 0)
+ timesyncd_usec = timespec_load(&st.st_mtim);
+ else if (r != -ENOENT)
+ log_warning_errno(r, "Could not stat %s, ignoring: %m", EPOCH_CLOCK_FILE);
- epoch_usec = (usec_t) TIME_EPOCH * USEC_PER_SEC;
- } else
- epoch_usec = timespec_load(&st.st_mtim);
+ epoch_usec = MAX3(epoch_usec,
+ timesyncd_usec,
+ (usec_t) TIME_EPOCH * USEC_PER_SEC);
+
+ if (epoch_usec == 0) /* Weird, but may happen if mtimes were reset to 0 during compilation. */
+ return log_debug("Clock epoch is 0, skipping clock adjustment.");
usec_t now_usec = now(CLOCK_REALTIME);
bool advance;