How can I make the mount system call from perl? Following:
$ret = syscall(&SYS_mount, "/proc", "/path/to/my/mount/point", 0, 0, 0);
leads to:
Modification of a read-only value attempted at ...
I cannot call the mount program using system , because I need to make a mount() system call, which apparently does not support the mount program. In particular, I need to call:
mount("/proc", "/path/to/my/mpoint/point", NULL, MS_REC|MS_PRIVATE|MS_BIND, NULL);
But if I try to run the following with an unprivileged namespace without mounting mount:
mount --make-rprivate --bind /proc /path/to/my/mountpoint
Then I get the following error:
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.
Using strace shows that mount is actually making a call:
mount("/proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND, NULL); mount("none", "/path/to/my/mointpoint", NULL, MS_REC|MS_PRIVATE, NULL);
But this separation of options does not work. I need MS_BIND and MS_REC|MS_PRIVATE in one call to the mount system call so that it works in an unprivileged namespace without access.
So, how can I make my initial system call in perl without an error message about trying to change a read-only value?
change
Fortunately, ikegami quickly pointed out what I did wrong when I try to use the perl syscall function, but in case someone finds it when you are looking for how to associate a directory mount from an unprivileged mount namespace only with the mount command utility lines, here's how:
mount --rbind /proc /path/to/my/mountpoint
This, in turn, will cause the following system call internally:
mount("proc", "/path/to/my/mountpoint", ..., MS_MGC_VAL|MS_BIND|MS_REC, 0);
The MS_MGC_VAL flag MS_MGC_VAL to be for backward compatibility with kernel versions prior to 2.4. The important bits are MS_BIND (to complete the binding installation) and MS_REC (in order to do this recursively, so that directories whose contents were hidden by other mounts mounted on them do not display their contents in the mount namespace).
So now I have to decide whether I go with the perl system function call or just the mount system code, because both work just as well :)