add hyper_enter_sandbox()

Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
This commit is contained in:
Lai Jiangshan
2016-08-02 11:15:45 +08:00
parent 0c05c999e3
commit 74f6930073
3 changed files with 68 additions and 80 deletions
+10 -80
View File
@@ -491,47 +491,27 @@ static int hyper_watch_exec_pty(struct hyper_exec *exec, struct hyper_pod *pod)
return 0;
}
static int hyper_enter_container(struct hyper_pod *pod,
struct hyper_exec *exec)
static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe)
{
int ipcns, utsns, mntns, ret;
struct hyper_container *c;
char path[512];
ret = ipcns = utsns = mntns = -1;
if (hyper_enter_sandbox(pod, pipe) < 0) {
perror("enter pidns of pod init failed");
hyper_send_type(pipe, -1);
goto out;
}
c = hyper_find_container(pod, exec->id);
if (c == NULL) {
fprintf(stderr, "can not find container %s\n", exec->id);
return -1;
}
sprintf(path, "/proc/%d/ns/uts", pod->init_pid);
utsns = open(path, O_RDONLY| O_CLOEXEC);
if (utsns < 0) {
perror("fail to open utsns of pod init");
goto out;
}
sprintf(path, "/proc/%d/ns/ipc", pod->init_pid);
ipcns = open(path, O_RDONLY| O_CLOEXEC);
if (ipcns < 0) {
perror("fail to open ipcns of pod init");
goto out;
}
mntns = c->ns;
if (mntns < 0) {
perror("fail to open mntns of pod init");
goto out;
}
if (setns(utsns, CLONE_NEWUTS) < 0 ||
setns(ipcns, CLONE_NEWIPC) <0 ||
setns(mntns, CLONE_NEWNS) < 0) {
if (setns(c->ns, CLONE_NEWNS) < 0) {
perror("fail to enter container ns");
goto out;
}
chdir("/");
/* TODO: merge container env to exec env in hyperd */
if (hyper_setup_env(c->exec.envs, c->exec.envs_num) < 0) {
@@ -539,59 +519,12 @@ static int hyper_enter_container(struct hyper_pod *pod,
goto out;
}
/* TODO: wait for container finishing setup root */
chdir("/");
/* already in pidns & mntns of container, mount proc filesystem */
if (exec->init && mount("proc", "/proc", "proc", MS_NOSUID| MS_NODEV| MS_NOEXEC, NULL) < 0) {
perror("fail to mount proc filesystem for container");
goto out;
}
ret = 0;
out:
close(ipcns);
close(utsns);
return ret;
}
static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int pipe)
{
int pid = -1, ret = -1;
char path[512];
int pidns;
sprintf(path, "/proc/%d/ns/pid", pod->init_pid);
pidns = open(path, O_RDONLY| O_CLOEXEC);
if (pidns < 0) {
perror("fail to open pidns of pod init");
goto out;
}
/* enter pidns of pod init, so the children of this process will run in
* pidns of pod init, see man 2 setns */
if (setns(pidns, CLONE_NEWPID) < 0) {
perror("enter pidns of pod init failed");
goto out;
}
close(pidns);
pid = fork();
if (pid < 0) {
perror("fail to fork");
goto out;
} else if (pid > 0) {
fprintf(stdout, "create exec cmd %s pid %d,ref %d\n", exec->argv[0], pid, exec->ref);
ret = 0;
goto out;
}
if (hyper_enter_container(pod, exec) < 0) {
fprintf(stderr, "enter container ns failed\n");
goto exit;
}
// set early env. the container env config can overwrite it
setenv("HOME", "/root", 1);
setenv("HOSTNAME", pod->hostname, 1);
@@ -602,11 +535,8 @@ static int hyper_do_exec_cmd(struct hyper_exec *exec, struct hyper_pod *pod, int
hyper_exec_process(exec);
exit:
_exit(125);
out:
hyper_send_type(pipe, pid);
_exit(ret);
_exit(125);
}
// do the exec, no return
@@ -627,7 +557,7 @@ static void hyper_exec_process(struct hyper_exec *exec)
goto exit;
}
// set the container env
// set the process env
if (hyper_setup_env(exec->envs, exec->envs_num) < 0) {
fprintf(stderr, "setup env failed\n");
goto exit;
+1
View File
@@ -119,6 +119,7 @@ static inline int hyper_create(char *hyper_path)
int hyper_open_serial(char *tty);
void hyper_cleanup_pod(struct hyper_pod *pod);
int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe);
extern struct hyper_pod global_pod;
extern struct hyper_ctl ctl;
+57
View File
@@ -326,6 +326,63 @@ out:
return ret;
}
// enter the sanbox and pass to the child, shouldn't call from the init process
int hyper_enter_sandbox(struct hyper_pod *pod, int pidpipe)
{
int ret = -1, pidns = -1, utsns = -1, ipcns = -1;
char path[512];
sprintf(path, "/proc/%d/ns/pid", pod->init_pid);
pidns = open(path, O_RDONLY| O_CLOEXEC);
if (pidns < 0) {
perror("fail to open pidns of pod init");
goto out;
}
sprintf(path, "/proc/%d/ns/uts", pod->init_pid);
utsns = open(path, O_RDONLY| O_CLOEXEC);
if (utsns < 0) {
perror("fail to open utsns of pod init");
goto out;
}
sprintf(path, "/proc/%d/ns/ipc", pod->init_pid);
ipcns = open(path, O_RDONLY| O_CLOEXEC);
if (ipcns < 0) {
perror("fail to open ipcns of pod init");
goto out;
}
if (setns(pidns, CLONE_NEWPID) < 0 ||
setns(utsns, CLONE_NEWUTS) < 0 ||
setns(ipcns, CLONE_NEWIPC) < 0) {
perror("fail to enter the sandbox");
goto out;
}
/* current process isn't in the pidns even setns(pidns, CLONE_NEWPID)
* was called. fork() is needed, so that the child process will run in
* the pidns, see man 2 setns */
ret = fork();
if (ret < 0) {
perror("fail to fork");
goto out;
} else if (ret > 0) {
fprintf(stdout, "create child process pid=%d in the sandbox\n", ret);
if (pidpipe > 0) {
hyper_send_type(pidpipe, ret);
}
_exit(0);
}
out:
close(pidns);
close(ipcns);
close(utsns);
return ret;
}
#ifdef WITH_VBOX
#define MAX_HOST_NAME 256