chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
networkd: manager - refactor link tracking a bit
[elogind.git]
/
src
/
network
/
networkd-netdev.c
diff --git
a/src/network/networkd-netdev.c
b/src/network/networkd-netdev.c
index 961404295d7c4a20690825c9c7d6fdcff90ca790..7962cc6c6a75a36c32503ef6ac634193792e2ab7 100644
(file)
--- 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");
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;
netdev_enslave_callback *callback;
if (!netdev)
return;
+ rtnl_message_new_synthetic_error(-ENODEV, 0, &m);
+
while ((callback = netdev->callbacks)) {
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);
}
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);
if (netdev->name)
hashmap_remove(netdev->manager->netdevs, netdev->name);
@@
-89,6
+108,21
@@
NetDev *netdev_ref(NetDev *netdev) {
return 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;
int netdev_get(Manager *manager, const char *name, NetDev **ret) {
NetDev *netdev;
@@
-168,7
+202,7
@@
static int netdev_enter_ready(NetDev *netdev) {
log_info_netdev(netdev, "netdev ready");
LIST_FOREACH(callbacks, callback, netdev->callbacks) {
log_info_netdev(netdev, "netdev ready");
LIST_FOREACH(callbacks, callback, netdev->callbacks) {
- /* enslave the links that were attempted to be enslaved befor the
+ /* enslave the links that were attempted to be enslaved befor
e
the
* link was ready */
netdev_enslave_ready(netdev, callback->link, callback->callback);
}
* link was ready */
netdev_enslave_ready(netdev, callback->link, callback->callback);
}
@@
-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) {
if (r == -EEXIST)
log_debug_netdev(netdev, "netdev exists, using existing");
else if (r < 0) {
- log_warning_netdev(netdev, "netdev
fail
ed: %s", strerror(-r));
- netdev_
enter_failed
(netdev);
+ log_warning_netdev(netdev, "netdev
could not be great
ed: %s", strerror(-r));
+ netdev_
drop
(netdev);
return 1;
}
return 1;
}
@@
-308,11
+342,15
@@
static int netdev_create(NetDev *netdev, Link *link, sd_rtnl_message_handler_t c
}
int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
}
int netdev_enslave(NetDev *netdev, Link *link, sd_rtnl_message_handler_t callback) {
+ int r;
+
if (netdev->kind == NETDEV_KIND_VLAN || netdev->kind == NETDEV_KIND_MACVLAN)
return netdev_create(netdev, link, callback);
if (netdev->state == NETDEV_STATE_READY) {
if (netdev->kind == NETDEV_KIND_VLAN || netdev->kind == NETDEV_KIND_MACVLAN)
return netdev_create(netdev, link, callback);
if (netdev->state == NETDEV_STATE_READY) {
- netdev_enslave_ready(netdev, link, callback);
+ r = netdev_enslave_ready(netdev, link, callback);
+ if (r < 0)
+ return r;
} else {
/* the netdev is not yet read, save this request for when it is*/
netdev_enslave_callback *cb;
} else {
/* the netdev is not yet read, save this request for when it is*/
netdev_enslave_callback *cb;