* The actual value does not matter, We do not care about the correct
* NTP UINT_MAX fraction; we just pass the plain nanosecond value.
*/
- assert_se(clock_gettime(CLOCK_MONOTONIC, &m->trans_time_mon) >= 0);
+ assert_se(clock_gettime(clock_boottime_or_monotonic(), &m->trans_time_mon) >= 0);
assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);
r = sd_event_add_time(
m->event,
&m->event_timeout,
- CLOCK_MONOTONIC,
- now(CLOCK_MONOTONIC) + TIMEOUT_USEC, 0,
+ clock_boottime_or_monotonic(),
+ now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0,
manager_timeout, m);
if (r < 0) {
log_error("Failed to arm timeout timer: %s", strerror(-r));
}
if (m->event_timer) {
- r = sd_event_source_set_time(m->event_timer, now(CLOCK_MONOTONIC) + next);
+ r = sd_event_source_set_time(m->event_timer, now(clock_boottime_or_monotonic()) + next);
if (r < 0)
return r;
return sd_event_add_time(
m->event,
&m->event_timer,
- CLOCK_MONOTONIC,
- now(CLOCK_MONOTONIC) + next, 0,
+ clock_boottime_or_monotonic(),
+ now(clock_boottime_or_monotonic()) + next, 0,
manager_timer, m);
}
/*
* For small deltas, tell the kernel to gradually adjust the system
* clock to the NTP time, larger deltas are just directly set.
- *
- * Clear STA_UNSYNC, it will enable the kernel's 11-minute mode, which
- * syncs the system time periodically to the hardware clock.
*/
if (fabs(offset) < NTP_MAX_ADJUST) {
tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
tmx.esterror = 0;
log_debug(" adjust (slew): %+.3f sec\n", offset);
} else {
- tmx.modes = ADJ_SETOFFSET | ADJ_NANO;
+ tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET;
/* ADJ_NANO uses nanoseconds in the microseconds field */
tmx.time.tv_sec = (long)offset;
log_debug(" adjust (jump): %+.3f sec\n", offset);
}
+ /*
+ * An unset STA_UNSYNC will enable the kernel's 11-minute mode,
+ * which syncs the system time periodically to the RTC.
+ *
+ * In case the RTC runs in local time, never touch the RTC,
+ * we have no way to properly handle daylight saving changes and
+ * mobile devices moving between time zones.
+ */
+ if (m->rtc_local_time)
+ tmx.status |= STA_UNSYNC;
+
switch (leap_sec) {
case 1:
tmx.status |= STA_INS;
" constant : %li\n"
" offset : %+.3f sec\n"
" freq offset : %+li (%i ppm)\n",
- tmx.status, tmx.status & STA_UNSYNC ? "" : "sync",
+ tmx.status, tmx.status & STA_UNSYNC ? "unsync" : "sync",
tmx.time.tv_sec, (unsigned long long) (tmx.time.tv_usec / NSEC_PER_MSEC),
tmx.constant,
(double)tmx.offset / NSEC_PER_SEC,
* The round-trip delay, d, and system clock offset, t, are defined as:
* d = (T4 - T1) - (T3 - T2) t = ((T2 - T1) + (T3 - T4)) / 2"
*/
- assert_se(clock_gettime(CLOCK_MONOTONIC, &now_ts) >= 0);
+ assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0);
origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
receive = ntp_ts_to_d(&ntpmsg.recv_time);
trans = ntp_ts_to_d(&ntpmsg.trans_time);
if (!ratelimit_test(&m->ratelimit)) {
log_debug("Slowing down attempts to contact servers.");
- r = sd_event_add_time(m->event, &m->event_retry, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + RETRY_USEC, 0, manager_retry, m);
+ r = sd_event_add_time(m->event, &m->event_retry, clock_boottime_or_monotonic(), now(clock_boottime_or_monotonic()) + RETRY_USEC, 0, manager_retry, m);
if (r < 0) {
log_error("Failed to create retry timer: %s", strerror(-r));
return r;
}
static int manager_add_server_string(Manager *m, const char *string) {
- char *w, *state;
+ const char *word, *state;
size_t l;
int r;
assert(m);
assert(string);
- FOREACH_WORD_QUOTED(w, l, string, state) {
+ FOREACH_WORD_QUOTED(word, l, string, state) {
char t[l+1];
- memcpy(t, w, l);
+ memcpy(t, word, l);
t[l] = 0;
r = manager_add_server(m, t);
if (r < 0)
log_error("Failed to add server %s to configuration, ignoring: %s", t, strerror(-r));
}
+ if (!isempty(state))
+ log_warning("Trailing garbage at the end of server list, ignoring.");
return 0;
}
_cleanup_network_monitor_unref_ sd_network_monitor *monitor = NULL;
int r, fd, events;
- r = sd_network_monitor_new(NULL, &monitor);
+ r = sd_network_monitor_new(&monitor, NULL);
if (r < 0)
return r;
goto out;
}
+ if (clock_is_localtime() > 0) {
+ log_info("The system is configured to read the RTC time in the local time zone. "
+ "This mode can not be fully supported. All system time to RTC updates are disabled.");
+ m->rtc_local_time = true;
+ }
+
manager_add_server_string(m, NTP_SERVERS);
manager_parse_config_file(m);