return RET_NERRNO(settimeofday(NULL, &tz));
}
-void clock_apply_epoch(void) {
+void clock_apply_epoch(bool allow_backwards) {
usec_t epoch_usec = 0, timesyncd_usec = 0;
struct stat st;
int r;
if (now_usec < epoch_usec)
advance = true;
- else if (CLOCK_VALID_RANGE_USEC_MAX > 0 && now_usec > usec_add(epoch_usec, CLOCK_VALID_RANGE_USEC_MAX))
+ else if (CLOCK_VALID_RANGE_USEC_MAX > 0 &&
+ now_usec > usec_add(epoch_usec, CLOCK_VALID_RANGE_USEC_MAX) &&
+ allow_backwards)
advance = false;
else
return; /* Nothing to do. */
return -errno;
}
-static void initialize_clock(void) {
+static void initialize_clock_timewarp(void) {
int r;
/* This is called very early on, before we parse the kernel command line or otherwise figure out why
/* The very first call of settimeofday() also does a time warp in the kernel.
*
* In the rtc-in-local time mode, we set the kernel's timezone, and rely on external tools to
- * take care of maintaining the RTC and do all adjustments. This matches the behavior of
+ * take care of maintaining the RTC and do all adjustments. This matches the behavior of
* Windows, which leaves the RTC alone if the registry tells that the RTC runs in UTC.
*/
r = clock_set_timezone(&min);
* time concepts will be treated as UTC that way.
*/
(void) clock_reset_timewarp();
-
- clock_apply_epoch();
}
static void apply_clock_update(void) {
- /* This is called later than initialize_clock(), i.e. after we parsed configuration files/kernel
- * command line and such. */
+ /* This is called later than clock_apply_epoch(), i.e. after we have parsed
+ * configuration files/kernel command line and such. */
if (arg_clock_usec == 0)
return;
}
if (!skip_setup)
- initialize_clock();
+ initialize_clock_timewarp();
+
+ clock_apply_epoch(/* allow_backwards= */ !skip_setup);
/* Set the default for later on, but don't actually open the logs like this for
* now. Note that if we are transitioning from the initrd there might still be