timesyncd: read server settings from a configuration file
Also, allow compiling in a default server list via a configure command line item.
This commit is contained in:
parent
16c058ba01
commit
e8af69739a
29
Makefile.am
29
Makefile.am
|
@ -128,6 +128,7 @@ polkitpolicy_in_files =
|
|||
polkitpolicy_files =
|
||||
dist_udevrules_DATA =
|
||||
nodist_udevrules_DATA =
|
||||
nodist_pkgsysconf_DATA =
|
||||
dist_pkgsysconf_DATA =
|
||||
dist_pkgdata_DATA =
|
||||
dist_dbuspolicy_DATA =
|
||||
|
@ -4017,7 +4018,17 @@ EXTRA_DIST += \
|
|||
# ------------------------------------------------------------------------------
|
||||
if ENABLE_TIMESYNCD
|
||||
systemd_timesyncd_SOURCES = \
|
||||
src/timesync/timesyncd.c
|
||||
src/timesync/timesyncd.c \
|
||||
src/timesync/timesyncd.h
|
||||
|
||||
nodist_systemd_timesyncd_SOURCES = \
|
||||
src/timesync/timesyncd-gperf.c
|
||||
|
||||
EXTRA_DIST += \
|
||||
src/timesync/timesyncd-gperf.gperf
|
||||
|
||||
CLEANFILES += \
|
||||
src/timesync/timesyncd-gperf.c
|
||||
|
||||
systemd_timesyncd_LDADD = \
|
||||
libsystemd-label.la \
|
||||
|
@ -4034,6 +4045,16 @@ nodist_systemunit_DATA += \
|
|||
|
||||
EXTRA_DIST += \
|
||||
units/systemd-timesyncd.service.in
|
||||
|
||||
nodist_pkgsysconf_DATA += \
|
||||
src/timesync/timesyncd.conf
|
||||
|
||||
EXTRA_DIST += \
|
||||
src/timesync/timesyncd.conf.in
|
||||
|
||||
CLEANFILES += \
|
||||
src/timesync/timesyncd.conf
|
||||
|
||||
endif
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
|
@ -4763,7 +4784,8 @@ substitutions = \
|
|||
'|RC_LOCAL_SCRIPT_PATH_START=$(RC_LOCAL_SCRIPT_PATH_START)|' \
|
||||
'|RC_LOCAL_SCRIPT_PATH_STOP=$(RC_LOCAL_SCRIPT_PATH_STOP)|' \
|
||||
'|PYTHON=$(PYTHON)|' \
|
||||
'|PYTHON_BINARY=$(PYTHON_BINARY)|'
|
||||
'|PYTHON_BINARY=$(PYTHON_BINARY)|' \
|
||||
'|NTP_SERVERS=$(NTP_SERVERS)|'
|
||||
|
||||
SED_PROCESS = \
|
||||
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
||||
|
@ -4791,6 +4813,9 @@ src/%.policy.in: src/%.policy.in.in
|
|||
%.rules: %.rules.in
|
||||
$(SED_PROCESS)
|
||||
|
||||
%.conf: %.conf.in
|
||||
$(SED_PROCESS)
|
||||
|
||||
%.sh: %.sh.in
|
||||
$(SED_PROCESS)
|
||||
$(AM_V_GEN)chmod +x $@
|
||||
|
|
10
configure.ac
10
configure.ac
|
@ -827,6 +827,15 @@ if test "x$enable_timesyncd" != "xno"; then
|
|||
fi
|
||||
AM_CONDITIONAL(ENABLE_TIMESYNCD, [test "$have_timesyncd" = "yes"])
|
||||
|
||||
AC_ARG_WITH(ntp-servers,
|
||||
AS_HELP_STRING([--with-ntp-servers=NTPSERVERS],
|
||||
[Space-separated list of default NTP servers]),
|
||||
[NTP_SERVERS="$withval"],
|
||||
[NTP_SERVERS="time1.google.com time2.google.com time3.google.com time4.google.com"])
|
||||
|
||||
AC_DEFINE_UNQUOTED(NTP_SERVERS, ["$NTP_SERVERS"], [Default NTP Servers])
|
||||
AC_SUBST(NTP_SERVERS)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
have_localed=no
|
||||
AC_ARG_ENABLE(localed, AS_HELP_STRING([--disable-localed], [disable locale daemon]))
|
||||
|
@ -1159,6 +1168,7 @@ AC_MSG_RESULT([
|
|||
hostnamed: ${have_hostnamed}
|
||||
timedated: ${have_timedated}
|
||||
timesyncd: ${have_timesyncd}
|
||||
default NTP servers: ${NTP_SERVERS}
|
||||
localed: ${have_localed}
|
||||
networkd: ${have_networkd}
|
||||
coredump: ${have_coredump}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
/timesyncd.conf
|
||||
/timesyncd-gperf.c
|
|
@ -0,0 +1 @@
|
|||
../Makefile
|
|
@ -0,0 +1,17 @@
|
|||
%{
|
||||
#include <stddef.h>
|
||||
#include "conf-parser.h"
|
||||
#include "timesyncd.h"
|
||||
%}
|
||||
struct ConfigPerfItem;
|
||||
%null_strings
|
||||
%language=ANSI-C
|
||||
%define slot-name section_and_lvalue
|
||||
%define hash-function-name timesyncdd_gperf_hash
|
||||
%define lookup-function-name timesyncd_gperf_lookup
|
||||
%readonly-tables
|
||||
%omit-struct-type
|
||||
%struct-type
|
||||
%includes
|
||||
%%
|
||||
Time.Servers, config_parse_servers, 0, 0
|
|
@ -3,7 +3,7 @@
|
|||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Kay Sievers
|
||||
Copyright 2014 Kay Sievers, Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -42,9 +42,11 @@
|
|||
#include "list.h"
|
||||
#include "ratelimit.h"
|
||||
#include "strv.h"
|
||||
#include "conf-parser.h"
|
||||
#include "sd-event.h"
|
||||
#include "sd-resolve.h"
|
||||
#include "sd-daemon.h"
|
||||
#include "timesyncd.h"
|
||||
|
||||
#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1)
|
||||
|
||||
|
@ -116,73 +118,6 @@ struct ntp_msg {
|
|||
struct ntp_ts trans_time;
|
||||
} _packed_;
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct ServerAddress ServerAddress;
|
||||
typedef struct ServerName ServerName;
|
||||
|
||||
struct ServerAddress {
|
||||
union sockaddr_union sockaddr;
|
||||
socklen_t socklen;
|
||||
LIST_FIELDS(ServerAddress, addresses);
|
||||
};
|
||||
|
||||
struct ServerName {
|
||||
char *string;
|
||||
LIST_HEAD(ServerAddress, addresses);
|
||||
LIST_FIELDS(ServerName, names);
|
||||
};
|
||||
|
||||
struct Manager {
|
||||
sd_event *event;
|
||||
sd_resolve *resolve;
|
||||
|
||||
LIST_HEAD(ServerName, servers);
|
||||
|
||||
RateLimit ratelimit;
|
||||
|
||||
/* peer */
|
||||
sd_resolve_query *resolve_query;
|
||||
sd_event_source *event_receive;
|
||||
ServerName *current_server_name;
|
||||
ServerAddress *current_server_address;
|
||||
int server_socket;
|
||||
uint64_t packet_count;
|
||||
sd_event_source *event_timeout;
|
||||
|
||||
/* last sent packet */
|
||||
struct timespec trans_time_mon;
|
||||
struct timespec trans_time;
|
||||
usec_t retry_interval;
|
||||
bool pending;
|
||||
|
||||
/* poll timer */
|
||||
sd_event_source *event_timer;
|
||||
usec_t poll_interval_usec;
|
||||
bool poll_resync;
|
||||
|
||||
/* history data */
|
||||
struct {
|
||||
double offset;
|
||||
double delay;
|
||||
} samples[8];
|
||||
unsigned int samples_idx;
|
||||
double samples_jitter;
|
||||
|
||||
/* last change */
|
||||
bool jumped;
|
||||
int drift_ppm;
|
||||
|
||||
/* watch for time changes */
|
||||
sd_event_source *event_clock_watch;
|
||||
int clock_watch_fd;
|
||||
|
||||
/* Retry connections */
|
||||
sd_event_source *event_retry;
|
||||
|
||||
/* Handle SIGINT/SIGTERM */
|
||||
sd_event_source *sigterm, *sigint;
|
||||
};
|
||||
|
||||
static void manager_free(Manager *m);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
#define _cleanup_manager_free_ _cleanup_(manager_freep)
|
||||
|
@ -974,6 +909,28 @@ static int manager_add_server(Manager *m, const char *server) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int manager_add_server_string(Manager *m, const char *string) {
|
||||
char *w, *state;
|
||||
size_t l;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(string);
|
||||
|
||||
FOREACH_WORD_QUOTED(w, l, string, state) {
|
||||
char t[l+1];
|
||||
|
||||
memcpy(t, w, 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));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void manager_disconnect(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
|
@ -1047,15 +1004,70 @@ static void manager_free(Manager *m) {
|
|||
free(m);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_manager_free_ Manager *m = NULL;
|
||||
const char *x;
|
||||
int config_parse_servers(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
Manager *m = userdata;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
|
||||
manager_flush_names(m);
|
||||
manager_add_server_string(m, rvalue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int manager_parse_config_file(Manager *m) {
|
||||
static const char fn[] = "/etc/systemd/timesyncd.conf";
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
f = fopen(fn, "re");
|
||||
if (!f) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
log_warning("Failed to open configuration file %s: %m", fn);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
r = config_parse(NULL, fn, f, "Time\0", config_item_perf_lookup,
|
||||
(void*) timesyncd_gperf_lookup, false, false, m);
|
||||
if (r < 0)
|
||||
log_warning("Failed to parse configuration file: %s", strerror(-r));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_manager_free_ Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
if (argc > 1) {
|
||||
log_error("This program does not take arguments.");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_set_facility(LOG_CRON);
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
umask(0022);
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1) == 0);
|
||||
|
||||
r = manager_new(&m);
|
||||
|
@ -1064,15 +1076,11 @@ int main(int argc, char *argv[]) {
|
|||
goto out;
|
||||
}
|
||||
|
||||
sd_notify(false, "READY=1");
|
||||
manager_add_server_string(m, NTP_SERVERS);
|
||||
manager_parse_config_file(m);
|
||||
|
||||
FOREACH_STRING(x, "8.8.8.8", "172.31.0.1", "time1.google.com", "time2.google.com", "time3.google.com", "time4.google.com", "0.fedora.pool.ntp.org") {
|
||||
r = manager_add_server(m, x);
|
||||
if (r < 0) {
|
||||
log_error("Failed to add server %s: %s", x, strerror(-r));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
log_debug("systemd-timesyncd running as pid %lu", (unsigned long) getpid());
|
||||
sd_notify(false, "READY=1");
|
||||
|
||||
r = manager_connect(m);
|
||||
if (r < 0)
|
||||
|
@ -1087,5 +1095,7 @@ int main(int argc, char *argv[]) {
|
|||
sd_event_get_exit_code(m->event, &r);
|
||||
|
||||
out:
|
||||
sd_notify(false, "STATUS=Shutting down...");
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# See timesyncd.conf(5) for details
|
||||
|
||||
[Time]
|
||||
#Servers=@NTP_SERVERS@
|
|
@ -0,0 +1,97 @@
|
|||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2014 Kay Sievers, Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "list.h"
|
||||
#include "socket-util.h"
|
||||
#include "ratelimit.h"
|
||||
#include "sd-event.h"
|
||||
#include "sd-resolve.h"
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct ServerAddress ServerAddress;
|
||||
typedef struct ServerName ServerName;
|
||||
|
||||
struct ServerAddress {
|
||||
union sockaddr_union sockaddr;
|
||||
socklen_t socklen;
|
||||
LIST_FIELDS(ServerAddress, addresses);
|
||||
};
|
||||
|
||||
struct ServerName {
|
||||
char *string;
|
||||
LIST_HEAD(ServerAddress, addresses);
|
||||
LIST_FIELDS(ServerName, names);
|
||||
};
|
||||
|
||||
struct Manager {
|
||||
sd_event *event;
|
||||
sd_resolve *resolve;
|
||||
|
||||
LIST_HEAD(ServerName, servers);
|
||||
|
||||
RateLimit ratelimit;
|
||||
|
||||
/* peer */
|
||||
sd_resolve_query *resolve_query;
|
||||
sd_event_source *event_receive;
|
||||
ServerName *current_server_name;
|
||||
ServerAddress *current_server_address;
|
||||
int server_socket;
|
||||
uint64_t packet_count;
|
||||
sd_event_source *event_timeout;
|
||||
|
||||
/* last sent packet */
|
||||
struct timespec trans_time_mon;
|
||||
struct timespec trans_time;
|
||||
usec_t retry_interval;
|
||||
bool pending;
|
||||
|
||||
/* poll timer */
|
||||
sd_event_source *event_timer;
|
||||
usec_t poll_interval_usec;
|
||||
bool poll_resync;
|
||||
|
||||
/* history data */
|
||||
struct {
|
||||
double offset;
|
||||
double delay;
|
||||
} samples[8];
|
||||
unsigned int samples_idx;
|
||||
double samples_jitter;
|
||||
|
||||
/* last change */
|
||||
bool jumped;
|
||||
int drift_ppm;
|
||||
|
||||
/* watch for time changes */
|
||||
sd_event_source *event_clock_watch;
|
||||
int clock_watch_fd;
|
||||
|
||||
/* Retry connections */
|
||||
sd_event_source *event_retry;
|
||||
|
||||
/* Handle SIGINT/SIGTERM */
|
||||
sd_event_source *sigterm, *sigint;
|
||||
};
|
||||
|
||||
const struct ConfigPerfItem* timesyncd_gperf_lookup(const char *key, unsigned length);
|
||||
|
||||
int config_parse_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
|
Loading…
Reference in New Issue