我正在学习mount命名空间,这是Linux内核提供的隔离机制。我写了一个简单的C程序来测试它。
#define _GNU_SOURCE
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <asm/unistd.h>
#include <sys/mount.h>
#include <errno.h>
#include <string.h>
#define STACK_SIZE (1024 * 1024)
static char container_stack[STACK_SIZE];
char* const container_args[] = {
"/bin/bash",
NULL
};
void mounts(void)
{
syscall(__NR_mount, "proc", "/home/aaa/nstest/", "proc", 0, NULL);
}
int container_main(void* arg)
{
printf("Container - inside the container!\n");
errno = 0;
mounts();
perror("mount");
execv(container_args[0], container_args);
printf("Something's wrong!\n");
return 1;
}
int main()
{
printf("Parent - start a container!\n");
int pid = syscall(__NR_clone, CLONE_NEWNS | SIGCHLD, NULL, NULL, NULL, NULL);
if (pid < 0) {
perror("clone failed");
exit(-1);
} else if (pid == 0) {
container_main(NULL);
exit(0);
}
waitpid(pid, NULL, 0);
printf("Parent - container stopped!\n");
return 0;
}
这段代码在我的Ubuntu上运行良好。目录&#34; / home / aaa / nstest /&#34;在根装入命名空间中挂载后,它在新安装命名空间中为空。
但是,它并不适用于Android模拟器。安装程序传播到根安装命名空间。首先我认为它可能是由内核引起的,不支持命名空间。所以我用所有相对的CONFIG开关编译金鱼,比如CONFIG_NAMESPACE。而且它也不起作用。
答案 0 :(得分:1)
即使在使用所有CONFIG_NAMESPACE重新编译内核之后,我也遇到了同样的问题。我已经尝试了unshare -m /bin/bash
命令,它可以在我的archlinux x86_64框中运行,
所以我深入研究了命令的strace unshare -m /bin/bash
。
...
unshare(CLONE_NEWNS) = 0
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL) = 0
execve("/bin/bash", ["/bin/bash"], [/* 19 vars */]) = 0
...
接缝需要额外拨打mount(...)
。将调用添加到我的代码中,它可以工作!
int main(int argc, const char* argv[]) {
const char * source=argv[1];
const char * target=argv[2];
if (unshare(CLONE_NEWNS) == -1) {
printf("Failed to unshare(): %s\n", strerror(errno));
return -1;
}
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL);
if (mount(source, target, NULL, MS_BIND, NULL) == -1) {
printf("Failed to mount %s to %s: %s\n", source, target, strerror(errno));
return -1;
}
sleep(50);
return 0;
}