network: add destroy callbacks for asynchronous netlink calls

This commit is contained in:
Yu Watanabe
2018-10-10 14:43:05 +09:00
parent 0d0f02cd15
commit 1046bf9b1a
18 changed files with 131 additions and 105 deletions
+3 -2
View File
@@ -10,7 +10,7 @@
/* callback for brige netdev's parameter set */
static int netdev_bridge_set_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_(netdev_unrefp) NetDev *netdev = userdata;
NetDev *netdev = userdata;
int r;
assert(netdev);
@@ -129,7 +129,8 @@ static int netdev_bridge_post_create(NetDev *netdev, Link *link, sd_netlink_mess
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler, NULL, netdev, 0, NULL);
r = sd_netlink_call_async(netdev->manager->rtnl, req, netdev_bridge_set_handler,
netdev_netlink_destroy_callback, netdev, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
+4 -3
View File
@@ -18,9 +18,10 @@
/* callback for geneve netdev's created without a backing Link */
static int geneve_netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_(netdev_unrefp) NetDev *netdev = userdata;
NetDev *netdev = userdata;
int r;
assert(netdev);
assert(netdev->state != _NETDEV_STATE_INVALID);
r = sd_netlink_message_get_errno(m);
@@ -135,12 +136,12 @@ static int netdev_geneve_create(NetDev *netdev) {
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler, NULL, netdev, 0, NULL);
r = sd_netlink_call_async(netdev->manager->rtnl, m, geneve_netdev_create_handler,
netdev_netlink_destroy_callback, netdev, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
netdev_ref(netdev);
netdev->state = NETDEV_STATE_CREATING;
log_netdev_debug(netdev, "Creating");
+22 -23
View File
@@ -99,25 +99,13 @@ static const char* const netdev_kind_table[_NETDEV_KIND_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(netdev_kind, NetDevKind);
DEFINE_CONFIG_PARSE_ENUM(config_parse_netdev_kind, netdev_kind, NetDevKind, "Failed to parse netdev kind");
static void netdev_cancel_callbacks(NetDev *netdev) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
static void netdev_callbacks_clear(NetDev *netdev) {
netdev_join_callback *callback;
if (!netdev || !netdev->manager)
if (!netdev)
return;
rtnl_message_new_synthetic_error(netdev->manager->rtnl, -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, callback->link);
}
LIST_REMOVE(callbacks, netdev->callbacks, callback);
link_unref(callback->link);
free(callback);
@@ -127,7 +115,7 @@ static void netdev_cancel_callbacks(NetDev *netdev) {
static NetDev *netdev_free(NetDev *netdev) {
assert(netdev);
netdev_cancel_callbacks(netdev);
netdev_callbacks_clear(netdev);
if (netdev->ifname && netdev->manager)
hashmap_remove(netdev->manager->netdevs, netdev->ifname);
@@ -161,6 +149,14 @@ static NetDev *netdev_free(NetDev *netdev) {
DEFINE_TRIVIAL_REF_UNREF_FUNC(NetDev, netdev, netdev_free);
void netdev_netlink_destroy_callback(void *userdata) {
NetDev *netdev = userdata;
assert(userdata);
netdev_unref(netdev);
}
void netdev_drop(NetDev *netdev) {
if (!netdev || netdev->state == NETDEV_STATE_LINGER)
return;
@@ -169,7 +165,7 @@ void netdev_drop(NetDev *netdev) {
log_netdev_debug(netdev, "netdev removed");
netdev_cancel_callbacks(netdev);
netdev_callbacks_clear(netdev);
netdev_unref(netdev);
@@ -197,7 +193,7 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret) {
static int netdev_enter_failed(NetDev *netdev) {
netdev->state = NETDEV_STATE_FAILED;
netdev_cancel_callbacks(netdev);
netdev_callbacks_clear(netdev);
return 0;
}
@@ -229,7 +225,8 @@ static int netdev_enslave_ready(NetDev *netdev, Link* link, sd_netlink_message_h
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MASTER attribute: %m");
r = sd_netlink_call_async(netdev->manager->rtnl, req, callback, NULL, link, 0, NULL);
r = sd_netlink_call_async(netdev->manager->rtnl, req, callback,
link_netlink_destroy_callback, link, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
@@ -274,9 +271,10 @@ static int netdev_enter_ready(NetDev *netdev) {
/* callback for netdev's created without a backing Link */
static int netdev_create_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
_cleanup_(netdev_unrefp) NetDev *netdev = userdata;
NetDev *netdev = userdata;
int r;
assert(netdev);
assert(netdev->state != _NETDEV_STATE_INVALID);
r = sd_netlink_message_get_errno(m);
@@ -321,8 +319,7 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call
return log_oom();
cb->callback = callback;
cb->link = link;
link_ref(link);
cb->link = link_ref(link);
LIST_PREPEND(callbacks, netdev->callbacks, cb);
@@ -537,13 +534,15 @@ static int netdev_create(NetDev *netdev, Link *link,
return log_netdev_error_errno(netdev, r, "Could not append IFLA_LINKINFO attribute: %m");
if (link) {
r = sd_netlink_call_async(netdev->manager->rtnl, m, callback, NULL, link, 0, NULL);
r = sd_netlink_call_async(netdev->manager->rtnl, m, callback,
link_netlink_destroy_callback, link, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
link_ref(link);
} else {
r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler, NULL, netdev, 0, NULL);
r = sd_netlink_call_async(netdev->manager->rtnl, m, netdev_create_handler,
netdev_netlink_destroy_callback, netdev, 0, NULL);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not send rtnetlink message: %m");
+1 -1
View File
@@ -150,7 +150,7 @@ void netdev_drop(NetDev *netdev);
NetDev *netdev_unref(NetDev *netdev);
NetDev *netdev_ref(NetDev *netdev);
void netdev_netlink_destroy_callback(void *userdata);
DEFINE_TRIVIAL_CLEANUP_FUNC(NetDev*, netdev_unref);
int netdev_get(Manager *manager, const char *name, NetDev **ret);