X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-manager.c;h=cffae835f5daf63efc221050b4b9e3b4786b3645;hb=113b3fc1a8061f4a24dd0db74e9a3cd0083b2251;hp=4d27272b3be3b7e47907b3fc3fcabd860a94881f;hpb=6a24f1484fcc1f59f89617afbe4282667a358eab;p=elogind.git diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 4d27272b3..cffae835f 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -27,11 +27,11 @@ #include "networkd.h" #include "networkd-netdev.h" #include "networkd-link.h" -#include "network-internal.h" #include "libudev-private.h" #include "udev-util.h" #include "rtnl-util.h" -#include "mkdir.h" +#include "bus-util.h" +#include "def.h" #include "virt.h" #include "sd-rtnl.h" @@ -76,8 +76,6 @@ static int setup_default_address_pool(Manager *m) { return 0; } -int manager_connect_bus(Manager *m); - static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) { Manager *m = userdata; @@ -151,10 +149,6 @@ int manager_connect_bus(Manager *m) { } if (r < 0) return r; - r = sd_bus_attach_event(m->bus, m->event, 0); - if (r < 0) - return r; - r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot, "type='signal'," "sender='org.freedesktop.login1'," @@ -166,6 +160,34 @@ int manager_connect_bus(Manager *m) { if (r < 0) return log_error_errno(r, "Failed to add match for PrepareForSleep: %m"); + r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m); + if (r < 0) + return log_error_errno(r, "Failed to add manager object vtable: %m"); + + r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m); + if (r < 0) + return log_error_errno(r, "Failed to add link object vtable: %m"); + + r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/link", link_node_enumerator, m); + if (r < 0) + return log_error_errno(r, "Failed to add link enumerator: %m"); + + r = sd_bus_add_fallback_vtable(m->bus, NULL, "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m); + if (r < 0) + return log_error_errno(r, "Failed to add network object vtable: %m"); + + r = sd_bus_add_node_enumerator(m->bus, NULL, "/org/freedesktop/network1/network", network_node_enumerator, m); + if (r < 0) + return log_error_errno(r, "Failed to add network enumerator: %m"); + + r = sd_bus_request_name(m->bus, "org.freedesktop.network1", 0); + if (r < 0) + return log_error_errno(r, "Failed to register 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; } @@ -419,10 +441,6 @@ int manager_new(Manager **ret) { if (r < 0) return r; - r = manager_connect_bus(m); - if (r < 0) - return r; - r = manager_connect_udev(m); if (r < 0) return r; @@ -469,6 +487,8 @@ void manager_free(Manager *m) { while ((network = m->networks)) network_free(network); + hashmap_free(m->networks_by_name); + while ((netdev = hashmap_first(m->netdevs))) netdev_unref(netdev); hashmap_free(m->netdevs); @@ -481,6 +501,51 @@ void manager_free(Manager *m) { free(m); } +static bool manager_check_idle(void *userdata) { + Manager *m = userdata; + Link *link; + Iterator i; + + assert(m); + + HASHMAP_FOREACH(link, m->links, i) { + /* we are not woken on udev activity, so let's just wait for the + * pending udev event */ + if (link->state == LINK_STATE_PENDING) + return false; + + if (!link->network) + continue; + + /* we are not woken on netork activity, so let's stay around */ + if (link_lldp_enabled(link) || + link_ipv4ll_enabled(link) || + link_dhcp4_server_enabled(link) || + link_dhcp4_enabled(link) || + link_dhcp6_enabled(link)) + return false; + } + + return true; +} + +int manager_run(Manager *m) { + assert(m); + + if (m->bus) + return bus_event_loop_with_idle( + m->event, + m->bus, + "org.freedesktop.network1", + DEFAULT_EXIT_USEC, + manager_check_idle, + m); + else + /* failed to connect to the bus, so we lose exit-on-idle logic, + this should not happen except if dbus is not around at all */ + return sd_event_loop(m->event); +} + int manager_load_config(Manager *m) { int r; @@ -741,6 +806,13 @@ int manager_save(Manager *m) { goto fail; } + if (m->operational_state != operstate) { + m->operational_state = operstate; + r = manager_send_changed(m, "OperationalState", NULL); + if (r < 0) + log_error_errno(r, "Could not emit changed OperationalState: %m"); + } + return 0; fail: