I am a little confused about what is happening here. I was following a guide where a new mount point was added after calling clone with the CLONE_NEWNS flag set. The mount point was supposed to only exist for the child process. I'm trying to do change the new filesystem namespace and it seems to effect the parent one.
My c program is pretty simple. Main will call clone
pid_t pid = clone(child_exec,c_stack, SIGCHLD | CLONE_NEWNS | CLONE_NEWPID ,args);
args is a chat array that contains a command to exec.
int child_exec(void *arg)
{
int err =0;
char **commands = (char **)arg;
mount("none", "/mytmp", "tmpfs", 0, "");
execvp(commands[0],commands);
return 0;
}
If the command that is passed to execvp is mount
I would expect the output to contain the /mytmp mount point and running the command mount
again after the program exits to not see /mytmp come up. That's not happening. I see it in the out when execvp is called and after when I run mount.
I tried mounting with MS_PRIVATE flag and using unshare(CLONE_FS);
I also had a similar problem where I tried to unmount /proc from the child process and a get resource is busy error. I thought that shouldn't have happened with a new namespace.
This came down to two issues for me.
First is it seems like the version of Ubuntu(16.04.1 LTS) or util-linux package I'm using shares the / mount namespace and CLONE_NEWNS propagates that setting. My / mount was shared. I verified this in /proc/self/mountinfo and /proc/1/mountinfo. I tried sudo mount --make-private -o remount /
from this answer and upgraed the package mentioned. https://unix.stackexchange.com/questions/246312/why-is-my-bind-mount-visible-outside-its-mount-namespace. That allowed me to make an extra mount without any effect on the parent namespace.
The second problem was unmounting /proc. This didn't work becasue my system had /proc/sys/fs/binfmt_misc
mounted twice. The discussion here inspired me to check that. http://linux-kernel.vger.kernel.narkive.com/aVUicig1/umount-proc-after-clone-newns-in-2-6-25
my final child_exec code ended up being
int child_exec(void *arg)
{
int err =0;
char **commands = (char **)arg;
printf("child...%s\n",commands[0]);
// if(unshare(CLONE_NEWNS) <0)
// printf("unshare issue?\n");
if (umount("/proc/sys/fs/binfmt_misc") <0)
printf("error unmount bin: %s\n",strerror(errno));
if (umount("/proc/sys/fs/binfmt_misc") <0)
printf("error unmount bin: %s\n",strerror(errno));
if (umount("/proc") <0)
printf("error unmount: %s\n",strerror(errno));
if (mount("proc", "/proc", "proc",0, NULL) <0)
printf("error mount: %s\n",strerror(errno));
execvp(commands[0],commands);
return 0;
}