summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/timesync/timesyncd-bus.c8
-rw-r--r--src/timesync/timesyncd-manager.c70
-rw-r--r--src/timesync/timesyncd-manager.h6
-rw-r--r--src/timesync/timesyncd-server.c31
4 files changed, 110 insertions, 5 deletions
diff --git a/src/timesync/timesyncd-bus.c b/src/timesync/timesyncd-bus.c
index 1c33f3fbd2..7237080f32 100644
--- a/src/timesync/timesyncd-bus.c
+++ b/src/timesync/timesyncd-bus.c
@@ -210,10 +210,10 @@ static int property_get_ntp_message(
static const sd_bus_vtable manager_vtable[] = {
SD_BUS_VTABLE_START(0),
- SD_BUS_PROPERTY("LinkNTPServers", "as", property_get_servers, offsetof(Manager, link_servers), 0),
- SD_BUS_PROPERTY("SystemNTPServers", "as", property_get_servers, offsetof(Manager, system_servers), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("RuntimeNTPServers", "as", property_get_servers, offsetof(Manager, runtime_servers), 0),
- SD_BUS_PROPERTY("FallbackNTPServers", "as", property_get_servers, offsetof(Manager, fallback_servers), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("LinkNTPServers", "as", property_get_servers, offsetof(Manager, link_servers), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("SystemNTPServers", "as", property_get_servers, offsetof(Manager, system_servers), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("RuntimeNTPServers", "as", property_get_servers, offsetof(Manager, runtime_servers), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+ SD_BUS_PROPERTY("FallbackNTPServers", "as", property_get_servers, offsetof(Manager, fallback_servers), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("ServerName", "s", property_get_current_server_name, offsetof(Manager, current_server_name), 0),
SD_BUS_PROPERTY("ServerAddress", "(iay)", property_get_current_server_address, offsetof(Manager, current_server_address), 0),
SD_BUS_PROPERTY("RootDistanceMaxUSec", "t", bus_property_get_usec, offsetof(Manager, root_distance_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c
index 74ac20ac7c..21825f1165 100644
--- a/src/timesync/timesyncd-manager.c
+++ b/src/timesync/timesyncd-manager.c
@@ -955,6 +955,8 @@ Manager* manager_free(Manager *m) {
sd_event_source_unref(m->event_save_time);
+ sd_event_source_unref(m->deferred_ntp_server_event_source);
+
sd_resolve_unref(m->resolve);
sd_event_unref(m->event);
@@ -1221,3 +1223,71 @@ static int manager_save_time_and_rearm(Manager *m, usec_t t) {
return 0;
}
+
+static const char* ntp_server_property_name[_SERVER_TYPE_MAX] = {
+ [SERVER_SYSTEM] = "SystemNTPServers",
+ [SERVER_FALLBACK] = "FallbackNTPServers",
+ [SERVER_LINK] = "LinkNTPServers",
+ [SERVER_RUNTIME] = "RuntimeNTPServers",
+};
+
+static int ntp_server_emit_changed_strv(Manager *manager, char **properties) {
+ assert(manager);
+ assert(properties);
+
+ if (sd_bus_is_ready(manager->bus) <= 0)
+ return 0;
+
+ return sd_bus_emit_properties_changed_strv(
+ manager->bus,
+ "/org/freedesktop/timesync1",
+ "org.freedesktop.timesync1.Manager",
+ properties);
+}
+
+static int on_deferred_ntp_server(sd_event_source *s, void *userdata) {
+ int r;
+ _cleanup_strv_free_ char **p = NULL;
+ Manager *m = ASSERT_PTR(userdata);
+
+ m->deferred_ntp_server_event_source = sd_event_source_disable_unref(m->deferred_ntp_server_event_source);
+
+ for (int type = SERVER_SYSTEM; type < _SERVER_TYPE_MAX; type++)
+ if (m->ntp_server_change_mask & (1U << type))
+ if (strv_extend(&p, ntp_server_property_name[type]) < 0)
+ log_oom();
+
+ m->ntp_server_change_mask = 0;
+
+ if (strv_isempty(p))
+ return log_error_errno(SYNTHETIC_ERRNO(ENOMEM), "Failed to build ntp server event strv!");
+
+ r = ntp_server_emit_changed_strv(m, p);
+ if (r < 0)
+ log_warning_errno(r, "Could not emit ntp server changed properties, ignoring: %m");
+
+ return 0;
+}
+
+int bus_manager_emit_ntp_server_changed(Manager *m) {
+ int r;
+
+ assert(m);
+
+ if (m->deferred_ntp_server_event_source)
+ return 0;
+
+ if (!m->event)
+ return 0;
+
+ if (IN_SET(sd_event_get_state(m->event), SD_EVENT_FINISHED, SD_EVENT_EXITING))
+ return 0;
+
+ r = sd_event_add_defer(m->event, &m->deferred_ntp_server_event_source, on_deferred_ntp_server, m);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate ntp server event source: %m");
+
+ (void) sd_event_source_set_description(m->deferred_ntp_server_event_source, "deferred-ntp-server");
+
+ return 1;
+}
diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h
index e595c7ddfc..8cbb91d907 100644
--- a/src/timesync/timesyncd-manager.h
+++ b/src/timesync/timesyncd-manager.h
@@ -116,6 +116,10 @@ struct Manager {
sd_event_source *event_save_time;
usec_t save_time_interval_usec;
bool save_on_exit;
+
+ /* Used to coalesce bus PropertiesChanged events */
+ sd_event_source *deferred_ntp_server_event_source;
+ unsigned ntp_server_change_mask;
};
int manager_new(Manager **ret);
@@ -133,3 +137,5 @@ void manager_disconnect(Manager *m);
bool manager_is_connected(Manager *m);
int manager_setup_save_time_event(Manager *m);
+
+int bus_manager_emit_ntp_server_changed(Manager *m);
diff --git a/src/timesync/timesyncd-server.c b/src/timesync/timesyncd-server.c
index 7aa1551baf..fc9bca8c5a 100644
--- a/src/timesync/timesyncd-server.c
+++ b/src/timesync/timesyncd-server.c
@@ -60,12 +60,31 @@ ServerAddress* server_address_free(ServerAddress *a) {
return mfree(a);
}
+static int enable_ntp_server_defer_event(Manager *m, ServerType type) {
+ int r;
+
+ assert(m);
+ assert((type >= 0) && (type < _SERVER_TYPE_MAX));
+
+ r = sd_event_source_set_enabled(m->deferred_ntp_server_event_source, SD_EVENT_ONESHOT);
+ if (r < 0)
+ return log_debug_errno(r, "Failed to reenable system ntp server change event source!");
+
+ r = bus_manager_emit_ntp_server_changed(m);
+ if (r < 0)
+ return r;
+
+ m->ntp_server_change_mask |= 1U << type;
+
+ return 1;
+}
+
int server_name_new(
Manager *m,
ServerName **ret,
ServerType type,
const char *string) {
-
+ int r;
ServerName *n;
assert(m);
@@ -103,6 +122,10 @@ int server_name_new(
assert_not_reached();
}
+ r = enable_ntp_server_defer_event(m, type);
+ if (r < 0)
+ log_debug_errno(r, "Failed to enable ntp server defer event, ignoring: %m");
+
if (type != SERVER_FALLBACK &&
m->current_server_name &&
m->current_server_name->type == SERVER_FALLBACK)
@@ -117,6 +140,8 @@ int server_name_new(
}
ServerName *server_name_free(ServerName *n) {
+ int r;
+
if (!n)
return NULL;
@@ -134,6 +159,10 @@ ServerName *server_name_free(ServerName *n) {
else
assert_not_reached();
+ r = enable_ntp_server_defer_event(n->manager, n->type);
+ if (r < 0)
+ log_debug_errno(r, "Failed to enable ntp server defer event, ignoring: %m");
+
if (n->manager->current_server_name == n)
manager_set_server_name(n->manager, NULL);
}