123 lines
4.2 KiB
Diff
123 lines
4.2 KiB
Diff
From e4103cf63f3e24667680544303e7c7230b3d508c Mon Sep 17 00:00:00 2001
|
|
From: Thomas Parrott <thomas.parrott@canonical.com>
|
|
Date: Fri, 26 Jul 2019 16:14:18 +0100
|
|
Subject: [PATCH] lxccontainer: do_lxcapi_detach_interface to support detaching
|
|
wlan devices
|
|
|
|
Signed-off-by: Thomas Parrott <thomas.parrott@canonical.com>
|
|
---
|
|
src/lxc/attach.c | 2 +-
|
|
src/lxc/attach.h | 2 ++
|
|
src/lxc/lxccontainer.c | 23 ++++++++++++++++++++++-
|
|
src/lxc/network.c | 4 ++--
|
|
src/lxc/network.h | 4 ++++
|
|
5 files changed, 31 insertions(+), 4 deletions(-)
|
|
|
|
diff --git src/lxc/attach.c src/lxc/attach.c
|
|
index 867aa91c0d..f63331edec 100644
|
|
--- src/lxc/attach.c
|
|
+++ src/lxc/attach.c
|
|
@@ -213,7 +213,7 @@ static int lxc_attach_to_ns(pid_t pid, struct lxc_proc_context_info *ctx)
|
|
return 0;
|
|
}
|
|
|
|
-static int lxc_attach_remount_sys_proc(void)
|
|
+int lxc_attach_remount_sys_proc(void)
|
|
{
|
|
int ret;
|
|
|
|
diff --git src/lxc/attach.h src/lxc/attach.h
|
|
index c576aa9fca..ce7c461b33 100644
|
|
--- src/lxc/attach.h
|
|
+++ src/lxc/attach.h
|
|
@@ -45,4 +45,6 @@ extern int lxc_attach(struct lxc_container *container,
|
|
lxc_attach_exec_t exec_function, void *exec_payload,
|
|
lxc_attach_options_t *options, pid_t *attached_process);
|
|
|
|
+extern int lxc_attach_remount_sys_proc(void);
|
|
+
|
|
#endif /* __LXC_ATTACH_H */
|
|
diff --git src/lxc/lxccontainer.c src/lxc/lxccontainer.c
|
|
index d8efdc41c6..52c38fd330 100644
|
|
--- src/lxc/lxccontainer.c
|
|
+++ src/lxc/lxccontainer.c
|
|
@@ -4793,6 +4793,7 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
|
|
{
|
|
int ret;
|
|
pid_t pid, pid_outside;
|
|
+ __do_free char *physname = NULL;
|
|
|
|
/*
|
|
* TODO - if this is a physical device, then we need am_host_unpriv.
|
|
@@ -4828,6 +4829,19 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
|
|
_exit(EXIT_FAILURE);
|
|
}
|
|
|
|
+ /* create new mount namespace for use with remounting /sys and is_wlan() below. */
|
|
+ ret = unshare(CLONE_NEWNS);
|
|
+ if (ret < 0) {
|
|
+ ERROR("Failed to unshare mount namespace");
|
|
+ _exit(EXIT_FAILURE);
|
|
+ }
|
|
+
|
|
+ /* set / recursively as private so that mount propagation doesn't affect us. */
|
|
+ if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0) < 0) {
|
|
+ ERROR("Failed to recursively set / as private in mount namespace");
|
|
+ _exit(EXIT_FAILURE);
|
|
+ }
|
|
+
|
|
ret = lxc_netdev_isup(ifname);
|
|
if (ret < 0) {
|
|
ERROR("Failed to determine whether network device \"%s\" is up", ifname);
|
|
@@ -4843,7 +4857,14 @@ static bool do_lxcapi_detach_interface(struct lxc_container *c,
|
|
}
|
|
}
|
|
|
|
- ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname);
|
|
+ /* remount /sys so is_wlan() can check if this device is a wlan device. */
|
|
+ lxc_attach_remount_sys_proc();
|
|
+ physname = is_wlan(ifname);
|
|
+ if (physname)
|
|
+ ret = lxc_netdev_move_wlan(physname, ifname, pid_outside, dst_ifname);
|
|
+ else
|
|
+ ret = lxc_netdev_move_by_name(ifname, pid_outside, dst_ifname);
|
|
+
|
|
/* -EINVAL means there is no netdev named as ifname. */
|
|
if (ret < 0) {
|
|
if (ret == -EINVAL)
|
|
diff --git src/lxc/network.c src/lxc/network.c
|
|
index 7684f95918..65727f6b5a 100644
|
|
--- src/lxc/network.c
|
|
+++ src/lxc/network.c
|
|
@@ -1172,7 +1172,7 @@ int lxc_netdev_move_by_index(int ifindex, pid_t pid, const char *ifname)
|
|
* will be passed to lxc_netdev_move_wlan() which will free it when done.
|
|
*/
|
|
#define PHYSNAME "/sys/class/net/%s/phy80211/name"
|
|
-static char *is_wlan(const char *ifname)
|
|
+char *is_wlan(const char *ifname)
|
|
{
|
|
__do_free char *path = NULL;
|
|
int i, ret;
|
|
@@ -1245,7 +1245,7 @@ static int lxc_netdev_rename_by_name_in_netns(pid_t pid, const char *old,
|
|
_exit(lxc_netdev_rename_by_name(old, new));
|
|
}
|
|
|
|
-static int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
|
|
+int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
|
|
const char *newname)
|
|
{
|
|
__do_free char *cmd = NULL;
|
|
diff --git src/lxc/network.h src/lxc/network.h
|
|
index acfd8a0532..8a86768d9e 100644
|
|
--- src/lxc/network.h
|
|
+++ src/lxc/network.h
|
|
@@ -293,4 +293,8 @@ extern int lxc_netns_set_nsid(int netns_fd);
|
|
extern int lxc_netns_get_nsid(__s32 fd);
|
|
extern int lxc_create_network(struct lxc_handler *handler);
|
|
|
|
+extern char *is_wlan(const char *ifname);
|
|
+extern int lxc_netdev_move_wlan(char *physname, const char *ifname, pid_t pid,
|
|
+ const char *newname);
|
|
+
|
|
#endif /* __LXC_NETWORK_H */
|