title: How does `ip netns exec` command create mount namespace?
body: <p>How does <code>ip netns exec</code> command create a mount namespace and prevent the changes from being propagated to other mount namespaces?</p>
  
  <p>Following is the from the man page of <code>ip-netns</code>:</p>
  
  <blockquote>
    <p>For applications that are aware of network namespaces, the convention
    is to look for global network configuration files first in
    /etc/netns/NAME/ then in /etc/. For example, if you want a different
    version of /etc/resolv.conf for a network namespace used to isolate
    your vpn you would name it /etc/netns/myvpn/resolv.conf.</p>
    
    <p>ip netns exec automates handling of this configuration, file
    convention for network namespace unaware applications, by creating a
    mount namespace and bind mounting all of the per network namespace
    configure files into their traditional location in /etc.</p>
  </blockquote>
  
  <p>But, how does it manage the bind mount being visible only in that particular namespace?</p>
  
  <p>Let me show an example.
  In one terminal, I create a network namespace ns3, and create a specific resolv.conf for ns3.</p>
  
  <pre><code># ip netns add ns3
  # mkdir /etc/netns/ns3
  # echo "ns3 conf" &gt; /etc/netns/ns3/resolv.conf
  # ip netns exec ns3 sleep 36000
  </code></pre>
  
  <p>Now in another terminal, I examine the /etc/resolv.conf.</p>
  
  <pre><code># cat /etc/resolv.conf
  default conf
  </code></pre>
  
  <p>The change made by the bind mount is not reflected here.
  The change is visible, only if i enter the mount namespace created by the <code>ip netns</code> command.</p>
  
  <pre><code># lsns | grep mnt
  4026533472 mnt        1 13016 root             sleep 36000
  # nsenter -m -t 13016
  # cat /etc/resolv.conf
  ns3 conf
  </code></pre>
  
  <p>So all works as expected.</p>
  
  <p>Now let me try to do this directly with <code>unshare</code> command, instead of using <code>ip netns exec</code>.</p>
  
  <p>I create a namespace again. With <code>unshare</code>, I am creating a mount namespace and doing the bind mount inside that mount namespace. I assume this is what <code>ip netns exec</code> command internally does.</p>
  
  <pre><code># ip netns add ns4
  # mkdir /etc/netns/ns4
  # echo "ns4 conf" &gt; /etc/netns/ns4/resolv.conf
  # unshare -m --propagation unchanged /bin/bash
  # mount --bind /etc/netns/ns4/resolv.conf /etc/resolv.conf
  </code></pre>
  
  <p>But this time when I check from another terminal, the changes have been propagated back which is not desired. </p>
  
  <pre><code># cat /etc/resolv.conf
  ns4 conf
  </code></pre>
  
  <p>So what is the additional step that <code>ip netns exec</code> does which prevent this propagation of changes? I assume it is related to the usage <code>make-shared</code> or <code>make-slave</code> flags, but couldn't figure out exactly.</p>