nspawn: explicitly remove veth links after use (#3111)

* sd-netlink: permit RTM_DELLINK messages with no ifindex

This is useful for removing network interfaces by name.

* nspawn: explicitly remove veth links we created after use

Sometimes the kernel keeps veth links pinned after the namespace they have been
joined to died. Let's hence explicitly remove veth links after use.

Fixes: #2173
This commit is contained in:
Lennart Poettering 2016-04-25 17:36:51 +02:00 committed by Daniel Mack
parent 4f4d6ee4be
commit d2773e59de
4 changed files with 51 additions and 1 deletions

View File

@ -402,7 +402,6 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
int r;
assert_return(rtnl_message_type_is_link(nlmsg_type), -EINVAL);
assert_return(nlmsg_type != RTM_DELLINK || index > 0, -EINVAL);
assert_return(ret, -EINVAL);
r = message_new(rtnl, ret, nlmsg_type);

View File

@ -538,3 +538,50 @@ int veth_extra_parse(char ***l, const char *p) {
a = b = NULL;
return 0;
}
static int remove_one_veth_link(sd_netlink *rtnl, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r;
if (isempty(name))
return 0;
r = sd_rtnl_message_new_link(rtnl, &m, RTM_DELLINK, 0);
if (r < 0)
return log_error_errno(r, "Failed to allocate netlink message: %m");
r = sd_netlink_message_append_string(m, IFLA_IFNAME, name);
if (r < 0)
return log_error_errno(r, "Failed to add netlink interface name: %m");
r = sd_netlink_call(rtnl, m, 0, NULL);
if (r == -ENODEV) /* Already gone */
return 0;
if (r < 0)
return log_error_errno(r, "Failed to remove veth interface %s: %m", name);
return 1;
}
int remove_veth_links(const char *primary, char **pairs) {
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
char **a, **b;
int r;
/* In some cases the kernel might pin the veth links between host and container even after the namespace
* died. Hence, let's better remove them explicitly too. */
if (isempty(primary) && strv_isempty(pairs))
return 0;
r = sd_netlink_open(&rtnl);
if (r < 0)
return log_error_errno(r, "Failed to connect to netlink: %m");
remove_one_veth_link(rtnl, primary);
STRV_FOREACH_PAIR(a, b, pairs)
remove_one_veth_link(rtnl, *a);
return 0;
}

View File

@ -34,3 +34,5 @@ int setup_ipvlan(const char *machine_name, pid_t pid, char **ifaces);
int move_network_interfaces(pid_t pid, char **ifaces);
int veth_extra_parse(char ***l, const char *p);
int remove_veth_links(const char *primary, char **pairs);

View File

@ -3713,6 +3713,7 @@ int main(int argc, char *argv[]) {
}
expose_port_flush(arg_expose_ports, &exposed);
(void) remove_veth_links(veth_name, arg_network_veth_extra);
}
finish:
@ -3745,6 +3746,7 @@ finish:
}
expose_port_flush(arg_expose_ports, &exposed);
(void) remove_veth_links(veth_name, arg_network_veth_extra);
free(arg_directory);
free(arg_template);