]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
lxccontainer: do_lxcapi_detach_interface to support detaching wlan devices 3107/head
authorThomas Parrott <thomas.parrott@canonical.com>
Fri, 26 Jul 2019 15:14:18 +0000 (16:14 +0100)
committerThomas Parrott <thomas.parrott@canonical.com>
Mon, 29 Jul 2019 15:54:27 +0000 (16:54 +0100)
Signed-off-by: Thomas Parrott <thomas.parrott@canonical.com>
src/lxc/attach.c
src/lxc/attach.h
src/lxc/lxccontainer.c
src/lxc/network.c
src/lxc/network.h

index 867aa91c0dea7b8f5ddf94d152c60220f1b48f48..f63331edec952129a2c8d56c1fea8c56f7fd4ec3 100644 (file)
@@ -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;
 
index c576aa9fcaac9b201da01d02efca9521a5f488b5..ce7c461b333fbb4e04cbe82fd7f93f702f599b32 100644 (file)
@@ -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 */
index d8efdc41c673a737741fc35718ab6879a01e8957..52c38fd330bbd4fe90efe353bc2569a6cd93d90f 100644 (file)
@@ -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)
index 7684f959186d074b3ef2971d9490cd80ffaf0f8c..65727f6b5aecb7ef4febbb1efa86ffc990a4b019 100644 (file)
@@ -1172,7 +1172,7 @@ out:
  * 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;
index acfd8a05325bbab4268c98522f856d162deb08f7..8a86768d9e02f634e5aff9ac5bfcbcbac98caf2e 100644 (file)
@@ -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 */