network: make Link and NetDev always have the valid poiter to Manager

c4397d94c3 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.
This commit is contained in:
Yu Watanabe 2019-01-14 00:30:37 +09:00 committed by Zbigniew Jędrzejewski-Szmek
parent 50198038c8
commit 9e2bbf9915
4 changed files with 10 additions and 8 deletions

View file

@ -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) {

View file

@ -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);

View file

@ -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) {

View file

@ -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) {