timedated: replace systemd-timedated-ntp.target logic with simpler scheme
The previous systemd-timedated-ntp.target was suffering by the problem that NTP implementations enabled via the machanism could not be disabled the obvious way on the "systemctl disable" command line. Replace systemd-timedated-ntp.target by a list of implementations we try in turn. The list is encoded in $pkgdatadir/ntp-units.
This commit is contained in:
parent
b1239c3fb3
commit
ac7019f33f
|
@ -96,6 +96,7 @@ dist_udevrules_DATA =
|
||||||
nodist_udevrules_DATA =
|
nodist_udevrules_DATA =
|
||||||
dist_man_MANS =
|
dist_man_MANS =
|
||||||
dist_pkgsysconf_DATA =
|
dist_pkgsysconf_DATA =
|
||||||
|
dist_pkgdata_DATA =
|
||||||
dist_dbuspolicy_DATA =
|
dist_dbuspolicy_DATA =
|
||||||
dbusinterface_DATA =
|
dbusinterface_DATA =
|
||||||
dist_dbussystemservice_DATA =
|
dist_dbussystemservice_DATA =
|
||||||
|
@ -132,6 +133,7 @@ AM_CPPFLAGS = \
|
||||||
-DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
|
-DSYSTEM_SHUTDOWN_PATH=\"$(systemshutdowndir)\" \
|
||||||
-DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
|
-DSYSTEM_SLEEP_PATH=\"$(systemsleepdir)\" \
|
||||||
-DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
|
-DSYSTEMD_KBD_MODEL_MAP=\"$(pkgdatadir)/kbd-model-map\" \
|
||||||
|
-DSYSTEMD_NTP_UNITS=\"$(pkgdatadir)/ntp-units\" \
|
||||||
-DX_SERVER=\"$(bindir)/X\" \
|
-DX_SERVER=\"$(bindir)/X\" \
|
||||||
-DUDEVLIBEXECDIR=\"$(udevlibexecdir)\" \
|
-DUDEVLIBEXECDIR=\"$(udevlibexecdir)\" \
|
||||||
-DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
|
-DPOLKIT_AGENT_BINARY_PATH=\"$(bindir)/pkttyagent\" \
|
||||||
|
@ -309,7 +311,6 @@ dist_systemunit_DATA = \
|
||||||
units/syslog.target \
|
units/syslog.target \
|
||||||
units/systemd-udev-control.socket \
|
units/systemd-udev-control.socket \
|
||||||
units/systemd-udev-kernel.socket \
|
units/systemd-udev-kernel.socket \
|
||||||
units/systemd-timedated-ntp.target \
|
|
||||||
units/system-update.target
|
units/system-update.target
|
||||||
|
|
||||||
nodist_systemunit_DATA = \
|
nodist_systemunit_DATA = \
|
||||||
|
@ -2745,7 +2746,7 @@ man/systemd-localed.8: man/systemd-localed.service.8
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
units/systemd-localed.service.in
|
units/systemd-localed.service.in
|
||||||
|
|
||||||
dist_pkgdata_DATA = \
|
dist_pkgdata_DATA += \
|
||||||
src/locale/kbd-model-map
|
src/locale/kbd-model-map
|
||||||
|
|
||||||
dist_noinst_SCRIPT = \
|
dist_noinst_SCRIPT = \
|
||||||
|
@ -2801,6 +2802,9 @@ timedated-install-data-hook:
|
||||||
INSTALL_DATA_HOOKS += \
|
INSTALL_DATA_HOOKS += \
|
||||||
timedated-install-data-hook
|
timedated-install-data-hook
|
||||||
|
|
||||||
|
dist_pkgdata_DATA += \
|
||||||
|
src/timedate/ntp-units
|
||||||
|
|
||||||
MANPAGES += \
|
MANPAGES += \
|
||||||
man/systemd-timedated.service.8
|
man/systemd-timedated.service.8
|
||||||
|
|
||||||
|
|
4
src/timedate/ntp-units
Normal file
4
src/timedate/ntp-units
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# NTP ervice implementations, in order for preference
|
||||||
|
|
||||||
|
chronyd.service
|
||||||
|
ntpd.service
|
|
@ -303,62 +303,112 @@ static int write_data_local_rtc(void) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char** get_ntp_services(void) {
|
||||||
|
char **r = NULL;
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
|
f = fopen(SYSTEMD_NTP_UNITS, "re");
|
||||||
|
if (!f)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
char line[PATH_MAX], *l, **q;
|
||||||
|
|
||||||
|
if (!fgets(line, sizeof(line), f)) {
|
||||||
|
|
||||||
|
if (ferror(f))
|
||||||
|
log_error("Failed to read NTP units file: %m");
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = strstrip(line);
|
||||||
|
if (l[0] == 0 || l[0] == '#')
|
||||||
|
continue;
|
||||||
|
|
||||||
|
|
||||||
|
q = strv_append(r, l);
|
||||||
|
if (!q) {
|
||||||
|
log_error("Out of memory");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
strv_free(r);
|
||||||
|
r = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int read_ntp(DBusConnection *bus) {
|
static int read_ntp(DBusConnection *bus) {
|
||||||
DBusMessage *m = NULL, *reply = NULL;
|
DBusMessage *m = NULL, *reply = NULL;
|
||||||
const char *name = "systemd-timedated-ntp.target", *s;
|
|
||||||
DBusError error;
|
DBusError error;
|
||||||
int r;
|
int r;
|
||||||
|
char **i, **l;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
|
|
||||||
dbus_error_init(&error);
|
dbus_error_init(&error);
|
||||||
|
|
||||||
m = dbus_message_new_method_call(
|
l = get_ntp_services();
|
||||||
"org.freedesktop.systemd1",
|
STRV_FOREACH(i, l) {
|
||||||
"/org/freedesktop/systemd1",
|
const char *s;
|
||||||
"org.freedesktop.systemd1.Manager",
|
|
||||||
"GetUnitFileState");
|
|
||||||
|
|
||||||
if (!m) {
|
if (m)
|
||||||
log_error("Out of memory");
|
dbus_message_unref(m);
|
||||||
r = -ENOMEM;
|
m = dbus_message_new_method_call(
|
||||||
goto finish;
|
"org.freedesktop.systemd1",
|
||||||
}
|
"/org/freedesktop/systemd1",
|
||||||
|
"org.freedesktop.systemd1.Manager",
|
||||||
if (!dbus_message_append_args(m,
|
"GetUnitFileState");
|
||||||
DBUS_TYPE_STRING, &name,
|
if (!m) {
|
||||||
DBUS_TYPE_INVALID)) {
|
log_error("Out of memory");
|
||||||
log_error("Could not append arguments to message.");
|
r = -ENOMEM;
|
||||||
r = -ENOMEM;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
|
|
||||||
if (!reply) {
|
|
||||||
|
|
||||||
if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
|
|
||||||
/* NTP is not installed. */
|
|
||||||
tz.use_ntp = false;
|
|
||||||
r = 0;
|
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_error("Failed to issue method call: %s", bus_error_message(&error));
|
if (!dbus_message_append_args(m,
|
||||||
r = -EIO;
|
DBUS_TYPE_STRING, i,
|
||||||
|
DBUS_TYPE_INVALID)) {
|
||||||
|
log_error("Could not append arguments to message.");
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply)
|
||||||
|
dbus_message_unref(reply);
|
||||||
|
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, &error);
|
||||||
|
if (!reply) {
|
||||||
|
if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) {
|
||||||
|
/* This implementation does not exist, try next one */
|
||||||
|
dbus_error_free(&error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error("Failed to issue method call: %s", bus_error_message(&error));
|
||||||
|
r = -EIO;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbus_message_get_args(reply, &error,
|
||||||
|
DBUS_TYPE_STRING, &s,
|
||||||
|
DBUS_TYPE_INVALID)) {
|
||||||
|
log_error("Failed to parse reply: %s", bus_error_message(&error));
|
||||||
|
r = -EIO;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
tz.use_ntp =
|
||||||
|
streq(s, "enabled") ||
|
||||||
|
streq(s, "enabled-runtime");
|
||||||
|
r = 0;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbus_message_get_args(reply, &error,
|
/* NTP is not installed. */
|
||||||
DBUS_TYPE_STRING, &s,
|
tz.use_ntp = 0;
|
||||||
DBUS_TYPE_INVALID)) {
|
|
||||||
log_error("Failed to parse reply: %s", bus_error_message(&error));
|
|
||||||
r = -EIO;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
tz.use_ntp =
|
|
||||||
streq(s, "enabled") ||
|
|
||||||
streq(s, "enabled-runtime");
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
@ -368,6 +418,8 @@ finish:
|
||||||
if (reply)
|
if (reply)
|
||||||
dbus_message_unref(reply);
|
dbus_message_unref(reply);
|
||||||
|
|
||||||
|
strv_free(l);
|
||||||
|
|
||||||
dbus_error_free(&error);
|
dbus_error_free(&error);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
|
@ -375,40 +427,60 @@ finish:
|
||||||
|
|
||||||
static int start_ntp(DBusConnection *bus, DBusError *error) {
|
static int start_ntp(DBusConnection *bus, DBusError *error) {
|
||||||
DBusMessage *m = NULL, *reply = NULL;
|
DBusMessage *m = NULL, *reply = NULL;
|
||||||
const char *name = "systemd-timedated-ntp.target", *mode = "replace";
|
const char *mode = "replace";
|
||||||
|
char **i, **l;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
assert(error);
|
assert(error);
|
||||||
|
|
||||||
m = dbus_message_new_method_call(
|
l = get_ntp_services();
|
||||||
"org.freedesktop.systemd1",
|
STRV_FOREACH(i, l) {
|
||||||
"/org/freedesktop/systemd1",
|
if (m)
|
||||||
"org.freedesktop.systemd1.Manager",
|
dbus_message_unref(m);
|
||||||
tz.use_ntp ? "StartUnit" : "StopUnit");
|
m = dbus_message_new_method_call(
|
||||||
if (!m) {
|
"org.freedesktop.systemd1",
|
||||||
log_error("Could not allocate message.");
|
"/org/freedesktop/systemd1",
|
||||||
r = -ENOMEM;
|
"org.freedesktop.systemd1.Manager",
|
||||||
|
tz.use_ntp ? "StartUnit" : "StopUnit");
|
||||||
|
if (!m) {
|
||||||
|
log_error("Could not allocate message.");
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dbus_message_append_args(m,
|
||||||
|
DBUS_TYPE_STRING, i,
|
||||||
|
DBUS_TYPE_STRING, &mode,
|
||||||
|
DBUS_TYPE_INVALID)) {
|
||||||
|
log_error("Could not append arguments to message.");
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply)
|
||||||
|
dbus_message_unref(reply);
|
||||||
|
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
|
||||||
|
if (!reply) {
|
||||||
|
if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound") ||
|
||||||
|
streq(error->name, "org.freedesktop.systemd1.LoadFailed") ||
|
||||||
|
streq(error->name, "org.freedesktop.systemd1.NoSuchUnit")) {
|
||||||
|
/* This implementation does not exist, try next one */
|
||||||
|
dbus_error_free(error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error("Failed to issue method call: %s", bus_error_message(error));
|
||||||
|
r = -EIO;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 0;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dbus_message_append_args(m,
|
/* No implementaiton available... */
|
||||||
DBUS_TYPE_STRING, &name,
|
r = -ENOENT;
|
||||||
DBUS_TYPE_STRING, &mode,
|
|
||||||
DBUS_TYPE_INVALID)) {
|
|
||||||
log_error("Could not append arguments to message.");
|
|
||||||
r = -ENOMEM;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
|
|
||||||
if (!reply) {
|
|
||||||
log_error("Failed to issue method call: %s", bus_error_message(error));
|
|
||||||
r = -EIO;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (m)
|
if (m)
|
||||||
|
@ -417,82 +489,105 @@ finish:
|
||||||
if (reply)
|
if (reply)
|
||||||
dbus_message_unref(reply);
|
dbus_message_unref(reply);
|
||||||
|
|
||||||
|
strv_free(l);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enable_ntp(DBusConnection *bus, DBusError *error) {
|
static int enable_ntp(DBusConnection *bus, DBusError *error) {
|
||||||
DBusMessage *m = NULL, *reply = NULL;
|
DBusMessage *m = NULL, *reply = NULL;
|
||||||
const char * const names[] = { "systemd-timedated-ntp.target", NULL };
|
|
||||||
int r;
|
int r;
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
dbus_bool_t f = FALSE, t = TRUE;
|
dbus_bool_t f = FALSE, t = TRUE;
|
||||||
|
char **i, **l;
|
||||||
|
|
||||||
assert(bus);
|
assert(bus);
|
||||||
assert(error);
|
assert(error);
|
||||||
|
|
||||||
m = dbus_message_new_method_call(
|
l = get_ntp_services();
|
||||||
"org.freedesktop.systemd1",
|
STRV_FOREACH(i, l) {
|
||||||
"/org/freedesktop/systemd1",
|
char* k[2];
|
||||||
"org.freedesktop.systemd1.Manager",
|
|
||||||
tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
|
|
||||||
|
|
||||||
if (!m) {
|
if (m)
|
||||||
log_error("Could not allocate message.");
|
dbus_message_unref(m);
|
||||||
r = -ENOMEM;
|
m = dbus_message_new_method_call(
|
||||||
goto finish;
|
"org.freedesktop.systemd1",
|
||||||
}
|
"/org/freedesktop/systemd1",
|
||||||
|
"org.freedesktop.systemd1.Manager",
|
||||||
dbus_message_iter_init_append(m, &iter);
|
tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles");
|
||||||
|
if (!m) {
|
||||||
r = bus_append_strv_iter(&iter, (char**) names);
|
log_error("Could not allocate message.");
|
||||||
if (r < 0) {
|
|
||||||
log_error("Failed to append unit files.");
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
/* send runtime bool */
|
|
||||||
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
|
|
||||||
log_error("Failed to append runtime boolean.");
|
|
||||||
r = -ENOMEM;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tz.use_ntp) {
|
|
||||||
/* send force bool */
|
|
||||||
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
|
|
||||||
log_error("Failed to append force boolean.");
|
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
|
dbus_message_iter_init_append(m, &iter);
|
||||||
if (!reply) {
|
|
||||||
log_error("Failed to issue method call: %s", bus_error_message(error));
|
k[0] = *i;
|
||||||
r = -EIO;
|
k[1] = NULL;
|
||||||
|
|
||||||
|
r = bus_append_strv_iter(&iter, k);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to append unit files.");
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send runtime bool */
|
||||||
|
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &f)) {
|
||||||
|
log_error("Failed to append runtime boolean.");
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tz.use_ntp) {
|
||||||
|
/* send force bool */
|
||||||
|
if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &t)) {
|
||||||
|
log_error("Failed to append force boolean.");
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reply)
|
||||||
|
dbus_message_unref(reply);
|
||||||
|
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
|
||||||
|
if (!reply) {
|
||||||
|
if (streq(error->name, "org.freedesktop.DBus.Error.FileNotFound")) {
|
||||||
|
/* This implementation does not exist, try next one */
|
||||||
|
dbus_error_free(error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error("Failed to issue method call: %s", bus_error_message(error));
|
||||||
|
r = -EIO;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_message_unref(m);
|
||||||
|
m = dbus_message_new_method_call(
|
||||||
|
"org.freedesktop.systemd1",
|
||||||
|
"/org/freedesktop/systemd1",
|
||||||
|
"org.freedesktop.systemd1.Manager",
|
||||||
|
"Reload");
|
||||||
|
if (!m) {
|
||||||
|
log_error("Could not allocate message.");
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbus_message_unref(reply);
|
||||||
|
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
|
||||||
|
if (!reply) {
|
||||||
|
log_error("Failed to issue method call: %s", bus_error_message(error));
|
||||||
|
r = -EIO;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 0;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_unref(m);
|
r = -ENOENT;
|
||||||
m = dbus_message_new_method_call(
|
|
||||||
"org.freedesktop.systemd1",
|
|
||||||
"/org/freedesktop/systemd1",
|
|
||||||
"org.freedesktop.systemd1.Manager",
|
|
||||||
"Reload");
|
|
||||||
if (!m) {
|
|
||||||
log_error("Could not allocate message.");
|
|
||||||
r = -ENOMEM;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbus_message_unref(reply);
|
|
||||||
reply = dbus_connection_send_with_reply_and_block(bus, m, -1, error);
|
|
||||||
if (!reply) {
|
|
||||||
log_error("Failed to issue method call: %s", bus_error_message(error));
|
|
||||||
r = -EIO;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (m)
|
if (m)
|
||||||
|
@ -501,6 +596,8 @@ finish:
|
||||||
if (reply)
|
if (reply)
|
||||||
dbus_message_unref(reply);
|
dbus_message_unref(reply);
|
||||||
|
|
||||||
|
strv_free(l);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
# 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.
|
|
||||||
|
|
||||||
# This target is enabled/disabled via the timedated mechanism when the
|
|
||||||
# user asks for it via the UI. NTP implementations should hook
|
|
||||||
# themselves into this target via .wants/ symlinks, and then add
|
|
||||||
# BindTo= on this target so that they are stopped when it goes away.
|
|
||||||
|
|
||||||
[Unit]
|
|
||||||
Description=Network Time Protocol
|
|
||||||
Documentation=http://www.freedesktop.org/wiki/Software/systemd/timedated
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
Loading…
Reference in a new issue