title: Executing mount system call from perl
body: <p>How can the <code>mount</code> system call be done from perl? The following:</p>
  
  <pre><code>$ret = syscall(&amp;SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0);
  </code></pre>
  
  <p>results in:</p>
  
  <pre><code>Modification of a read-only value attempted at ...
  </code></pre>
  
  <p>I cannot call the <code>mount</code> program using <code>system</code> because I need to make a <code>mount()</code> system call that the <code>mount</code> program doesn't seem to be capable of. More specifically, I need to call:</p>
  
  <pre><code>mount("/proc", "/path/to/my/mpoint/point", NULL, MS_REC|MS_PRIVATE|MS_BIND, NULL);
  </code></pre>
  
  <p>But if I try to run the following with an unprivileged unshared mount linux namespace:</p>
  
  <pre><code>mount --make-rprivate --bind /proc /path/to/my/mountpoint
  </code></pre>
  
  <p>Then I get the following error:</p>
  
  <pre><code>mount: wrong fs type, bad option, bad superblock on /proc,
         missing codepage or helper program, or other error
  
         In some cases useful info is found in syslog - try
         dmesg | tail or so.
  </code></pre>
  
  <p>Using <code>strace</code> reveals that what the <code>mount</code> program actually does is to call:</p>
  
  <pre><code>mount("/proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND, NULL);
  mount("none", "/path/to/my/mointpoint", NULL, MS_REC|MS_PRIVATE, NULL);
  </code></pre>
  
  <p>But this splitting of options does not work. I need <code>MS_BIND</code> and <code>MS_REC|MS_PRIVATE</code> in a single call to the <code>mount</code> system call for it to work in an unprivileged unshared mount namespace.</p>
  
  <p>So how can I do my initial system call in perl without the error message about an attempt of a modification of a read-only value?</p>
  
  <p><strong>edit</strong>:</p>
  
  <p>Thankfully ikegami was quick to point out what i did wrong when trying to use perl's <code>syscall</code> function but in case somebody finds this when searching for how to bind mount a directory from within an unprivileged mount namespace with just the <code>mount</code> command line utility, here is how:</p>
  
  <pre><code>mount --rbind /proc /path/to/my/mountpoint
  </code></pre>
  
  <p>This in turn will call the following syscall internally:</p>
  
  <pre><code>mount("proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND|MS_REC, 0);
  </code></pre>
  
  <p>The <code>MS_MGC_VAL</code> flag just seems to be for backwards compatibility with kernel versions prior to 2.4. The important bits are <code>MS_BIND</code> (for doing the bind mounting itself) and <code>MS_REC</code> (for doing it recursively so that directories that have their content hidden by other mounts being done into them do not have their content exposed in the mount namespace).</p>
  
  <p>So now I have to decide whether I go with a perl <code>system</code> function call or just do the <code>mount</code> systemcall because both work just as well :)</p>