mirror of
https://github.com/systemd/systemd
synced 2026-03-24 15:55:00 +01:00
Compare commits
2 Commits
8a513eee30
...
46db176f8c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
46db176f8c | ||
|
|
33e82f3ef3 |
@ -75,10 +75,11 @@
|
|||||||
<term><filename>/var/lib/systemd/timesync/clock</filename></term>
|
<term><filename>/var/lib/systemd/timesync/clock</filename></term>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The modification time ("mtime") of this file indicates the timestamp of the last successful
|
<para>The modification time ("mtime") of this file is updated on each successful NTP synchronization
|
||||||
synchronization (or at least the systemd build date, in case synchronization was not possible). It
|
or after each <varname>SaveIntervalSec=</varname> time interval, as specified in
|
||||||
is used to ensure that the system clock remains roughly monotonic across reboots, in case no local
|
<citerefentry><refentrytitle>timesyncd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
RTC is available.</para>
|
At the minimum, it will be set to the systemd build date. It is used to ensure that the system clock
|
||||||
|
remains roughly monotonic across reboots, in case no local RTC is available.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|||||||
@ -103,6 +103,18 @@
|
|||||||
Defaults to 30 seconds and must not be smaller than 1 second.</para></listitem>
|
Defaults to 30 seconds and must not be smaller than 1 second.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>SaveIntervalSec=</varname></term>
|
||||||
|
<listitem><para>The interval at which the current time is periodically saved to disk, in the absence
|
||||||
|
of any recent synchronisation from an NTP server. This is especially useful for offline systems
|
||||||
|
with no local RTC, as it will guarantee that the system clock remains roughly monotonic across
|
||||||
|
reboots.</para>
|
||||||
|
|
||||||
|
<para>Takes a time interval value. The default unit is seconds, but other units may be specified, see
|
||||||
|
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
Defaults to 60 seconds.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@ -25,3 +25,4 @@ Time.RootDistanceMaxSec, config_parse_sec, 0, offs
|
|||||||
Time.PollIntervalMinSec, config_parse_sec, 0, offsetof(Manager, poll_interval_min_usec)
|
Time.PollIntervalMinSec, config_parse_sec, 0, offsetof(Manager, poll_interval_min_usec)
|
||||||
Time.PollIntervalMaxSec, config_parse_sec, 0, offsetof(Manager, poll_interval_max_usec)
|
Time.PollIntervalMaxSec, config_parse_sec, 0, offsetof(Manager, poll_interval_max_usec)
|
||||||
Time.ConnectionRetrySec, config_parse_sec, 0, offsetof(Manager, connection_retry_usec)
|
Time.ConnectionRetrySec, config_parse_sec, 0, offsetof(Manager, connection_retry_usec)
|
||||||
|
Time.SaveIntervalSec, config_parse_sec, 0, offsetof(Manager, save_time_interval_usec)
|
||||||
|
|||||||
@ -59,6 +59,7 @@ static int manager_arm_timer(Manager *m, usec_t next);
|
|||||||
static int manager_clock_watch_setup(Manager *m);
|
static int manager_clock_watch_setup(Manager *m);
|
||||||
static int manager_listen_setup(Manager *m);
|
static int manager_listen_setup(Manager *m);
|
||||||
static void manager_listen_stop(Manager *m);
|
static void manager_listen_stop(Manager *m);
|
||||||
|
static int manager_save_time_and_rearm(Manager *m);
|
||||||
|
|
||||||
static double ntp_ts_short_to_d(const struct ntp_ts_short *ts) {
|
static double ntp_ts_short_to_d(const struct ntp_ts_short *ts) {
|
||||||
return be16toh(ts->sec) + (be16toh(ts->frac) / 65536.0);
|
return be16toh(ts->sec) + (be16toh(ts->frac) / 65536.0);
|
||||||
@ -303,8 +304,11 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return -errno;
|
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. */
|
/* If touch fails, there isn't much we can do. Maybe it'll work next time. */
|
||||||
(void) touch("/var/lib/systemd/timesync/clock");
|
|
||||||
(void) touch("/run/systemd/timesync/synchronized");
|
(void) touch("/run/systemd/timesync/synchronized");
|
||||||
|
|
||||||
m->drift_freq = tmx.freq;
|
m->drift_freq = tmx.freq;
|
||||||
@ -591,7 +595,6 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
|
|||||||
m->poll_interval_usec / USEC_PER_SEC);
|
m->poll_interval_usec / USEC_PER_SEC);
|
||||||
|
|
||||||
if (!spike) {
|
if (!spike) {
|
||||||
m->sync = true;
|
|
||||||
r = manager_adjust_clock(m, offset, leap_sec);
|
r = manager_adjust_clock(m, offset, leap_sec);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_error_errno(r, "Failed to call clock_adjtime(): %m");
|
log_error_errno(r, "Failed to call clock_adjtime(): %m");
|
||||||
@ -942,6 +945,8 @@ Manager* manager_free(Manager *m) {
|
|||||||
sd_event_source_unref(m->network_event_source);
|
sd_event_source_unref(m->network_event_source);
|
||||||
sd_network_monitor_unref(m->network_monitor);
|
sd_network_monitor_unref(m->network_monitor);
|
||||||
|
|
||||||
|
sd_event_source_unref(m->event_save_time);
|
||||||
|
|
||||||
sd_resolve_unref(m->resolve);
|
sd_resolve_unref(m->resolve);
|
||||||
sd_event_unref(m->event);
|
sd_event_unref(m->event);
|
||||||
|
|
||||||
@ -1104,6 +1109,8 @@ int manager_new(Manager **ret) {
|
|||||||
|
|
||||||
m->ratelimit = (RateLimit) { RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST };
|
m->ratelimit = (RateLimit) { RATELIMIT_INTERVAL_USEC, RATELIMIT_BURST };
|
||||||
|
|
||||||
|
m->save_time_interval_usec = DEFAULT_SAVE_TIME_INTERVAL_USEC;
|
||||||
|
|
||||||
r = sd_event_default(&m->event);
|
r = sd_event_default(&m->event);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -1131,3 +1138,60 @@ int manager_new(Manager **ret) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int manager_save_time_handler(sd_event_source *s, uint64_t usec, void *userdata) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
(void) manager_save_time_and_rearm(m);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int manager_setup_save_time_event(Manager *m) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
assert(!m->event_save_time);
|
||||||
|
|
||||||
|
if (m->save_time_interval_usec == USEC_INFINITY)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* NB: we'll accumulate scheduling latencies here, but this doesn't matter */
|
||||||
|
r = sd_event_add_time_relative(
|
||||||
|
m->event, &m->event_save_time,
|
||||||
|
clock_boottime_or_monotonic(),
|
||||||
|
m->save_time_interval_usec,
|
||||||
|
10 * USEC_PER_SEC,
|
||||||
|
manager_save_time_handler, m);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add save time event: %m");
|
||||||
|
|
||||||
|
(void) sd_event_source_set_description(m->event_save_time, "save-time");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int manager_save_time_and_rearm(Manager *m) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
r = touch(CLOCK_FILE);
|
||||||
|
if (r < 0)
|
||||||
|
log_debug_errno(r, "Failed to update " CLOCK_FILE ", ignoring: %m");
|
||||||
|
|
||||||
|
m->save_on_exit = true;
|
||||||
|
|
||||||
|
if (m->save_time_interval_usec != USEC_INFINITY) {
|
||||||
|
r = sd_event_source_set_time_relative(m->event_save_time, m->save_time_interval_usec);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to rearm save time event: %m");
|
||||||
|
|
||||||
|
r = sd_event_source_set_enabled(m->event_save_time, SD_EVENT_ONESHOT);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to enable save time event: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@ -27,7 +27,12 @@ typedef struct Manager Manager;
|
|||||||
#define NTP_RETRY_INTERVAL_MIN_USEC (15 * USEC_PER_SEC)
|
#define NTP_RETRY_INTERVAL_MIN_USEC (15 * USEC_PER_SEC)
|
||||||
#define NTP_RETRY_INTERVAL_MAX_USEC (6 * 60 * USEC_PER_SEC) /* 6 minutes */
|
#define NTP_RETRY_INTERVAL_MAX_USEC (6 * 60 * USEC_PER_SEC) /* 6 minutes */
|
||||||
|
|
||||||
#define DEFAULT_CONNECTION_RETRY_USEC (30*USEC_PER_SEC)
|
#define DEFAULT_CONNECTION_RETRY_USEC (30 * USEC_PER_SEC)
|
||||||
|
|
||||||
|
#define DEFAULT_SAVE_TIME_INTERVAL_USEC (60 * USEC_PER_SEC)
|
||||||
|
|
||||||
|
#define STATE_DIR "/var/lib/systemd/timesync"
|
||||||
|
#define CLOCK_FILE STATE_DIR "/clock"
|
||||||
|
|
||||||
struct Manager {
|
struct Manager {
|
||||||
sd_bus *bus;
|
sd_bus *bus;
|
||||||
@ -83,7 +88,6 @@ struct Manager {
|
|||||||
|
|
||||||
/* last change */
|
/* last change */
|
||||||
bool jumped;
|
bool jumped;
|
||||||
bool sync;
|
|
||||||
int64_t drift_freq;
|
int64_t drift_freq;
|
||||||
|
|
||||||
/* watch for time changes */
|
/* watch for time changes */
|
||||||
@ -100,6 +104,11 @@ struct Manager {
|
|||||||
struct ntp_msg ntpmsg;
|
struct ntp_msg ntpmsg;
|
||||||
struct timespec origin_time, dest_time;
|
struct timespec origin_time, dest_time;
|
||||||
bool spike;
|
bool spike;
|
||||||
|
|
||||||
|
/* save time event */
|
||||||
|
sd_event_source *event_save_time;
|
||||||
|
usec_t save_time_interval_usec;
|
||||||
|
bool save_on_exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
int manager_new(Manager **ret);
|
int manager_new(Manager **ret);
|
||||||
@ -113,3 +122,5 @@ void manager_flush_server_names(Manager *m, ServerType t);
|
|||||||
|
|
||||||
int manager_connect(Manager *m);
|
int manager_connect(Manager *m);
|
||||||
void manager_disconnect(Manager *m);
|
void manager_disconnect(Manager *m);
|
||||||
|
|
||||||
|
int manager_setup_save_time_event(Manager *m);
|
||||||
|
|||||||
@ -21,9 +21,6 @@
|
|||||||
#include "timesyncd-manager.h"
|
#include "timesyncd-manager.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
|
|
||||||
#define STATE_DIR "/var/lib/systemd/timesync"
|
|
||||||
#define CLOCK_FILE STATE_DIR "/clock"
|
|
||||||
|
|
||||||
static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
static int load_clock_timestamp(uid_t uid, gid_t gid) {
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
usec_t min = TIME_EPOCH * USEC_PER_SEC;
|
usec_t min = TIME_EPOCH * USEC_PER_SEC;
|
||||||
@ -155,6 +152,10 @@ static int run(int argc, char *argv[]) {
|
|||||||
"STATUS=Daemon is running",
|
"STATUS=Daemon is running",
|
||||||
NOTIFY_STOPPING);
|
NOTIFY_STOPPING);
|
||||||
|
|
||||||
|
r = manager_setup_save_time_event(m);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
if (network_is_online()) {
|
if (network_is_online()) {
|
||||||
r = manager_connect(m);
|
r = manager_connect(m);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -166,10 +167,10 @@ static int run(int argc, char *argv[]) {
|
|||||||
return log_error_errno(r, "Failed to run event loop: %m");
|
return log_error_errno(r, "Failed to run event loop: %m");
|
||||||
|
|
||||||
/* if we got an authoritative time, store it in the file system */
|
/* if we got an authoritative time, store it in the file system */
|
||||||
if (m->sync) {
|
if (m->save_on_exit) {
|
||||||
r = touch(CLOCK_FILE);
|
r = touch(CLOCK_FILE);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_debug_errno(r, "Failed to touch %s, ignoring: %m", CLOCK_FILE);
|
log_debug_errno(r, "Failed to touch " CLOCK_FILE ", ignoring: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -18,3 +18,4 @@
|
|||||||
#RootDistanceMaxSec=5
|
#RootDistanceMaxSec=5
|
||||||
#PollIntervalMinSec=32
|
#PollIntervalMinSec=32
|
||||||
#PollIntervalMaxSec=2048
|
#PollIntervalMaxSec=2048
|
||||||
|
#SaveIntervalSec=60
|
||||||
|
|||||||
@ -347,12 +347,14 @@ run_qemu() {
|
|||||||
[ "$ARCH" ] || ARCH=$(uname -m)
|
[ "$ARCH" ] || ARCH=$(uname -m)
|
||||||
case $ARCH in
|
case $ARCH in
|
||||||
ppc64*)
|
ppc64*)
|
||||||
KERNEL_BIN="/boot/vmlinux-$KERNEL_VER"
|
# Ubuntu ppc64* calls the kernel binary as vmlinux-*, RHEL/CentOS
|
||||||
CONSOLE=hvc0
|
# uses the "standard" vmlinuz- prefix
|
||||||
;;
|
[[ -e "/boot/vmlinux-$KERNEL_VER" ]] && KERNEL_BIN="/boot/vmlinux-$KERNEL_VER" || KERNEL_BIN="/boot/vmlinuz-$KERNEL_VER"
|
||||||
|
CONSOLE=hvc0
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
KERNEL_BIN="/boot/vmlinuz-$KERNEL_VER"
|
KERNEL_BIN="/boot/vmlinuz-$KERNEL_VER"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user