From 54615659458432f3479f8503ccb6cea66fcfdcd6 Mon Sep 17 00:00:00 2001
From: Rich Lane <rlane@bigswitch.com>
Date: Sun, 17 Nov 2013 22:38:30 -0800
Subject: [PATCH] mnexec: mount sysfs in each container

The sysfs filesystem is [tagged][1] with a set of namespaces when mounted, taken
from the mounting process. Among other things, this controls which network
devices will show up in /sys/class/net and /sys/class/net/bonding_masters.

Without this change, mininet will not mount sysfs in a node. Attempting to
configure a bond interface in a node will only affect the parent namespace.

This change mounts a new sysfs filesystem in each node. To prevent this mount
from affecting the parent namespace the mount namespace is also unshared.

[1]: https://www.kernel.org/doc/Documentation/filesystems/sysfs-tagging.txt
---
 mnexec.c | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/mnexec.c b/mnexec.c
index b7be9bc1..fee3d250 100644
--- a/mnexec.c
+++ b/mnexec.c
@@ -5,7 +5,7 @@
  *
  *  - closing all file descriptors except stdin/out/error
  *  - detaching from a controlling tty using setsid
- *  - running in a network namespace
+ *  - running in network and mount namespaces
  *  - printing out the pid of a process so we can identify it later
  *  - attaching to a namespace and cgroup
  *  - setting RT scheduling
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <sched.h>
 #include <ctype.h>
+#include <sys/mount.h>
 
 #if !defined(VERSION)
 #define VERSION "(devel)"
@@ -35,9 +36,9 @@ void usage(char *name)
            "Options:\n"
            "  -c: close all file descriptors except stdin/out/error\n"
            "  -d: detach from tty by calling setsid()\n"
-           "  -n: run in new network namespace\n"
+           "  -n: run in new network and mount namespaces\n"
            "  -p: print ^A + pid\n"
-           "  -a pid: attach to pid's network namespace\n"
+           "  -a pid: attach to pid's network and mount namespaces\n"
            "  -g group: add to cgroup\n"
            "  -r rtprio: run with SCHED_RR (usually requires -g)\n"
            "  -v: print version\n",
@@ -122,11 +123,16 @@ int main(int argc, char *argv[])
             setsid();
             break;
         case 'n':
-            /* run in network namespace */
-            if (unshare(CLONE_NEWNET) == -1) {
+            /* run in network and mount namespaces */
+            if (unshare(CLONE_NEWNET|CLONE_NEWNS) == -1) {
                 perror("unshare");
                 return 1;
             }
+            /* mount sysfs to pick up the new network namespace */
+            if (mount("sysfs", "/sys", "sysfs", MS_MGC_VAL, NULL) == -1) {
+                perror("mount");
+                return 1;
+            }
             break;
         case 'p':
             /* print pid */
-- 
GitLab