#include "libudev-private.h"
#include "udev-util.h"
#include "rtnl-util.h"
+#include "bus-util.h"
+#include "def.h"
#include "mkdir.h"
#include "virt.h"
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;
} 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',"
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;
}
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;
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);
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;
for (link = reply; link; link = sd_rtnl_message_next(link)) {
int k;
+ m->enumerating = true;
+
k = manager_rtnl_process_link(m->rtnl, link, m);
if (k < 0)
r = k;
+
+ m->enumerating = false;
}
return r;
for (addr = reply; addr; addr = sd_rtnl_message_next(addr)) {
int k;
+ m->enumerating = true;
+
k = link_rtnl_process_address(m->rtnl, addr, m);
if (k < 0)
r = k;
+
+ m->enumerating = false;
}
return r;
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: