mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
networkd,resolved: make use of watch_bind feature to connect to the bus
The changes both networkd and resolved to make use of the watch_bind feature of sd-bus to connect to the system bus. This way, both daemons can be started during early boot, and automatically and instantly connect to the system bus as it becomes available. This replaces prior code that used a time-based retry logic to connect to the bus.
This commit is contained in:
parent
b38cc8d563
commit
d7afd945b5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user