diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2019-01-13 16:30:37 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-01-15 14:48:53 +0100 |
commit | 9e2bbf9915255770836d16cd99eeb6536297079d (patch) | |
tree | 9433c4c5187678f0229e88a077fc5fd03ff7e8dd | |
parent | Update uk.po (diff) | |
download | systemd-9e2bbf9915255770836d16cd99eeb6536297079d.tar.xz systemd-9e2bbf9915255770836d16cd99eeb6536297079d.zip |
network: make Link and NetDev always have the valid poiter to Manager
c4397d94c3d94909188d82e086ebedf5d3690569 introduces
link_detach_from_manager() and netdev_detach_from_manager(), and they
set Link::manager or NetDev::manager NULL.
But, at the time e.g. link is removed, hence link_drop() is called,
there may be still some asynchronous netlink call is waiting, and
their callbacks hit assertion.
This make {link,netdev}_detach_from_manager() just drop all references
from manager, but keep the pointer to manager.
Fixes #11411.
-rw-r--r-- | src/network/netdev/netdev.c | 9 | ||||
-rw-r--r-- | src/network/netdev/netdev.h | 1 | ||||
-rw-r--r-- | src/network/netdev/wireguard.c | 6 | ||||
-rw-r--r-- | src/network/networkd-link.c | 2 |
4 files changed, 10 insertions, 8 deletions
diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index f0e9d00246..65959f4a03 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -148,11 +148,16 @@ static void netdev_callbacks_clear(NetDev *netdev) { } } +bool netdev_is_managed(NetDev *netdev) { + if (!netdev || !netdev->manager || !netdev->ifname) + return false; + + return hashmap_get(netdev->manager->netdevs, netdev->ifname) == netdev; +} + static void netdev_detach_from_manager(NetDev *netdev) { if (netdev->ifname && netdev->manager) hashmap_remove(netdev->manager->netdevs, netdev->ifname); - - netdev->manager = NULL; } static NetDev *netdev_free(NetDev *netdev) { diff --git a/src/network/netdev/netdev.h b/src/network/netdev/netdev.h index bfe1094181..d6524da0f3 100644 --- a/src/network/netdev/netdev.h +++ b/src/network/netdev/netdev.h @@ -156,6 +156,7 @@ NetDev *netdev_ref(NetDev *netdev); DEFINE_TRIVIAL_DESTRUCTOR(netdev_destroy_callback, NetDev, netdev_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref); +bool netdev_is_managed(NetDev *netdev); int netdev_get(Manager *manager, const char *name, NetDev **ret); int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink); int netdev_get_mac(const char *ifname, struct ether_addr **ret); diff --git a/src/network/netdev/wireguard.c b/src/network/netdev/wireguard.c index 167cf65046..45b7c7c330 100644 --- a/src/network/netdev/wireguard.c +++ b/src/network/netdev/wireguard.c @@ -224,8 +224,7 @@ static int on_resolve_retry(sd_event_source *s, usec_t usec, void *userdata) { w = WIREGUARD(netdev); assert(w); - if (!netdev->manager) - /* The netdev is detached. */ + if (!netdev_is_managed(netdev)) return 0; assert(!w->unresolved_endpoints); @@ -260,8 +259,7 @@ static int wireguard_resolve_handler(sd_resolve_query *q, w = WIREGUARD(netdev); assert(w); - if (!netdev->manager) - /* The netdev is detached. */ + if (!netdev_is_managed(netdev)) return 0; if (ret != 0) { diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 5353b9daaf..3661498f39 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -517,8 +517,6 @@ static void link_detach_from_manager(Link *link) { hashmap_remove(link->manager->links, INT_TO_PTR(link->ifindex)); set_remove(link->manager->links_requesting_uuid, link); link_clean(link); - - link->manager = NULL; } static Link *link_free(Link *link) { |