X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fnetwork%2Fnetworkd-netdev.c;h=7962cc6c6a75a36c32503ef6ac634193792e2ab7;hb=4d473d5dded03d3b682dc389d610bb6b2db6e5f7;hp=5ee257f984b815a97e3a2a4896acccf8fc200e13;hpb=b226d99b044222739dccfa9cf9f7a9d79576c407;p=elogind.git diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index 5ee257f98..7962cc6c6 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -48,16 +48,35 @@ static const char* const macvlan_mode_table[_NETDEV_MACVLAN_MODE_MAX] = { DEFINE_STRING_TABLE_LOOKUP(macvlan_mode, MacVlanMode); DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode"); -static void netdev_free(NetDev *netdev) { +static void netdev_cancel_callbacks(NetDev *netdev) { + _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL; netdev_enslave_callback *callback; if (!netdev) return; + rtnl_message_new_synthetic_error(-ENODEV, 0, &m); + while ((callback = netdev->callbacks)) { + if (m) { + assert(callback->link); + assert(callback->callback); + assert(netdev->manager); + assert(netdev->manager->rtnl); + + callback->callback(netdev->manager->rtnl, m, link); + } + LIST_REMOVE(callbacks, netdev->callbacks, callback); free(callback); } +} + +static void netdev_free(NetDev *netdev) { + if (!netdev) + return; + + netdev_cancel_callbacks(netdev); if (netdev->name) hashmap_remove(netdev->manager->netdevs, netdev->name); @@ -89,6 +108,21 @@ NetDev *netdev_ref(NetDev *netdev) { return netdev; } +void netdev_drop(NetDev *netdev) { + if (!netdev || netdev->state == NETDEV_STATE_LINGER) + return; + + netdev->state = NETDEV_STATE_LINGER; + + log_debug_netdev(netdev, "dropped"); + + netdev_cancel_callbacks(netdev); + + netdev_unref(netdev); + + return; +} + int netdev_get(Manager *manager, const char *name, NetDev **ret) { NetDev *netdev; @@ -185,8 +219,8 @@ static int netdev_create_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userda if (r == -EEXIST) log_debug_netdev(netdev, "netdev exists, using existing"); else if (r < 0) { - log_warning_netdev(netdev, "netdev failed: %s", strerror(-r)); - netdev_enter_failed(netdev); + log_warning_netdev(netdev, "netdev could not be greated: %s", strerror(-r)); + netdev_drop(netdev); return 1; }