diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 79d58dd099..4733dd5177 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -82,19 +82,6 @@ static int setup_default_address_pool(Manager *m) { return 0; } -static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) { - Manager *m = userdata; - - assert(s); - assert(m); - - m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source); - - manager_connect_bus(m); - - return 0; -} - static int manager_reset_all(Manager *m) { Link *link; Iterator i; @@ -116,6 +103,7 @@ static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_b int b, r; assert(message); + assert(m); r = sd_bus_message_read(message, "b", &b); if (r < 0) { @@ -133,34 +121,32 @@ static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_b return 0; } +static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { + Manager *m = userdata; + + assert(message); + assert(m); + + /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */ + if (m->dynamic_hostname) + (void) manager_set_hostname(m, m->dynamic_hostname); + if (m->dynamic_timezone) + (void) manager_set_timezone(m, m->dynamic_timezone); + + return 0; +} + int manager_connect_bus(Manager *m) { int r; assert(m); - r = sd_bus_default_system(&m->bus); - if (r < 0) { - /* We failed to connect? Yuck, we must be in early - * boot. Let's try in 5s again. */ - - log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m"); - - r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m); - if (r < 0) - return log_error_errno(r, "Failed to install bus reconnect time event: %m"); - + if (m->bus) return 0; - } - r = sd_bus_match_signal_async( - m->bus, &m->prepare_for_sleep_slot, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - "PrepareForSleep", - match_prepare_for_sleep, NULL, m); + r = bus_open_system_watch_bind(&m->bus); if (r < 0) - return log_error_errno(r, "Failed to request match for PrepareForSleep: %m"); + return log_error_errno(r, "Failed to connect to bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m); if (r < 0) @@ -190,17 +176,27 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); - /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */ - if (m->dynamic_hostname) { - r = manager_set_hostname(m, m->dynamic_hostname); - if (r < 0) - return r; - } - if (m->dynamic_timezone) { - r = manager_set_timezone(m, m->dynamic_timezone); - if (r < 0) - return r; - } + r = sd_bus_match_signal_async( + m->bus, + &m->connected_slot, + "org.freedesktop.DBus.Local", + NULL, + "org.freedesktop.DBus.Local", + "Connected", + on_connected, NULL, m); + if (r < 0) + return log_error_errno(r, "Failed to request match on Connected signal: %m"); + + r = sd_bus_match_signal_async( + m->bus, + &m->prepare_for_sleep_slot, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + "PrepareForSleep", + match_prepare_for_sleep, NULL, m); + if (r < 0) + log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m"); return 0; } @@ -1320,6 +1316,7 @@ void manager_free(Manager *m) { sd_bus_unref(m->bus); sd_bus_slot_unref(m->prepare_for_sleep_slot); + sd_bus_slot_unref(m->connected_slot); sd_event_source_unref(m->bus_retry_event_source); free(m->dynamic_timezone); @@ -1594,12 +1591,12 @@ int manager_set_hostname(Manager *m, const char *hostname) { int r; log_debug("Setting transient hostname: '%s'", strna(hostname)); + if (free_and_strdup(&m->dynamic_hostname, hostname) < 0) return log_oom(); - if (!m->bus) { - /* TODO: replace by assert when we can rely on kdbus */ - log_info("Not connected to system bus, ignoring transient hostname."); + if (!m->bus || sd_bus_is_ready(m->bus) <= 0) { + log_info("Not connected to system bus, not setting hostname."); return 0; } @@ -1646,8 +1643,8 @@ int manager_set_timezone(Manager *m, const char *tz) { if (free_and_strdup(&m->dynamic_timezone, tz) < 0) return log_oom(); - if (!m->bus) { - log_info("Not connected to system bus, ignoring timezone."); + if (!m->bus || sd_bus_is_ready(m->bus) <= 0) { + log_info("Not connected to system bus, not setting hostname."); return 0; } diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h index 186cb41891..1f7f306af9 100644 --- a/src/network/networkd-manager.h +++ b/src/network/networkd-manager.h @@ -43,6 +43,7 @@ struct Manager { sd_event_source *bus_retry_event_source; sd_bus *bus; sd_bus_slot *prepare_for_sleep_slot; + sd_bus_slot *connected_slot; struct udev *udev; struct udev_monitor *udev_monitor; sd_event_source *udev_event_source; diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index ff629ea41b..ffd7c4824e 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -1844,18 +1844,6 @@ static const sd_bus_vtable resolve_vtable[] = { SD_BUS_VTABLE_END, }; -static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) { - Manager *m = userdata; - - assert(s); - assert(m); - - m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source); - - manager_connect_bus(m); - return 0; -} - static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) { Manager *m = userdata; int b, r; @@ -1886,20 +1874,9 @@ int manager_connect_bus(Manager *m) { if (m->bus) return 0; - r = sd_bus_default_system(&m->bus); - if (r < 0) { - /* We failed to connect? Yuck, we must be in early - * boot. Let's try in 5s again. */ - - log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m"); - - r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m); - if (r < 0) - return log_error_errno(r, "Failed to install bus reconnect time event: %m"); - - (void) sd_event_source_set_description(m->bus_retry_event_source, "bus-retry"); - return 0; - } + r = bus_open_system_watch_bind(&m->bus); + if (r < 0) + return log_error_errno(r, "Failed to connect to system bus: %m"); r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m); if (r < 0) @@ -1940,7 +1917,7 @@ int manager_connect_bus(Manager *m) { NULL, m); if (r < 0) - log_error_errno(r, "Failed to request match for PrepareForSleep: %m"); + log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m"); return 0; } diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index b9e25a0d4e..b6677e27f6 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1598,3 +1598,54 @@ int bus_track_add_name_many(sd_bus_track *t, char **l) { return r; } + +int bus_open_system_watch_bind(sd_bus **ret) { + _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL; + const char *e; + int r; + + assert(ret); + + /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */ + + r = sd_bus_new(&bus); + if (r < 0) + return r; + + e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS"); + if (!e) + e = DEFAULT_SYSTEM_BUS_ADDRESS; + + r = sd_bus_set_address(bus, e); + if (r < 0) + return r; + + r = sd_bus_set_bus_client(bus, true); + if (r < 0) + return r; + + r = sd_bus_set_trusted(bus, true); + if (r < 0) + return r; + + r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS); + if (r < 0) + return r; + + r = sd_bus_set_watch_bind(bus, true); + if (r < 0) + return r; + + r = sd_bus_set_connected_signal(bus, true); + if (r < 0) + return r; + + r = sd_bus_start(bus); + if (r < 0) + return r; + + *ret = bus; + bus = NULL; + + return 0; +} diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index a9f4969d7d..cbd22a6cd6 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -162,3 +162,5 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); int bus_track_add_name_many(sd_bus_track *t, char **l); + +int bus_open_system_watch_bind(sd_bus **ret); diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 76bd5eff95..df21b3f30e 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -152,6 +152,8 @@ int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b); int sd_bus_get_exit_on_disconnect(sd_bus *bus); int sd_bus_set_watch_bind(sd_bus *bus, int b); int sd_bus_get_watch_bind(sd_bus *bus); +int sd_bus_set_connected_signal(sd_bus *bus, int b); +int sd_bus_get_connected_signal(sd_bus *bus); int sd_bus_start(sd_bus *bus);