systemd generates some timestamps before the very first call of settimeofday(). When we are in rtc-in-local time mode, these timestamps are wrong.
Affected timestamps are: Kernel, InitRD, Userspace, SecurityStart, SecurityFinish In this patch, adjustments are applied after the very first call. Before applying this patch: $ last hch tty1 Wed Nov 19 15:39 still logged in reboot system boot 3.16.0-4-amd64 Wed Nov 19 23:39 - 15:40 (-7:-59) ... $ systemctl show ... FirmwareTimestampMonotonic=0 LoaderTimestampMonotonic=0 KernelTimestamp=Wed 2014-11-19 23:39:10 CST KernelTimestampMonotonic=0 InitRDTimestampMonotonic=0 UserspaceTimestamp=Wed 2014-11-19 23:39:13 CST UserspaceTimestampMonotonic=2707714 FinishTimestamp=Wed 2014-11-19 15:39:25 CST FinishTimestampMonotonic=14463839 SecurityStartTimestamp=Wed 2014-11-19 23:39:13 CST SecurityStartTimestampMonotonic=2710030 SecurityFinishTimestamp=Wed 2014-11-19 23:39:13 CST SecurityFinishTimestampMonotonic=2721209 ... After applying this patch: $ last hch tty1 Wed Nov 19 15:43 still logged in reboot system boot 3.16.0-4-amd64 Wed Nov 19 15:43 - 15:43 (00:00) ... $ systemctl show ... FirmwareTimestampMonotonic=0 LoaderTimestampMonotonic=0 KernelTimestamp=Wed 2014-11-19 15:42:57 CST KernelTimestampMonotonic=0 InitRDTimestampMonotonic=0 UserspaceTimestamp=Wed 2014-11-19 15:43:00 CST UserspaceTimestampMonotonic=2862393 FinishTimestamp=Wed 2014-11-19 15:43:13 CST FinishTimestampMonotonic=15647941 SecurityStartTimestamp=Wed 2014-11-19 15:43:00 CST SecurityStartTimestampMonotonic=2864772 SecurityFinishTimestamp=Wed 2014-11-19 15:43:00 CST SecurityFinishTimestampMonotonic=2875854 ... --- src/core/main.c | 11 ++++++++++- src/shared/time-util.c | 14 ++++++++++++++ src/shared/time-util.h | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/core/main.c b/src/core/main.c index 64acdf7..86af1e5 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1318,8 +1318,17 @@ int main(int argc, char *argv[]) { r = clock_set_timezone(&min); if (r < 0) log_error("Failed to apply local time delta, ignoring: %s", strerror(-r)); - else + else { log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min); + + /* Fix timestamps generated before the very first call. */ + dual_timestamp_warp(&kernel_timestamp, min); + dual_timestamp_warp(&userspace_timestamp, min); + if(in_initrd()) + dual_timestamp_warp(&initrd_timestamp, min); + dual_timestamp_warp(&security_start_timestamp, min); + dual_timestamp_warp(&security_finish_timestamp, min); + } } else if (!in_initrd()) { /* * Do a dummy very first call to seal the kernel's time warp magic. diff --git a/src/shared/time-util.c b/src/shared/time-util.c index d3404af..f323835 100644 --- a/src/shared/time-util.c +++ b/src/shared/time-util.c @@ -88,6 +88,20 @@ dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u) { return ts; } +dual_timestamp* dual_timestamp_warp(dual_timestamp *ts, int min) { + usec_t d; + if (min >= 0) { + d = min * USEC_PER_MINUTE; + ts->realtime = + ts->realtime > d ? + ts->realtime - d : 0; + } else { + d = (-min) * USEC_PER_MINUTE; + ts->realtime = ts->realtime + d; + } + return ts; +} + usec_t timespec_load(const struct timespec *ts) { assert(ts); diff --git a/src/shared/time-util.h b/src/shared/time-util.h index b55a660..8c09963 100644 --- a/src/shared/time-util.h +++ b/src/shared/time-util.h @@ -74,6 +74,7 @@ usec_t now(clockid_t clock); dual_timestamp* dual_timestamp_get(dual_timestamp *ts); dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u); dual_timestamp* dual_timestamp_from_monotonic(dual_timestamp *ts, usec_t u); +dual_timestamp* dual_timestamp_warp(dual_timestamp *ts, int min); static inline bool dual_timestamp_is_set(dual_timestamp *ts) { return ((ts->realtime > 0 && ts->realtime != USEC_INFINITY) || -- 2.1.3 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel