title: Mount system call not working with MS_PRIVATE flag
body: <p>We are trying to learn how to build a container-like application on Linux (I'm using Ubuntu 20.04).</p>
  <p>We've fetched an Ubuntu file system with the following command:</p>
  <pre><code>sudo debootstrap --variant=minbase bionic /home/some/path/ubuntu_fs http://ftp.heanet.ie/pub/ubuntu/
  </code></pre>
  <p>Here's what we are doing at the moment:</p>
  <pre><code>#include &lt;bits/stdc++.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sched.h&gt;
  #include &lt;sys/wait.h&gt;
  #include &lt;sys/mount.h&gt;
  
  using namespace std;
  
  
  #define STACK_SIZE (1024 * 1024)
  #define CHROOT_PATH &quot;/home/some/path/ubuntu_fs&quot;
  
  struct ChildArgs{
      char ** argv;
  };
  
  
  
  int child(void* args)
  {
      sethostname(&quot;conman&quot;, 6);   
      chroot(CHROOT_PATH);
      chdir(&quot;/&quot;);
  
      ChildArgs* child_args = static_cast&lt;ChildArgs*&gt;(args);
  
      // Removing the `if` block immediately below makes the program run fine
      if(mount(&quot;&quot;, &quot;/&quot;, &quot;&quot;, MS_PRIVATE | MS_REC, NULL))
      {
          perror(&quot;Mount failed\n&quot;);
          return errno;
      }
  
      if(mount(&quot;proc&quot;, &quot;/proc&quot;, &quot;proc&quot;, 0, NULL))
      {
          perror(&quot;Mount failed\n&quot;);
          return errno;
      }
  
      pid_t fork_pid = fork();
      if(fork_pid &lt; 0)
          return EXIT_FAILURE;
  
      else if(fork_pid == 0)
      {
  
          execvp(child_args-&gt;argv[0], child_args-&gt;argv);
      }
  
      else
      {
          waitpid(fork_pid, NULL, 0);
          umount(&quot;/proc&quot;);
          umount(&quot;/&quot;);
      }
      return 0;
  }
  
  int main(int argc, char *argv[])
  {
      static char child_stack[STACK_SIZE];
  
      int flags = CLONE_NEWUTS | CLONE_NEWNS | CLONE_NEWPID | SIGCHLD;
  
      ChildArgs child_args {&amp;argv[1]};
      pid_t childpid = clone(child, child_stack + STACK_SIZE, flags, &amp;child_args);
  
      if(waitpid(childpid, NULL, 0) == -1)
      {   
          perror(&quot;Error&quot;);
          exit(EXIT_FAILURE);
      }
  
      return 0;
  }
  </code></pre>
  <p>The reason we want to mount the chroot directory as private is that we do not want mounts in the child mount namespace to propagate to any other namespace. If we do not do this, any mounts in the new namespace inherit the <code>MS_SHARED</code> mount type from the parent mount, and are hence visible in the parent namespace. <a href="https://stackoverflow.com/questions/41561136/unshare-mount-namespace-not-working-as-expected">This SO answer</a> also recommends doing the same.</p>
  <p>However, executing our code returns the following error:</p>
  <pre><code>Mount failed: Invalid argument
  </code></pre>
  <p>Changing the <code>MS_PRIVATE | MS_REC</code> to <code>0</code> returns the following:</p>
  <pre><code>Mount failed: No such device
  </code></pre>
  <p><strong>Only</strong> mounting <code>/proc</code> and <code>/sys</code> in the <code>chroot</code> directory works fine, but are visible from the parent namespaces <em>(as expected)</em>.</p>
  <p>Any suggestions on how to make the mounts private would be very helpful.</p>