diff --git a/man/systemd-timedated.service.xml b/man/systemd-timedated.service.xml
index 3626e8bc51..f981848cb2 100644
--- a/man/systemd-timedated.service.xml
+++ b/man/systemd-timedated.service.xml
@@ -31,7 +31,7 @@
systemd-timedated is a system service
that may be used as a mechanism to change the system clock and
- timezone, as well as to enable/disable NTP time synchronization.
+ timezone, as well as to enable/disable network time synchronization.
systemd-timedated is automatically activated
on request and terminates itself when it is unused.
@@ -46,25 +46,36 @@
- Environment
+ List of network time synchronization services
-
-
- $SYSTEMD_TIMEDATED_NTP_SERVICES
+ systemd-timesyncd will look for files with a .list extension
+ in ntp-units.d/ directories. Each file is parsed as a list of unit names, one per
+ line. Empty lines and lines with comments (#) are ignored. Files are read from
+ /usr/lib/systemd/ntp-units.d/ and the corresponding directories under
+ /etc/, /run/, /usr/local/lib/. Files in
+ /etc/ override files with the same name in /run/,
+ /usr/local/lib/, and /usr/lib/. Files in
+ /run/ override files with the same name under /usr/. Packages
+ should install their configuration files in /usr/lib/ (distribution packages) or
+ /usr/local/lib/ (local installs).
- Colon-separated list of unit names of NTP client services.
- If not set, then
- systemd-timesyncd.service8
- is used. See the entries of NTP related commands of
- timedatectl1
- for details about this.
+
+ ntp-units.d/ entry for systemd-timesyncd
+ # /usr/lib/systemd/ntp-units.d/80-systemd-timesync.list
+systemd-timesyncd.service
+
+
- Example:
- SYSTEMD_TIMEDATED_NTP_SERVICES=ntpd.service:chronyd.service:systemd-timesyncd.service
-
-
-
+ If the environment variable $SYSTEMD_TIMEDATED_NTP_SERVICES is set,
+ systemd-timesyncd will parse the contents of that variable as a colon-separated list
+ of unit names. When set, this variable overrides the file-based list described above.
+
+
+ An override that specifies that chronyd should be used if available
+ SYSTEMD_TIMEDATED_NTP_SERVICES=chronyd.service:systemd-timesyncd.service
+
+
See Also
diff --git a/man/timedatectl.xml b/man/timedatectl.xml
index 262b9126e7..f797e0cd67 100644
--- a/man/timedatectl.xml
+++ b/man/timedatectl.xml
@@ -23,22 +23,25 @@
- timedatectl OPTIONS COMMAND
+ timedatectl
+ OPTIONS
+ COMMAND
Description
- timedatectl may be used to query and
- change the system clock and its settings.
+ timedatectl may be used to query and change the system clock and its settings,
+ and enable or disable time synchronization services.
Use
systemd-firstboot1
to initialize the system time zone for mounted (but not booted)
system images.
- timedatectl may be used to show the current status of
+ timedatectl may be used to show the current status of time synchronization
+ services, for example
systemd-timesyncd.service8.
@@ -123,11 +126,8 @@
status
- Show current settings of the system clock and RTC,
- including whether network time synchronization through
- systemd-timesyncd.service is active. Even if it is
- inactive, a different service might still synchronize the clock.
- If no command is specified, this is the implied default.
+ Show current settings of the system clock and RTC, including whether network time
+ synchronization is active. If no command is specified, this is the implied default.
@@ -193,11 +193,11 @@
set-ntp [BOOL]
- Takes a boolean argument. Controls whether network time synchronization is active
- and enabled (if available). If the argument is true, this enables and starts the first existed
- service listed in the environment variable $SYSTEMD_TIMEDATED_NTP_SERVICES
- of systemd-timedated.service. If the argument is false, then this disables and
- stops the all services listed in $SYSTEMD_TIMEDATED_NTP_SERVICES.
+ Takes a boolean argument. Controls whether network time synchronization is active and
+ enabled (if available). If the argument is true, this enables and starts the first existing network
+ synchronization service. If the argument is false, then this disables and stops the known network
+ synchronization services. The way that the list of services is built is described below.
+
@@ -250,8 +250,7 @@
Exit status
- On success, 0 is returned, a non-zero failure
- code otherwise.
+ On success, 0 is returned, a non-zero failure code otherwise.
diff --git a/meson.build b/meson.build
index 04a830cdfa..09abd9e2ec 100644
--- a/meson.build
+++ b/meson.build
@@ -157,6 +157,7 @@ systemdstatedir = join_paths(localstatedir, 'lib/systemd')
catalogstatedir = join_paths(systemdstatedir, 'catalog')
randomseeddir = join_paths(localstatedir, 'lib/systemd')
profiledir = join_paths(rootlibexecdir, 'portable', 'profile')
+ntpservicelistdir = join_paths(rootprefixdir, 'lib/systemd/ntp-units.d')
docdir = get_option('docdir')
if docdir == ''
diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c
index c602e036eb..96e74a758f 100644
--- a/src/shared/pretty-print.c
+++ b/src/shared/pretty-print.c
@@ -247,6 +247,11 @@ static int guess_type(const char **name, bool *is_usr, bool *is_collection, cons
if (path_equal(n, "kernel/install.d"))
ext = ".install";
+ if (path_equal(n, "systemd/ntp-units.d")) {
+ coll = true;
+ ext = ".list";
+ }
+
if (PATH_IN_SET(n, "systemd/system-preset", "systemd/user-preset")) {
coll = true;
ext = ".preset";
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c
index 57bbefc0c1..074ba3c079 100644
--- a/src/timedate/timedated.c
+++ b/src/timedate/timedated.c
@@ -15,7 +15,9 @@
#include "bus-error.h"
#include "bus-util.h"
#include "clock-util.h"
+#include "conf-files.h"
#include "def.h"
+#include "fd-util.h"
#include "fileio-label.h"
#include "fileio.h"
#include "fs-util.h"
@@ -36,6 +38,8 @@
#define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n"
#define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n"
+#define UNIT_LIST_DIRS (const char* const*) CONF_PATHS_STRV("systemd/ntp-units.d")
+
typedef struct UnitStatusInfo {
char *name;
char *load_state;
@@ -117,20 +121,17 @@ static int context_add_ntp_service(Context *c, const char *s) {
return 0;
}
-static int context_parse_ntp_services(Context *c) {
+static int context_parse_ntp_services_from_environment(Context *c) {
const char *env, *p;
int r;
assert(c);
env = getenv("SYSTEMD_TIMEDATED_NTP_SERVICES");
- if (!env) {
- r = context_add_ntp_service(c, "systemd-timesyncd.service");
- if (r < 0)
- log_warning_errno(r, "Failed to add NTP service \"systemd-timesyncd.service\", ignoring: %m");
-
+ if (!env)
return 0;
- }
+
+ log_debug("Using list of ntp services from environment variable $SYSTEMD_TIMEDATED_NTP_SERVICES.");
for (p = env;;) {
_cleanup_free_ char *word = NULL;
@@ -150,7 +151,62 @@ static int context_parse_ntp_services(Context *c) {
log_warning_errno(r, "Failed to add NTP service \"%s\", ignoring: %m", word);
}
- return 0;
+ return 1;
+}
+
+static int context_parse_ntp_services_from_disk(Context *c) {
+ _cleanup_strv_free_ char **files = NULL;
+ char **f;
+ int r;
+
+ r = conf_files_list_strv(&files, ".list", NULL, CONF_FILES_FILTER_MASKED, UNIT_LIST_DIRS);
+ if (r < 0)
+ return log_error_errno(r, "Failed to enumerate .list files: %m");
+
+ STRV_FOREACH(f, files) {
+ _cleanup_fclose_ FILE *file = NULL;
+
+ log_debug("Reading file '%s'", *f);
+
+ r = fopen_unlocked(*f, "re", &file);
+ if (r < 0) {
+ log_error_errno(r, "Failed to open %s, ignoring: %m", *f);
+ continue;
+ }
+
+ for (;;) {
+ _cleanup_free_ char *line = NULL;
+ const char *word;
+
+ r = read_line(file, LINE_MAX, &line);
+ if (r < 0) {
+ log_error_errno(r, "Failed to read %s, ignoring: %m", *f);
+ continue;
+ }
+ if (r == 0)
+ break;
+
+ word = strstrip(line);
+ if (isempty(word) || startswith("#", word))
+ continue;
+
+ r = context_add_ntp_service(c, word);
+ if (r < 0)
+ log_warning_errno(r, "Failed to add NTP service \"%s\", ignoring: %m", word);
+ }
+ }
+
+ return 1;
+}
+
+static int context_parse_ntp_services(Context *c) {
+ int r;
+
+ r = context_parse_ntp_services_from_environment(c);
+ if (r != 0)
+ return r;
+
+ return context_parse_ntp_services_from_disk(c);
}
static int context_ntp_service_is_active(Context *c) {
diff --git a/src/timesync/80-systemd-timesync.list b/src/timesync/80-systemd-timesync.list
new file mode 100644
index 0000000000..d5959ade89
--- /dev/null
+++ b/src/timesync/80-systemd-timesync.list
@@ -0,0 +1 @@
+systemd-timesyncd.service
diff --git a/src/timesync/meson.build b/src/timesync/meson.build
index b79ef08277..e5c118c8db 100644
--- a/src/timesync/meson.build
+++ b/src/timesync/meson.build
@@ -32,6 +32,8 @@ if conf.get('ENABLE_TIMESYNCD') == 1
install_dir : dbuspolicydir)
install_data('org.freedesktop.timesync1.service',
install_dir : dbussystemservicedir)
+ install_data('80-systemd-timesync.list',
+ install_dir : ntpservicelistdir)
endif
############################################################
diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
index 2d8d14f6de..2136a85b35 100644
--- a/units/systemd-timesyncd.service.in
+++ b/units/systemd-timesyncd.service.in
@@ -15,6 +15,7 @@ ConditionVirtualization=!container
DefaultDependencies=no
After=systemd-remount-fs.service systemd-sysusers.service
Before=time-set.target sysinit.target shutdown.target
+Conflicts=chronyd.service ntpd.service
Conflicts=shutdown.target
Wants=time-set.target time-sync.target