From 9e644a9cedde002f0fe932d38b244f75513ada88 Mon Sep 17 00:00:00 2001 From: Philippe Coval Date: Thu, 14 Nov 2013 16:29:07 +0100 Subject: [PATCH] timedate: connman support and sync NTP state Relying on enabled status of NTP unit providers is not enough, since those could be installed as "static services" so we can not rely on this, and the internal state should be queried. If connman-ntp is installed as "static systemd service" then updates NTP mode from connman-ntp state. (This query is done through dbus and look for "TimeUpdates" == "auto" in reply). This is fixing issues like unpreserved/inconsistent states between freedesktop and connman (specially after rebooting). Unless there is a generic way to query NTP providers this could done by hand there and for other ones (ntpd, chronyd etc too). Some hints in TODO file and over there : http://www.freedesktop.org/wiki/Software/systemd/timedated/ Change-Id: I975dd2a385ae4e08556d0d76831214bfaa8ea298 Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71922 Bug: https://01.org/jira/browse/CM-654 Signed-off-by: Philippe Coval --- src/timedate/timedated.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index cdb6e5b..6ca1192 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -318,6 +318,91 @@ static char** get_ntp_services(void) { return strv_uniq(i); } +static int read_ntp_connman(DBusConnection *bus) { + int r = FALSE; + DBusMessage *m = NULL, *reply = NULL; + DBusError error; + DBusMessageIter arrayiter, dictiter, entryiter, variter; + int type; + char *key = NULL, *value = NULL; + + assert(bus); + + dbus_error_init(&error); + + m = dbus_message_new_method_call("net.connman", + "/", + "net.connman.Clock", + "GetProperties"); + if (!m) { + log_oom(); + 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")) + dbus_error_free(&error); + log_error("Failed to issue method call: %s", bus_error_message(&error)); + goto finish; + } + + if (!dbus_message_iter_init(reply, &arrayiter)) { + log_error("Failed to parse reply"); + goto finish; + } + + dbus_message_iter_recurse(&arrayiter, &dictiter); + + do { + type = dbus_message_iter_get_arg_type(&dictiter); + if (type != DBUS_TYPE_DICT_ENTRY) + continue; + + dbus_message_iter_recurse(&dictiter, &entryiter); + + type = dbus_message_iter_get_arg_type(&entryiter); + if (type != DBUS_TYPE_STRING) + continue; + + key = NULL; + dbus_message_iter_get_basic(&entryiter, &key); + if (!streq(key,"TimeUpdates")) + continue; + + if (!dbus_message_iter_next(&entryiter)) + continue; + + type=dbus_message_iter_get_arg_type(&entryiter); + if (type != DBUS_TYPE_VARIANT) + continue; + + dbus_message_iter_recurse(&entryiter, &variter); + + type = dbus_message_iter_get_arg_type(&variter); + if (type != DBUS_TYPE_STRING) + continue; + + value = NULL; + dbus_message_iter_get_basic(&variter, &value); + log_debug("connan: ntp: TimeUpdates=\'%s\' ?= \'auto\'", value); + r = streq(value, "auto"); + + goto finish; + + } while (dbus_message_iter_next(&dictiter)); + +finish: + + if (m) + dbus_message_unref(m); + + if (reply) + dbus_message_unref(reply); + + return r; +} + static int read_ntp(DBusConnection *bus) { DBusMessage *m = NULL, *reply = NULL; DBusError error; @@ -373,9 +458,14 @@ static int read_ntp(DBusConnection *bus) { } tz.can_ntp = 1; - tz.use_ntp = - streq(s, "enabled") || - streq(s, "enabled-runtime"); + if (i && streq(*i, "connman-ntp.service") && + streq(s, "static")) { + tz.use_ntp = read_ntp_connman(bus); + } else { + tz.use_ntp = + streq(s, "enabled") || + streq(s, "enabled-runtime"); + } r = 0; goto finish; } -- 1.8.1.2