mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-08-26 18:17:25 +00:00
split container operation to hyper_setup_container() and hyper_run_process()
Signed-off-by: Lai Jiangshan <jiangshanlai@gmail.com>
This commit is contained in:
+9
-60
@@ -499,47 +499,21 @@ static int hyper_rescan_scsi(void)
|
||||
struct hyper_container_arg {
|
||||
struct hyper_container *c;
|
||||
struct hyper_pod *pod;
|
||||
int ipcns;
|
||||
int utsns;
|
||||
int pipe[2];
|
||||
};
|
||||
|
||||
static int hyper_container_init(void *data)
|
||||
static int hyper_setup_container_rootfs(void *data)
|
||||
{
|
||||
struct hyper_container_arg *arg = data;
|
||||
struct hyper_container *container = arg->c;
|
||||
char root[512], rootfs[512];
|
||||
int setup_dns;
|
||||
|
||||
fprintf(stdout, "%s in\n", __func__);
|
||||
if (container->exec.argv == NULL) {
|
||||
fprintf(stdout, "no cmd!\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (setns(arg->ipcns, CLONE_NEWIPC) < 0) {
|
||||
perror("setns to ipcns of pod init faild");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (setns(arg->utsns, CLONE_NEWUTS) < 0) {
|
||||
perror("setns to ipcns of pod init faild");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hyper_rescan_scsi() < 0) {
|
||||
fprintf(stdout, "rescan scsi failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// set early env. the container env config can overwrite it
|
||||
setenv("HOME", "/root", 1);
|
||||
setenv("HOSTNAME", arg->pod->hostname, 1);
|
||||
if (container->exec.tty)
|
||||
setenv("TERM", "xterm", 1);
|
||||
else
|
||||
unsetenv("TERM");
|
||||
|
||||
if (mount("", "/", NULL, MS_SLAVE|MS_REC, NULL) < 0) {
|
||||
perror("mount SLAVE failed");
|
||||
goto fail;
|
||||
@@ -650,7 +624,8 @@ static int hyper_container_init(void *data)
|
||||
}
|
||||
|
||||
hyper_send_type(arg->pipe[1], READY);
|
||||
hyper_exec_process(&container->exec);
|
||||
fflush(NULL);
|
||||
_exit(0);
|
||||
|
||||
fail:
|
||||
hyper_send_type(arg->pipe[1], ERROR);
|
||||
@@ -674,23 +649,15 @@ static int hyper_setup_pty(struct hyper_container *c)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hyper_setup_exec_tty(&c->exec) < 0) {
|
||||
fprintf(stderr, "setup container pts failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hyper_start_container(struct hyper_container *container,
|
||||
int utsns, int ipcns, struct hyper_pod *pod)
|
||||
int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod)
|
||||
{
|
||||
int stacksize = getpagesize() * 42;
|
||||
struct hyper_container_arg arg = {
|
||||
.c = container,
|
||||
.pod = pod,
|
||||
.utsns = utsns,
|
||||
.ipcns = ipcns,
|
||||
.pipe = {-1, -1},
|
||||
};
|
||||
int flags = CLONE_NEWNS | SIGCHLD;
|
||||
@@ -699,24 +666,18 @@ int hyper_start_container(struct hyper_container *container,
|
||||
uint32_t type;
|
||||
int pid;
|
||||
|
||||
if (container->image == NULL || container->exec.argv == NULL) {
|
||||
fprintf(stdout, "container root image %s, argv %p\n",
|
||||
container->image, container->exec.argv);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (pipe2(arg.pipe, O_CLOEXEC) < 0) {
|
||||
perror("create pipe between pod init execcmd failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hyper_setup_pty(container) < 0) {
|
||||
fprintf(stderr, "setup pty device for container failed\n");
|
||||
if (hyper_setup_container_portmapping(container, pod) < 0) {
|
||||
perror("fail to setup port mapping for container");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hyper_watch_exec_pty(&container->exec, pod) < 0) {
|
||||
fprintf(stderr, "faile to watch container pty\n");
|
||||
if (hyper_setup_pty(container) < 0) {
|
||||
fprintf(stderr, "setup pty device for container failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -726,7 +687,7 @@ int hyper_start_container(struct hyper_container *container,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pid = clone(hyper_container_init, stack + stacksize, flags, &arg);
|
||||
pid = clone(hyper_setup_container_rootfs, stack + stacksize, flags, &arg);
|
||||
free(stack);
|
||||
if (pid < 0) {
|
||||
perror("create child process failed");
|
||||
@@ -746,24 +707,12 @@ int hyper_start_container(struct hyper_container *container,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
container->exec.pid = pid;
|
||||
list_add_tail(&container->exec.list, &pod->exec_head);
|
||||
container->exec.ref++;
|
||||
|
||||
close(arg.pipe[0]);
|
||||
close(arg.pipe[1]);
|
||||
fprintf(stdout, "container %s,init pid %d,ref %d\n", container->id, pid, container->exec.ref);
|
||||
return 0;
|
||||
fail:
|
||||
close(container->ns);
|
||||
hyper_reset_event(&container->exec.stdinev);
|
||||
hyper_reset_event(&container->exec.stdoutev);
|
||||
hyper_reset_event(&container->exec.stderrev);
|
||||
container->ns = -1;
|
||||
fprintf(stdout, "container %s init exit code %d\n", container->id, -1);
|
||||
container->exec.code = -1;
|
||||
container->exec.seq = 0;
|
||||
container->exec.ref = 0;
|
||||
close(arg.pipe[0]);
|
||||
close(arg.pipe[1]);
|
||||
return -1;
|
||||
|
||||
+1
-2
@@ -53,8 +53,7 @@ struct hyper_container {
|
||||
|
||||
struct hyper_pod;
|
||||
|
||||
int hyper_start_container(struct hyper_container *container,
|
||||
int utsns, int ipcns, struct hyper_pod *pod);
|
||||
int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod);
|
||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, const char *id);
|
||||
void hyper_cleanup_container(struct hyper_container *container, struct hyper_pod *pod);
|
||||
void hyper_cleanup_containers(struct hyper_pod *pod);
|
||||
|
||||
+9
-130
@@ -274,141 +274,18 @@ fail:
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct hyper_stage0_arg {
|
||||
struct hyper_pod *pod;
|
||||
struct hyper_container *container;
|
||||
int ctl_pipe[2];
|
||||
};
|
||||
|
||||
// stage0: enter the pidns
|
||||
static int hyper_container_stage0(void *data)
|
||||
{
|
||||
int pidns, ipcns, utsns, ret;
|
||||
struct hyper_container *c;
|
||||
struct hyper_stage0_arg *arg;
|
||||
struct hyper_pod *pod;
|
||||
char path[64];
|
||||
|
||||
arg = data;
|
||||
pod = arg->pod;
|
||||
c = arg->container;
|
||||
|
||||
ret = pidns = ipcns = utsns = -1;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ret = hyper_start_container(c, utsns, ipcns, pod);
|
||||
out:
|
||||
close(pidns);
|
||||
close(utsns);
|
||||
close(ipcns);
|
||||
|
||||
if (hyper_send_type(arg->ctl_pipe[1], ret ? ERROR : READY) < 0) {
|
||||
fprintf(stderr, "container init send ready message failed\n");
|
||||
}
|
||||
|
||||
/* hyper_container_stage0 shares fd table with init, let init closes pipe. */
|
||||
//close(arg->ctl_pipe[0]);
|
||||
//close(arg->ctl_pipe[1]);
|
||||
|
||||
_exit(ret);
|
||||
}
|
||||
|
||||
int hyper_start_container_stage0(struct hyper_container *c, struct hyper_pod *pod)
|
||||
{
|
||||
int stacksize = getpagesize() * 4;
|
||||
void *stack = NULL;
|
||||
struct hyper_stage0_arg arg = {
|
||||
.pod = pod,
|
||||
.container = c,
|
||||
.ctl_pipe = {-1, -1},
|
||||
};
|
||||
int ret = -1, pid, status;
|
||||
uint32_t type;
|
||||
|
||||
if (pipe2(arg.ctl_pipe, O_CLOEXEC) < 0) {
|
||||
perror("create pipe between hyper init and pod init failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
stack = malloc(stacksize);
|
||||
if (stack == NULL) {
|
||||
perror("fail to allocate stack for container init");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hyper_setup_container_portmapping(c, pod) < 0) {
|
||||
perror("fail to setup port mapping for container");
|
||||
goto out;
|
||||
}
|
||||
|
||||
pid = clone(hyper_container_stage0, stack + stacksize, CLONE_VM| CLONE_FILES| SIGQUIT, &arg);
|
||||
if (pid < 0) {
|
||||
perror("enter container pid ns failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (waitpid(pid, &status, __WCLONE) <= 0) {
|
||||
perror("waiting hyper_container_stage0 finish failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait for container start */
|
||||
if (hyper_get_type(arg.ctl_pipe[0], &type) < 0) {
|
||||
perror("get enter_container_pidns ready message failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (type != READY) {
|
||||
fprintf(stderr, "get incorrect enter_container_pidns message type %d, expect READY\n",
|
||||
type);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* container process is spawned and ready to execute */
|
||||
pod->remains++;
|
||||
ret = 0;
|
||||
out:
|
||||
close(arg.ctl_pipe[0]);
|
||||
close(arg.ctl_pipe[1]);
|
||||
|
||||
free(stack);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hyper_start_containers(struct hyper_pod *pod)
|
||||
{
|
||||
struct hyper_container *c;
|
||||
|
||||
// TODO: setup containers and run container init processes
|
||||
// via separated hyperstart APIs
|
||||
list_for_each_entry(c, &pod->containers, list) {
|
||||
if (hyper_start_container_stage0(c, pod) < 0)
|
||||
if (hyper_setup_container(c, pod) < 0)
|
||||
return -1;
|
||||
if (hyper_run_process(&c->exec) < 0)
|
||||
return -1;
|
||||
pod->remains++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -665,7 +542,9 @@ static int hyper_new_container(char *json, int length)
|
||||
}
|
||||
|
||||
list_add_tail(&c->list, &pod->containers);
|
||||
ret = hyper_start_container_stage0(c, pod);
|
||||
ret = hyper_setup_container(c, pod);
|
||||
if (ret >= 0)
|
||||
ret = hyper_run_process(&c->exec);
|
||||
if (ret < 0) {
|
||||
//TODO full grace cleanup
|
||||
hyper_cleanup_container(c, pod);
|
||||
|
||||
Reference in New Issue
Block a user