title: golang mount namespace: mounted volume are not cleared after the process exits?
body: <p>code below, I thought if I starts a process with syscall.CLONE_NEWNS, every mount option inside the namespace will be cleared when the process exits. </p>
  
  <p>but it is not? </p>
  
  <pre><code>package main
  import (
          "fmt"
          "os"
          "os/exec"
          "syscall"
  )
  
  var command string = "/usr/bin/bash"
  
  func container_command() {
  
          fmt.Printf("starting container command %s\n", command)
          cmd := exec.Command(command)
          cmd.SysProcAttr = &amp;syscall.SysProcAttr{Cloneflags: syscall.CLONE_NEWPID |
                  syscall.CLONE_NEWNS,
          }
          cmd.Stdin = os.Stdin
          cmd.Stdout = os.Stdout
          cmd.Stderr = os.Stderr
  
          if err := cmd.Run(); err != nil {
                  fmt.Println("error", err)
                  os.Exit(1)
          }
  }
  
  func main() {
          fmt.Printf("starting current process %d\n", os.Getpid())
          container_command()
          fmt.Printf("command ended\n")
  
  }
  </code></pre>
  
  <p>run this and mount a directory, this directory still exits after the program exits. </p>
  
  <pre><code>[root@localhost go]# go run namespace-1.go
  starting current process 7558
  starting container command /usr/bin/bash
  [root@ns-process go]# mount --bind /home /mnt
  [root@ns-process go]# ls /mnt
  vagrant
  [root@ns-process go]# exit
  exit
  command ended
  [root@localhost go]# ls /mnt
  vagrant
  [root@localhost go]#
  </code></pre>
  
  <p>if this is the desired behavior, how is the proc get mounted in container implementations? because if I mount proc inside the namespace, I will get </p>
  
  <pre><code>[root@ns-process go]# mount -t proc /proc
  [root@ns-process go]# exit
  exit
  command ended
  [root@localhost go]# mount
  mount: failed to read mtab: No such file or directory
  [root@localhost go]#
  </code></pre>
  
  <p>proc has to be remounted to get it back. </p>
  
  <p>update: 
  doing the same in C also gives the same result, I think this should be a intended behavior. </p>
  
  <pre><code>#define _GNU_SOURCE
  #include &lt;sys/types.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;sched.h&gt;
  #include &lt;signal.h&gt;
  #include &lt;unistd.h&gt;
  
  #define STACK_SIZE (1024 * 1024)
  static char container_stack[STACK_SIZE];
  
  char* const container_args[] = {
      "/bin/bash",
      NULL
  };
  
  int container_main(void* arg)
  {
          printf("Container [%5d] - inside the container!\n", getpid());
              sethostname("container",10);
              system("mount -t proc proc /proc");
              execv(container_args[0], container_args);
              printf("Something's wrong!\n");
              return 1;
  }
  
  int main()
  {
      printf("start a container!\n");
      int container_pid = clone(container_main, container_stack+STACK_SIZE,
              CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL);
      waitpid(container_pid, NULL, 0);
      printf("container ended!\n");
      return 0;
  }
  </code></pre>
  
  <p>command output:</p>
  
  <pre><code>[root@localhost ~]# gcc a.c
  [root@localhost ~]# ./a.out
  start a container!
  Container [    1] - inside the container!
  [root@container ~]# ps -ef
  UID        PID  PPID  C STIME TTY          TIME CMD
  root         1     0  0 08:57 pts/0    00:00:00 /bin/bash
  root        17     1  0 08:57 pts/0    00:00:00 ps -ef
  [root@container ~]# exit
  exit
  container stopped!
  [root@localhost ~]# ps -ef
  Error, do this: mount -t proc proc /proc
  [root@localhost ~]# cat a.c
  </code></pre>