mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
Merge pull request #22789 from poettering/timesync-struct-log
timesyncd: various refactorings and cleanup + structured log msg on first sync
This commit is contained in:
commit
59b8e67582
@ -526,3 +526,11 @@ be updated to operate in a hotplug fashion without depending on
|
||||
systemd-udev-settle.service:
|
||||
|
||||
@OFFENDING_UNITS@
|
||||
|
||||
-- 7c8a41f37b764941a0e1780b1be2f037
|
||||
Subject: Initial clock synchronization
|
||||
Defined-By: systemd
|
||||
Support: %SUPPORT_URL%
|
||||
|
||||
For the first time during the current boot an NTP synchronization has been
|
||||
acquired and the local system clock adjustment has been initiated.
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "dirent-util.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "event-util.h"
|
||||
#include "exec-util.h"
|
||||
#include "execute.h"
|
||||
#include "exit-status.h"
|
||||
@ -406,13 +407,8 @@ static int manager_setup_time_change(Manager *m) {
|
||||
return 0;
|
||||
|
||||
m->time_change_event_source = sd_event_source_disable_unref(m->time_change_event_source);
|
||||
m->time_change_fd = safe_close(m->time_change_fd);
|
||||
|
||||
m->time_change_fd = time_change_fd();
|
||||
if (m->time_change_fd < 0)
|
||||
return log_error_errno(m->time_change_fd, "Failed to create timer change timer fd: %m");
|
||||
|
||||
r = sd_event_add_io(m->event, &m->time_change_event_source, m->time_change_fd, EPOLLIN, manager_dispatch_time_change_fd, m);
|
||||
r = event_add_time_change(m->event, &m->time_change_event_source, manager_dispatch_time_change_fd, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create time change event source: %m");
|
||||
|
||||
@ -421,8 +417,6 @@ static int manager_setup_time_change(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set priority of time change event sources: %m");
|
||||
|
||||
(void) sd_event_source_set_description(m->time_change_event_source, "manager-time-change");
|
||||
|
||||
log_debug("Set up TFD_TIMER_CANCEL_ON_SET timerfd.");
|
||||
|
||||
return 0;
|
||||
@ -820,7 +814,6 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
|
||||
.notify_fd = -1,
|
||||
.cgroups_agent_fd = -1,
|
||||
.signal_fd = -1,
|
||||
.time_change_fd = -1,
|
||||
.user_lookup_fds = { -1, -1 },
|
||||
.private_listen_fd = -1,
|
||||
.dev_autofs_fd = -1,
|
||||
@ -1509,7 +1502,6 @@ Manager* manager_free(Manager *m) {
|
||||
safe_close(m->signal_fd);
|
||||
safe_close(m->notify_fd);
|
||||
safe_close(m->cgroups_agent_fd);
|
||||
safe_close(m->time_change_fd);
|
||||
safe_close_pair(m->user_lookup_fds);
|
||||
|
||||
manager_close_ask_password(m);
|
||||
@ -2913,7 +2905,6 @@ static int manager_dispatch_time_change_fd(sd_event_source *source, int fd, uint
|
||||
Unit *u;
|
||||
|
||||
assert(m);
|
||||
assert(m->time_change_fd == fd);
|
||||
|
||||
log_struct(LOG_DEBUG,
|
||||
"MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
|
||||
|
@ -226,7 +226,6 @@ struct Manager {
|
||||
|
||||
sd_event_source *sigchld_event_source;
|
||||
|
||||
int time_change_fd;
|
||||
sd_event_source *time_change_event_source;
|
||||
|
||||
sd_event_source *timezone_change_event_source;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "event-source.h"
|
||||
#include "event-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
#include "string-util.h"
|
||||
|
||||
@ -121,3 +122,41 @@ int event_source_is_enabled(sd_event_source *s) {
|
||||
|
||||
return sd_event_source_get_enabled(s, NULL);
|
||||
}
|
||||
|
||||
int event_add_time_change(sd_event *e, sd_event_source **ret, sd_event_io_handler_t callback, void *userdata) {
|
||||
_cleanup_(sd_event_source_disable_unrefp) sd_event_source *s = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
assert(e);
|
||||
|
||||
/* Allocates an IO event source that gets woken up whenever the clock changes. Needs to be recreated on each event */
|
||||
|
||||
fd = time_change_fd();
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = sd_event_add_io(e, &s, fd, EPOLLIN, callback, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_source_set_io_fd_own(s, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_FD(fd);
|
||||
|
||||
r = sd_event_source_set_description(s, "time-change");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(s);
|
||||
else {
|
||||
r = sd_event_source_set_floating(s, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,3 +29,5 @@ int event_reset_time_relative(
|
||||
bool force_reset);
|
||||
int event_source_disable(sd_event_source *s);
|
||||
int event_source_is_enabled(sd_event_source *s);
|
||||
|
||||
int event_add_time_change(sd_event *e, sd_event_source **ret, sd_event_io_handler_t callback, void *userdata);
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "bus-polkit.h"
|
||||
#include "dirent-util.h"
|
||||
#include "dns-domain.h"
|
||||
#include "event-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "hostname-util.h"
|
||||
@ -338,28 +339,16 @@ static int on_clock_change(sd_event_source *source, int fd, uint32_t revents, vo
|
||||
}
|
||||
|
||||
static int manager_clock_change_listen(Manager *m) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
m->clock_change_event_source = sd_event_source_disable_unref(m->clock_change_event_source);
|
||||
|
||||
fd = time_change_fd();
|
||||
if (fd < 0)
|
||||
return log_error_errno(fd, "Failed to allocate clock change timer fd: %m");
|
||||
|
||||
r = sd_event_add_io(m->event, &m->clock_change_event_source, fd, EPOLLIN, on_clock_change, m);
|
||||
r = event_add_time_change(m->event, &m->clock_change_event_source, on_clock_change, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create clock change event source: %m");
|
||||
|
||||
r = sd_event_source_set_io_fd_own(m->clock_change_event_source, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to pass ownership of clock fd to event source: %m");
|
||||
TAKE_FD(fd);
|
||||
|
||||
(void) sd_event_source_set_description(m->clock_change_event_source, "clock-change");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -200,6 +200,9 @@ _SD_BEGIN_DECLARATIONS;
|
||||
#define SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED_STR \
|
||||
SD_ID128_MAKE_STR(1c,04,54,c1,bd,22,41,e0,ac,6f,ef,b4,bc,63,14,33)
|
||||
|
||||
#define SD_MESSAGE_TIME_SYNC SD_ID128_MAKE(7c,8a,41,f3,7b,76,49,41,a0,e1,78,0b,1b,e2,f0,37)
|
||||
#define SD_MESSAGE_TIME_SYNC_STR SD_ID128_MAKE_STR(7c,8a,41,f3,7b,76,49,41,a0,e1,78,0b,1b,e2,f0,37)
|
||||
|
||||
_SD_END_DECLARATIONS;
|
||||
|
||||
#endif
|
||||
|
@ -11,9 +11,11 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "sd-daemon.h"
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "dns-domain.h"
|
||||
#include "event-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
@ -28,6 +30,7 @@
|
||||
#include "time-util.h"
|
||||
#include "timesyncd-conf.h"
|
||||
#include "timesyncd-manager.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef ADJ_SETOFFSET
|
||||
@ -59,7 +62,7 @@ static int manager_arm_timer(Manager *m, usec_t next);
|
||||
static int manager_clock_watch_setup(Manager *m);
|
||||
static int manager_listen_setup(Manager *m);
|
||||
static void manager_listen_stop(Manager *m);
|
||||
static int manager_save_time_and_rearm(Manager *m);
|
||||
static int manager_save_time_and_rearm(Manager *m, usec_t t);
|
||||
|
||||
static double ntp_ts_short_to_d(const struct ntp_ts_short *ts) {
|
||||
return be16toh(ts->sec) + (be16toh(ts->frac) / 65536.0);
|
||||
@ -229,14 +232,9 @@ static int manager_clock_watch_setup(Manager *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
|
||||
safe_close(m->clock_watch_fd);
|
||||
m->event_clock_watch = sd_event_source_disable_unref(m->event_clock_watch);
|
||||
|
||||
m->clock_watch_fd = time_change_fd();
|
||||
if (m->clock_watch_fd < 0)
|
||||
return log_error_errno(m->clock_watch_fd, "Failed to create timerfd: %m");
|
||||
|
||||
r = sd_event_add_io(m->event, &m->event_clock_watch, m->clock_watch_fd, EPOLLIN, manager_clock_watch, m);
|
||||
r = event_add_time_change(m->event, &m->event_clock_watch, manager_clock_watch, m);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create clock watch event source: %m");
|
||||
|
||||
@ -244,31 +242,29 @@ static int manager_clock_watch_setup(Manager *m) {
|
||||
}
|
||||
|
||||
static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
|
||||
struct timex tmx = {};
|
||||
int r;
|
||||
struct timex tmx;
|
||||
|
||||
assert(m);
|
||||
|
||||
/*
|
||||
* For small deltas, tell the kernel to gradually adjust the system
|
||||
* clock to the NTP time, larger deltas are just directly set.
|
||||
*/
|
||||
/* For small deltas, tell the kernel to gradually adjust the system clock to the NTP time, larger
|
||||
* deltas are just directly set. */
|
||||
if (fabs(offset) < NTP_MAX_ADJUST) {
|
||||
tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR;
|
||||
tmx.status = STA_PLL;
|
||||
tmx.offset = offset * NSEC_PER_SEC;
|
||||
tmx.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4;
|
||||
tmx.maxerror = 0;
|
||||
tmx.esterror = 0;
|
||||
tmx = (struct timex) {
|
||||
.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR,
|
||||
.status = STA_PLL,
|
||||
.offset = offset * NSEC_PER_SEC,
|
||||
.constant = log2i(m->poll_interval_usec / USEC_PER_SEC) - 4,
|
||||
};
|
||||
|
||||
log_debug(" adjust (slew): %+.3f sec", offset);
|
||||
} else {
|
||||
tmx.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR;
|
||||
tmx = (struct timex) {
|
||||
.modes = ADJ_STATUS | ADJ_NANO | ADJ_SETOFFSET | ADJ_MAXERROR | ADJ_ESTERROR,
|
||||
|
||||
/* ADJ_NANO uses nanoseconds in the microseconds field */
|
||||
tmx.time.tv_sec = (long)offset;
|
||||
tmx.time.tv_usec = (offset - tmx.time.tv_sec) * NSEC_PER_SEC;
|
||||
tmx.maxerror = 0;
|
||||
tmx.esterror = 0;
|
||||
/* ADJ_NANO uses nanoseconds in the microseconds field */
|
||||
.time.tv_sec = (long)offset,
|
||||
.time.tv_usec = (offset - (double) (long) offset) * NSEC_PER_SEC,
|
||||
};
|
||||
|
||||
/* the kernel expects -0.3s as {-1, 7000.000.000} */
|
||||
if (tmx.time.tv_usec < 0) {
|
||||
@ -280,14 +276,11 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
|
||||
log_debug(" adjust (jump): %+.3f sec", offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* An unset STA_UNSYNC will enable the kernel's 11-minute mode,
|
||||
* which syncs the system time periodically to the RTC.
|
||||
/* 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.
|
||||
*/
|
||||
* 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;
|
||||
|
||||
@ -300,17 +293,9 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
|
||||
break;
|
||||
}
|
||||
|
||||
r = clock_adjtime(CLOCK_REALTIME, &tmx);
|
||||
if (r < 0)
|
||||
if (clock_adjtime(CLOCK_REALTIME, &tmx) < 0)
|
||||
return -errno;
|
||||
|
||||
r = manager_save_time_and_rearm(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* If touch fails, there isn't much we can do. Maybe it'll work next time. */
|
||||
(void) touch("/run/systemd/timesync/synchronized");
|
||||
|
||||
m->drift_freq = tmx.freq;
|
||||
|
||||
log_debug(" status : %04i %s\n"
|
||||
@ -427,15 +412,12 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
||||
.msg_name = &server_addr,
|
||||
.msg_namelen = sizeof(server_addr),
|
||||
};
|
||||
struct cmsghdr *cmsg;
|
||||
struct timespec *recv_time = NULL;
|
||||
triple_timestamp dts;
|
||||
ssize_t len;
|
||||
double origin, receive, trans, dest;
|
||||
double delay, offset;
|
||||
double root_distance;
|
||||
double origin, receive, trans, dest, delay, offset, root_distance;
|
||||
bool spike;
|
||||
int leap_sec;
|
||||
int r;
|
||||
int leap_sec, r;
|
||||
|
||||
assert(source);
|
||||
assert(m);
|
||||
@ -466,21 +448,9 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMSG_FOREACH(cmsg, &msghdr) {
|
||||
if (cmsg->cmsg_level != SOL_SOCKET)
|
||||
continue;
|
||||
|
||||
switch (cmsg->cmsg_type) {
|
||||
case SCM_TIMESTAMPNS:
|
||||
assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct timespec)));
|
||||
|
||||
recv_time = (struct timespec *) CMSG_DATA(cmsg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
recv_time = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_TIMESTAMPNS, struct timespec);
|
||||
if (!recv_time)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Invalid packet timestamp.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Packet timestamp missing.");
|
||||
|
||||
if (!m->pending) {
|
||||
log_debug("Unexpected reply. Ignoring.");
|
||||
@ -597,10 +567,23 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
||||
m->samples_jitter, spike ? " spike" : "",
|
||||
m->poll_interval_usec / USEC_PER_SEC);
|
||||
|
||||
/* Get current monotonic/realtime clocks immediately before adjusting the latter */
|
||||
triple_timestamp_get(&dts);
|
||||
|
||||
if (!spike) {
|
||||
/* Fix up our idea of the time. */
|
||||
dts.realtime = (usec_t) (dts.realtime + offset * USEC_PER_SEC);
|
||||
|
||||
r = manager_adjust_clock(m, offset, leap_sec);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed to call clock_adjtime(): %m");
|
||||
|
||||
(void) manager_save_time_and_rearm(m, dts.realtime);
|
||||
|
||||
/* If touch fails, there isn't much we can do. Maybe it'll work next time. */
|
||||
r = touch("/run/systemd/timesync/synchronized");
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to touch /run/systemd/timesync/synchronized, ignoring: %m");
|
||||
}
|
||||
|
||||
/* Save NTP response */
|
||||
@ -621,15 +604,26 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
||||
"NTPMessage",
|
||||
NULL);
|
||||
|
||||
if (!m->good) {
|
||||
if (!m->talking) {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
|
||||
m->good = true;
|
||||
m->talking = true;
|
||||
|
||||
server_address_pretty(m->current_server_address, &pretty);
|
||||
/* "Initial", as further successful syncs will not be logged. */
|
||||
log_info("Initial synchronization to time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
sd_notifyf(false, "STATUS=Initial synchronization to time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
(void) server_address_pretty(m->current_server_address, &pretty);
|
||||
|
||||
log_info("Contacted time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
(void) sd_notifyf(false, "STATUS=Contacted time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
}
|
||||
|
||||
if (!spike && !m->synchronized) {
|
||||
m->synchronized = true;
|
||||
|
||||
log_struct(LOG_INFO,
|
||||
LOG_MESSAGE("Initial clock synchronization to %s.", FORMAT_TIMESTAMP_STYLE(dts.realtime, TIMESTAMP_US)),
|
||||
"MESSAGE_ID=" SD_MESSAGE_TIME_SYNC_STR,
|
||||
"MONOTONIC_USEC=" USEC_FMT, dts.monotonic,
|
||||
"REALTIME_USEC=" USEC_FMT, dts.realtime,
|
||||
"BOOTIME_USEC=" USEC_FMT, dts.boottime);
|
||||
}
|
||||
|
||||
r = manager_arm_timer(m, m->poll_interval_usec);
|
||||
@ -686,14 +680,14 @@ static int manager_begin(Manager *m) {
|
||||
assert_return(m->current_server_name, -EHOSTUNREACH);
|
||||
assert_return(m->current_server_address, -EHOSTUNREACH);
|
||||
|
||||
m->good = false;
|
||||
m->talking = false;
|
||||
m->missed_replies = NTP_MAX_MISSED_REPLIES;
|
||||
if (m->poll_interval_usec == 0)
|
||||
m->poll_interval_usec = m->poll_interval_min_usec;
|
||||
|
||||
server_address_pretty(m->current_server_address, &pretty);
|
||||
log_debug("Connecting to time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
sd_notifyf(false, "STATUS=Connecting to time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
(void) sd_notifyf(false, "STATUS=Connecting to time server %s (%s).", strna(pretty), m->current_server_name->string);
|
||||
|
||||
r = manager_clock_watch_setup(m);
|
||||
if (r < 0)
|
||||
@ -818,7 +812,7 @@ int manager_connect(Manager *m) {
|
||||
if (m->current_server_address && m->current_server_address->addresses_next)
|
||||
manager_set_server_address(m, m->current_server_address->addresses_next);
|
||||
else {
|
||||
struct addrinfo hints = {
|
||||
static const struct addrinfo hints = {
|
||||
.ai_flags = AI_NUMERICSERV|AI_ADDRCONFIG,
|
||||
.ai_socktype = SOCK_DGRAM,
|
||||
};
|
||||
@ -910,12 +904,11 @@ void manager_disconnect(Manager *m) {
|
||||
|
||||
manager_listen_stop(m);
|
||||
|
||||
m->event_clock_watch = sd_event_source_unref(m->event_clock_watch);
|
||||
m->clock_watch_fd = safe_close(m->clock_watch_fd);
|
||||
m->event_clock_watch = sd_event_source_disable_unref(m->event_clock_watch);
|
||||
|
||||
m->event_timeout = sd_event_source_unref(m->event_timeout);
|
||||
|
||||
sd_notify(false, "STATUS=Idle.");
|
||||
(void) sd_notify(false, "STATUS=Idle.");
|
||||
}
|
||||
|
||||
void manager_flush_server_names(Manager *m, ServerType t) {
|
||||
@ -1098,21 +1091,26 @@ int manager_new(Manager **ret) {
|
||||
|
||||
assert(ret);
|
||||
|
||||
m = new0(Manager, 1);
|
||||
m = new(Manager, 1);
|
||||
if (!m)
|
||||
return -ENOMEM;
|
||||
|
||||
m->root_distance_max_usec = NTP_ROOT_DISTANCE_MAX_USEC;
|
||||
m->poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC;
|
||||
m->poll_interval_max_usec = NTP_POLL_INTERVAL_MAX_USEC;
|
||||
*m = (Manager) {
|
||||
.root_distance_max_usec = NTP_ROOT_DISTANCE_MAX_USEC,
|
||||
.poll_interval_min_usec = NTP_POLL_INTERVAL_MIN_USEC,
|
||||
.poll_interval_max_usec = NTP_POLL_INTERVAL_MAX_USEC,
|
||||
|
||||
m->connection_retry_usec = DEFAULT_CONNECTION_RETRY_USEC;
|
||||
.connection_retry_usec = DEFAULT_CONNECTION_RETRY_USEC,
|
||||
|
||||
m->server_socket = m->clock_watch_fd = -1;
|
||||
.server_socket = -1,
|
||||
|
||||
m->ratelimit = (RateLimit) { RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST };
|
||||
.ratelimit = (RateLimit) {
|
||||
RATELIMIT_INTERVAL_USEC,
|
||||
RATELIMIT_BURST
|
||||
},
|
||||
|
||||
m->save_time_interval_usec = DEFAULT_SAVE_TIME_INTERVAL_USEC;
|
||||
.save_time_interval_usec = DEFAULT_SAVE_TIME_INTERVAL_USEC,
|
||||
};
|
||||
|
||||
r = sd_event_default(&m->event);
|
||||
if (r < 0)
|
||||
@ -1123,6 +1121,12 @@ int manager_new(Manager **ret) {
|
||||
|
||||
(void) sd_event_set_watchdog(m->event, true);
|
||||
|
||||
/* Load previous synchronization state */
|
||||
r = access("/run/systemd/timesync/synchronized", F_OK);
|
||||
if (r < 0 && errno != ENOENT)
|
||||
log_debug_errno(errno, "Failed to determine whether /run/systemd/timesync/synchronized exists, ignoring: %m");
|
||||
m->synchronized = r >= 0;
|
||||
|
||||
r = sd_resolve_default(&m->resolve);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1147,7 +1151,7 @@ static int manager_save_time_handler(sd_event_source *s, uint64_t usec, void *us
|
||||
|
||||
assert(m);
|
||||
|
||||
(void) manager_save_time_and_rearm(m);
|
||||
(void) manager_save_time_and_rearm(m, USEC_INFINITY);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1175,12 +1179,16 @@ int manager_setup_save_time_event(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int manager_save_time_and_rearm(Manager *m) {
|
||||
static int manager_save_time_and_rearm(Manager *m, usec_t t) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
r = touch(CLOCK_FILE);
|
||||
/* Updates the timestamp file to the specified time. If 't' is USEC_INFINITY uses the current system
|
||||
* clock, but otherwise uses the specified timestamp. Note that whenever we acquire an NTP sync the
|
||||
* specified timestamp value might be more accurate than the system clock, since the latter is
|
||||
* subject to slow adjustments. */
|
||||
r = touch_file(CLOCK_FILE, false, t, UID_INVALID, GID_INVALID, MODE_INVALID);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to update " CLOCK_FILE ", ignoring: %m");
|
||||
|
||||
|
@ -61,7 +61,7 @@ struct Manager {
|
||||
int missed_replies;
|
||||
uint64_t packet_count;
|
||||
sd_event_source *event_timeout;
|
||||
bool good;
|
||||
bool talking;
|
||||
|
||||
/* last sent packet */
|
||||
struct timespec trans_time_mon;
|
||||
@ -92,7 +92,6 @@ struct Manager {
|
||||
|
||||
/* watch for time changes */
|
||||
sd_event_source *event_clock_watch;
|
||||
int clock_watch_fd;
|
||||
|
||||
/* Retry connections */
|
||||
sd_event_source *event_retry;
|
||||
@ -105,6 +104,9 @@ struct Manager {
|
||||
struct timespec origin_time, dest_time;
|
||||
bool spike;
|
||||
|
||||
/* Indicates whether we ever managed to set the local clock from NTP */
|
||||
bool synchronized;
|
||||
|
||||
/* save time event */
|
||||
sd_event_source *event_save_time;
|
||||
usec_t save_time_interval_usec;
|
||||
|
@ -16,16 +16,19 @@ int server_address_new(
|
||||
assert(socklen >= offsetof(struct sockaddr, sa_data));
|
||||
assert(socklen <= sizeof(union sockaddr_union));
|
||||
|
||||
a = new0(ServerAddress, 1);
|
||||
a = new(ServerAddress, 1);
|
||||
if (!a)
|
||||
return -ENOMEM;
|
||||
|
||||
*a = (ServerAddress) {
|
||||
.name = n,
|
||||
.socklen = socklen,
|
||||
};
|
||||
|
||||
memcpy(&a->sockaddr, sockaddr, socklen);
|
||||
a->socklen = socklen;
|
||||
|
||||
LIST_FIND_TAIL(addresses, n->addresses, tail);
|
||||
LIST_INSERT_AFTER(addresses, n->addresses, tail, a);
|
||||
a->name = n;
|
||||
|
||||
if (ret)
|
||||
*ret = a;
|
||||
@ -58,12 +61,16 @@ int server_name_new(
|
||||
assert(m);
|
||||
assert(string);
|
||||
|
||||
n = new0(ServerName, 1);
|
||||
n = new(ServerName, 1);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
n->type = type;
|
||||
n->string = strdup(string);
|
||||
*n = (ServerName) {
|
||||
.manager = m,
|
||||
.type = type,
|
||||
.string = strdup(string),
|
||||
};
|
||||
|
||||
if (!n->string) {
|
||||
free(n);
|
||||
return -ENOMEM;
|
||||
@ -81,8 +88,6 @@ int server_name_new(
|
||||
} else
|
||||
assert_not_reached();
|
||||
|
||||
n->manager = m;
|
||||
|
||||
if (type != SERVER_FALLBACK &&
|
||||
m->current_server_name &&
|
||||
m->current_server_name->type == SERVER_FALLBACK)
|
||||
|
@ -22,9 +22,8 @@
|
||||
#include "user-util.h"
|
||||
|
||||
static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
||||
usec_t min = TIME_EPOCH * USEC_PER_SEC, ct;
|
||||
_cleanup_close_ int fd = -1;
|
||||
usec_t min = TIME_EPOCH * USEC_PER_SEC;
|
||||
usec_t ct;
|
||||
int r;
|
||||
|
||||
/* Let's try to make sure that the clock is always
|
||||
@ -40,8 +39,7 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
||||
usec_t stamp;
|
||||
|
||||
/* check if the recorded time is later than the compiled-in one */
|
||||
r = fstat(fd, &st);
|
||||
if (r >= 0) {
|
||||
if (fstat(fd, &st) >= 0) {
|
||||
stamp = timespec_load(&st.st_mtim);
|
||||
if (stamp > min)
|
||||
min = stamp;
|
||||
@ -64,7 +62,7 @@ static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
||||
}
|
||||
|
||||
/* create stamp file with the compiled-in date */
|
||||
r = touch_file(CLOCK_FILE, false, min, uid, gid, 0644);
|
||||
r = touch_file(CLOCK_FILE, /* parents= */ false, min, uid, gid, 0644);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to create %s, ignoring: %m", CLOCK_FILE);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user