diff options
author | Lennart Poettering <lennart@poettering.net> | 2012-07-01 17:37:21 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2012-07-02 10:43:56 +0200 |
commit | ac7019f33f1618f5b69ed44a8623e2596f1e3856 (patch) | |
tree | debfa0184b8c05760825f5e6c7ad00c0a3452d9e /src/timedate/timedated.c | |
parent | b1239c3fb3d19ff7273a8e5ead5c42f055d10b92 (diff) |
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.
Diffstat (limited to 'src/timedate/timedated.c')
-rw-r--r-- | src/timedate/timedated.c | 321 |
1 files changed, 209 insertions, 112 deletions
diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 8316bc3ea2..4be7c3a997 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -303,62 +303,112 @@ static int write_data_local_rtc(void) { 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) { DBusMessage *m = NULL, *reply = NULL; - const char *name = "systemd-timedated-ntp.target", *s; DBusError error; int r; + char **i, **l; assert(bus); dbus_error_init(&error); - m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - "GetUnitFileState"); - - if (!m) { - log_error("Out of memory"); - r = -ENOMEM; - goto finish; - } + l = get_ntp_services(); + STRV_FOREACH(i, l) { + const char *s; + + if (m) + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + "GetUnitFileState"); + if (!m) { + log_error("Out of memory"); + r = -ENOMEM; + goto finish; + } - if (!dbus_message_append_args(m, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) { - log_error("Could not append arguments to message."); - r = -ENOMEM; - goto finish; - } + if (!dbus_message_append_args(m, + DBUS_TYPE_STRING, i, + 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) { + 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; + } - if (streq(error.name, "org.freedesktop.DBus.Error.FileNotFound")) { - /* NTP is not installed. */ - tz.use_ntp = false; - r = 0; + log_error("Failed to issue method call: %s", bus_error_message(&error)); + r = -EIO; goto finish; } - 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; + } - 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; + tz.use_ntp = + streq(s, "enabled") || + streq(s, "enabled-runtime"); + r = 0; goto finish; } - tz.use_ntp = - streq(s, "enabled") || - streq(s, "enabled-runtime"); + /* NTP is not installed. */ + tz.use_ntp = 0; r = 0; finish: @@ -368,6 +418,8 @@ finish: if (reply) dbus_message_unref(reply); + strv_free(l); + dbus_error_free(&error); return r; @@ -375,40 +427,60 @@ finish: static int start_ntp(DBusConnection *bus, DBusError *error) { DBusMessage *m = NULL, *reply = NULL; - const char *name = "systemd-timedated-ntp.target", *mode = "replace"; + const char *mode = "replace"; + char **i, **l; int r; assert(bus); assert(error); - m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - tz.use_ntp ? "StartUnit" : "StopUnit"); - if (!m) { - log_error("Could not allocate message."); - r = -ENOMEM; - goto finish; - } + l = get_ntp_services(); + STRV_FOREACH(i, l) { + if (m) + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "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, &name, - DBUS_TYPE_STRING, &mode, - DBUS_TYPE_INVALID)) { - log_error("Could not append arguments to 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; + } - 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; + r = 0; goto finish; } - r = 0; + /* No implementaiton available... */ + r = -ENOENT; finish: if (m) @@ -417,82 +489,105 @@ finish: if (reply) dbus_message_unref(reply); + strv_free(l); + return r; } static int enable_ntp(DBusConnection *bus, DBusError *error) { DBusMessage *m = NULL, *reply = NULL; - const char * const names[] = { "systemd-timedated-ntp.target", NULL }; int r; DBusMessageIter iter; dbus_bool_t f = FALSE, t = TRUE; + char **i, **l; assert(bus); assert(error); - m = dbus_message_new_method_call( - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1.Manager", - tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles"); + l = get_ntp_services(); + STRV_FOREACH(i, l) { + char* k[2]; + + if (m) + dbus_message_unref(m); + m = dbus_message_new_method_call( + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1.Manager", + tz.use_ntp ? "EnableUnitFiles" : "DisableUnitFiles"); + if (!m) { + log_error("Could not allocate message."); + r = -ENOMEM; + goto finish; + } - if (!m) { - log_error("Could not allocate message."); - r = -ENOMEM; - goto finish; - } + dbus_message_iter_init_append(m, &iter); - dbus_message_iter_init_append(m, &iter); + k[0] = *i; + k[1] = NULL; - r = bus_append_strv_iter(&iter, (char**) names); - 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; - } + r = bus_append_strv_iter(&iter, k); + if (r < 0) { + log_error("Failed to append unit files."); + 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."); + /* 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; } - } - 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; - } + 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; + } + } - 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; - } + 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; + } - 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; + 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; } - r = 0; + r = -ENOENT; finish: if (m) @@ -501,6 +596,8 @@ finish: if (reply) dbus_message_unref(reply); + strv_free(l); + return r; } |