diff --git a/src/timesync/meson.build b/src/timesync/meson.build index 72c7327cc8..5ecf98a029 100644 --- a/src/timesync/meson.build +++ b/src/timesync/meson.build @@ -4,6 +4,8 @@ systemd_timesyncd_sources = files(''' timesyncd.c + timesyncd-bus.c + timesyncd-bus.h timesyncd-conf.c timesyncd-conf.h timesyncd-manager.c @@ -27,6 +29,10 @@ if conf.get('ENABLE_TIMESYNCD') == 1 configuration : substs) install_data(timesyncd_conf, install_dir : pkgsysconfdir) + install_data('org.freedesktop.timesync1.conf', + install_dir : dbuspolicydir) + install_data('org.freedesktop.timesync1.service', + install_dir : dbussystemservicedir) endif ############################################################ diff --git a/src/timesync/org.freedesktop.timesync1.conf b/src/timesync/org.freedesktop.timesync1.conf new file mode 100644 index 0000000000..eccdbec718 --- /dev/null +++ b/src/timesync/org.freedesktop.timesync1.conf @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/timesync/org.freedesktop.timesync1.service b/src/timesync/org.freedesktop.timesync1.service new file mode 100644 index 0000000000..84b4b4f973 --- /dev/null +++ b/src/timesync/org.freedesktop.timesync1.service @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: LGPL-2.1+ +# +# 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. + +[D-BUS Service] +Name=org.freedesktop.timesync1 +Exec=/bin/false +User=root +SystemdService=dbus-org.freedesktop.timesync1.service diff --git a/src/timesync/timesyncd-bus.c b/src/timesync/timesyncd-bus.c new file mode 100644 index 0000000000..2068601e70 --- /dev/null +++ b/src/timesync/timesyncd-bus.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "sd-bus.h" + +#include "alloc-util.h" +#include "bus-util.h" +#include "in-addr-util.h" +#include "log.h" +#include "macro.h" +#include "time-util.h" +#include "timesyncd-bus.h" + +static int property_get_servers( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ServerName *p, **s = userdata; + int r; + + assert(s); + assert(bus); + assert(reply); + + r = sd_bus_message_open_container(reply, 'a', "s"); + if (r < 0) + return r; + + LIST_FOREACH(names, p, *s) { + r = sd_bus_message_append(reply, "s", p->string); + if (r < 0) + return r; + } + + return sd_bus_message_close_container(reply); +} + +static int property_get_current_server_name( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ServerName **s = userdata; + + assert(s); + assert(bus); + assert(reply); + + return sd_bus_message_append(reply, "s", *s ? (*s)->string : ""); +} + +static int property_get_current_server_address( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ServerAddress *a; + int r; + + assert(bus); + assert(reply); + assert(userdata); + + a = *(ServerAddress **) userdata; + + if (!a) + return sd_bus_message_append(reply, "(iay)", AF_UNSPEC, 0); + + r = sd_bus_message_open_container(reply, 'r', "iay"); + if (r < 0) + return r; + + r = sd_bus_message_append(reply, "i", a->sockaddr.sa.sa_family); + if (r < 0) + return r; + + r = sd_bus_message_append_array(reply, 'y', &a->sockaddr.in.sin_addr, FAMILY_ADDRESS_SIZE(a->sockaddr.sa.sa_family)); + if (r < 0) + return r; + + return sd_bus_message_close_container(reply); +} + +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("FallbackNTPServers", "as", property_get_servers, offsetof(Manager, fallback_servers), SD_BUS_VTABLE_PROPERTY_CONST), + 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, max_root_distance_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PollIntervalMinUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_min_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PollIntervalMaxUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_max_usec), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("PollIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, poll_interval_usec), 0), + + SD_BUS_VTABLE_END +}; + +int manager_connect_bus(Manager *m) { + int r; + + assert(m); + + if (m->bus) + return 0; + + r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-timesync"); + if (r < 0) + return log_error_errno(r, "Failed to connect to bus: %m"); + + r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/timesync1", "org.freedesktop.timesync1.Manager", manager_vtable, m); + if (r < 0) + return log_error_errno(r, "Failed to add manager object vtable: %m"); + + r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.timesync1", 0, NULL, NULL); + if (r < 0) + return log_error_errno(r, "Failed to request name: %m"); + + r = sd_bus_attach_event(m->bus, m->event, 0); + if (r < 0) + return log_error_errno(r, "Failed to attach bus to event loop: %m"); + + return 0; +} diff --git a/src/timesync/timesyncd-bus.h b/src/timesync/timesyncd-bus.h new file mode 100644 index 0000000000..6670ffbc36 --- /dev/null +++ b/src/timesync/timesyncd-bus.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +#pragma once + +#include "timesyncd-manager.h" + +int manager_connect_bus(Manager *m); diff --git a/src/timesync/timesyncd-manager.c b/src/timesync/timesyncd-manager.c index c5721a5752..520e4e1f0f 100644 --- a/src/timesync/timesyncd-manager.c +++ b/src/timesync/timesyncd-manager.c @@ -986,6 +986,8 @@ void manager_free(Manager *m) { sd_resolve_unref(m->resolve); sd_event_unref(m->event); + sd_bus_unref(m->bus); + free(m); } diff --git a/src/timesync/timesyncd-manager.h b/src/timesync/timesyncd-manager.h index 62f129ef9b..500f94c5ca 100644 --- a/src/timesync/timesyncd-manager.h +++ b/src/timesync/timesyncd-manager.h @@ -7,6 +7,7 @@ Copyright 2014 Kay Sievers, Lennart Poettering ***/ +#include "sd-bus.h" #include "sd-event.h" #include "sd-network.h" #include "sd-resolve.h" @@ -27,6 +28,7 @@ typedef struct Manager Manager; #define NTP_POLL_INTERVAL_MAX_USEC (2048 * USEC_PER_SEC) struct Manager { + sd_bus *bus; sd_event *event; sd_resolve *resolve; diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c index 8a4999c74a..dbecfb6ce8 100644 --- a/src/timesync/timesyncd.c +++ b/src/timesync/timesyncd.c @@ -16,6 +16,7 @@ #include "network-util.h" #include "process-util.h" #include "signal-util.h" +#include "timesyncd-bus.h" #include "timesyncd-conf.h" #include "timesyncd-manager.h" #include "user-util.h" @@ -133,6 +134,12 @@ int main(int argc, char *argv[]) { goto finish; } + r = manager_connect_bus(m); + if (r < 0) { + log_error_errno(r, "Could not connect to bus: %m"); + goto finish; + } + if (clock_is_localtime(NULL) > 0) { log_info("The system is configured to read the RTC time in the local time zone. " "This mode cannot be fully supported. All system time to RTC updates are disabled."); diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in index 5b8b243f17..913dac773a 100644 --- a/units/systemd-timesyncd.service.in +++ b/units/systemd-timesyncd.service.in @@ -45,3 +45,4 @@ StateDirectory=systemd/timesync [Install] WantedBy=sysinit.target +Alias=dbus-org.freedesktop.timesync1.service