diff options
-rw-r--r-- | src/network/netdev/netdev.c | 28 | ||||
-rw-r--r-- | src/network/netdev/netdev.h | 6 | ||||
-rw-r--r-- | src/network/networkd-link.h | 4 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 4 | ||||
-rw-r--r-- | src/network/networkd-network.c | 41 | ||||
-rw-r--r-- | src/network/networkd-network.h | 2 |
6 files changed, 61 insertions, 24 deletions
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index f7598dc7ea..48ea6c9f77 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -34,6 +34,7 @@ #include "networkd-queue.h" #include "networkd-setlink.h" #include "networkd-sriov.h" +#include "networkd-state-file.h" #include "nlmon.h" #include "path-lookup.h" #include "siphash24.h" @@ -351,16 +352,16 @@ void link_assign_netdev(Link *link) { old = TAKE_PTR(link->netdev); if (netdev_get(link->manager, link->ifname, &netdev) < 0) - return; + goto not_found; int ifindex = NETDEV_VTABLE(netdev)->get_ifindex ? NETDEV_VTABLE(netdev)->get_ifindex(netdev, link->ifname) : netdev->ifindex; if (ifindex != link->ifindex) - return; + goto not_found; if (NETDEV_VTABLE(netdev)->iftype != link->iftype) - return; + goto not_found; if (!NETDEV_VTABLE(netdev)->skip_netdev_kind_check) { const char *kind; @@ -371,13 +372,23 @@ void link_assign_netdev(Link *link) { kind = netdev_kind_to_string(netdev->kind); if (!streq_ptr(kind, link->kind)) - return; + goto not_found; } link->netdev = netdev_ref(netdev); - if (netdev != old) - log_link_debug(link, "Found matching .netdev file: %s", netdev->filename); + if (netdev == old) + return; /* The same NetDev found. */ + + log_link_debug(link, "Found matching .netdev file: %s", netdev->filename); + link_dirty(link); + return; + +not_found: + + if (old) + /* Previously assigned NetDev is detached from Manager? Update the state file. */ + link_dirty(link); } void netdev_enter_failed(NetDev *netdev) { @@ -1003,15 +1014,12 @@ int netdev_load_one(Manager *manager, const char *filename) { return 0; } -int netdev_load(Manager *manager, bool reload) { +int netdev_load(Manager *manager) { _cleanup_strv_free_ char **files = NULL; int r; assert(manager); - if (!reload) - hashmap_clear_with_destructor(manager->netdevs, netdev_unref); - r = conf_files_list_strv(&files, ".netdev", NULL, 0, NETWORK_DIRS); if (r < 0) return log_error_errno(r, "Failed to enumerate netdev files: %m"); diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index 10b9d0dd77..b3969b6e3b 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -211,14 +211,14 @@ NetDev* netdev_detach_name(NetDev *netdev, const char *name); void netdev_detach(NetDev *netdev); int netdev_set_ifindex_internal(NetDev *netdev, int ifindex); -int netdev_load(Manager *manager, bool reload); +int netdev_load(Manager *manager); int netdev_load_one(Manager *manager, const char *filename); void netdev_drop(NetDev *netdev); void netdev_enter_failed(NetDev *netdev); int netdev_enter_ready(NetDev *netdev); -NetDev *netdev_unref(NetDev *netdev); -NetDev *netdev_ref(NetDev *netdev); +NetDev* netdev_unref(NetDev *netdev); +NetDev* netdev_ref(NetDev *netdev); DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index e29dd5d990..8ac7c35563 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -222,8 +222,8 @@ bool link_is_ready_to_configure(Link *link, bool allow_unmanaged); void link_ntp_settings_clear(Link *link); void link_dns_settings_clear(Link *link); -Link *link_unref(Link *link); -Link *link_ref(Link *link); +Link* link_unref(Link *link); +Link* link_ref(Link *link); DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_unref); DEFINE_TRIVIAL_DESTRUCTOR(link_netlink_destroy_callback, Link, link_unref); diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index fdaf3ff4d7..ca2b008a34 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -777,7 +777,7 @@ int manager_start(Manager *m) { int manager_load_config(Manager *m) { int r; - r = netdev_load(m, false); + r = netdev_load(m); if (r < 0) return r; @@ -1188,7 +1188,7 @@ int manager_reload(Manager *m, sd_bus_message *message) { (void) notify_reloading(); - r = netdev_load(m, /* reload= */ true); + r = netdev_load(m); if (r < 0) goto finish; diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 3d399fe876..9cd683e9bc 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -598,24 +598,47 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi return 0; } -int network_load(Manager *manager, OrderedHashmap **networks) { +int network_load(Manager *manager, OrderedHashmap **ret) { _cleanup_strv_free_ char **files = NULL; + OrderedHashmap *networks = NULL; int r; assert(manager); - - ordered_hashmap_clear_with_destructor(*networks, network_unref); + assert(ret); r = conf_files_list_strv(&files, ".network", NULL, 0, NETWORK_DIRS); if (r < 0) return log_error_errno(r, "Failed to enumerate network files: %m"); STRV_FOREACH(f, files) - (void) network_load_one(manager, networks, *f); + (void) network_load_one(manager, &networks, *f); + *ret = TAKE_PTR(networks); return 0; } +static bool network_netdev_equal(Network *a, Network *b) { + assert(a); + assert(b); + + if (a->batadv != b->batadv || + a->bridge != b->bridge || + a->bond != b->bond || + a->vrf != b->vrf || + a->xfrm != b->xfrm) + return false; + + if (hashmap_size(a->stacked_netdevs) != hashmap_size(b->stacked_netdevs)) + return false; + + NetDev *n; + HASHMAP_FOREACH(n, a->stacked_netdevs) + if (hashmap_get(b->stacked_netdevs, n->ifname) != n) + return false; + + return true; +} + int network_reload(Manager *manager) { OrderedHashmap *new_networks = NULL; Network *n, *old; @@ -630,15 +653,21 @@ int network_reload(Manager *manager) { ORDERED_HASHMAP_FOREACH(n, new_networks) { r = network_get_by_name(manager, n->name, &old); if (r < 0) { - log_debug("Found new .network file: %s", n->filename); + log_debug("%s: Found new .network file.", n->filename); continue; } if (!stats_by_path_equal(n->stats_by_path, old->stats_by_path)) { - log_debug("Found updated .network file: %s", n->filename); + log_debug("%s: Found updated .network file.", n->filename); + continue; + } + + if (!network_netdev_equal(n, old)) { + log_debug("%s: Detected update of referenced .netdev file(s).", n->filename); continue; } + /* Nothing updated, use the existing Network object, and drop the new one. */ r = ordered_hashmap_replace(new_networks, old->name, old); if (r < 0) goto failure; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index b4ab117928..30ea9ac352 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -419,7 +419,7 @@ Network *network_ref(Network *network); Network *network_unref(Network *network); DEFINE_TRIVIAL_CLEANUP_FUNC(Network*, network_unref); -int network_load(Manager *manager, OrderedHashmap **networks); +int network_load(Manager *manager, OrderedHashmap **ret); int network_reload(Manager *manager); int network_load_one(Manager *manager, OrderedHashmap **networks, const char *filename); int network_verify(Network *network); |