mirror of
https://github.com/clearlinux/hyperstart.git
synced 2026-09-03 20:21:47 +00:00
create container process in hyper init
Move most of functions from pod init to hyper init. this makes logic more clearer Signed-off-by: Gao feng <omarapazanadi@gmail.com>
This commit is contained in:
+60
-33
@@ -276,6 +276,9 @@ static int hyper_rescan_scsi(void)
|
||||
|
||||
struct hyper_container_arg {
|
||||
struct hyper_container *c;
|
||||
int pidns;
|
||||
int ipcns;
|
||||
int utsns;
|
||||
int pipe[2];
|
||||
};
|
||||
|
||||
@@ -291,6 +294,21 @@ static int hyper_container_init(void *data)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (setns(arg->pidns, CLONE_NEWPID) < 0) {
|
||||
perror("setns to pidns of pod init faild");
|
||||
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;
|
||||
@@ -405,11 +423,40 @@ fail:
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
int hyper_start_container(struct hyper_container *container)
|
||||
static int hyper_setup_pty(struct hyper_container *c)
|
||||
{
|
||||
char root[512];
|
||||
|
||||
sprintf(root, "/tmp/hyper/%s/devpts/", c->id);
|
||||
|
||||
if (hyper_mkdir(root) < 0) {
|
||||
perror("make container pts directroy failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount("devpts", root, "devpts", MS_NOSUID,
|
||||
"newinstance,ptmxmode=0666,mode=0620") < 0) {
|
||||
perror("mount devpts failed");
|
||||
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 pidns, int utsns, int ipcns)
|
||||
{
|
||||
int stacksize = getpagesize() * 4;
|
||||
struct hyper_container_arg arg = {
|
||||
.c = container,
|
||||
.pidns = pidns,
|
||||
.utsns = utsns,
|
||||
.ipcns = ipcns,
|
||||
};
|
||||
int flags = CLONE_NEWNS | SIGCHLD;
|
||||
uint32_t type;
|
||||
@@ -422,6 +469,11 @@ int hyper_start_container(struct hyper_container *container)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hyper_setup_pty(container) < 0) {
|
||||
fprintf(stderr, "setup pty device for container failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, arg.pipe) < 0) {
|
||||
perror("create pipe between pod init execcmd failed");
|
||||
goto fail;
|
||||
@@ -430,7 +482,7 @@ int hyper_start_container(struct hyper_container *container)
|
||||
stack = malloc(stacksize);
|
||||
if (stack == NULL) {
|
||||
perror("fail to allocate stack for container init");
|
||||
return -1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pid = clone(hyper_container_init, stack + stacksize, flags, &arg);
|
||||
@@ -439,54 +491,29 @@ int hyper_start_container(struct hyper_container *container)
|
||||
perror("create child process failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
container->exec.pid = pid;
|
||||
|
||||
/* wait for ready message */
|
||||
if (hyper_get_type_block(arg.pipe[0], &type) < 0 || type != READY) {
|
||||
fprintf(stdout, "wait for container started failed\n");
|
||||
fprintf(stderr, "wait for container started failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
close(arg.pipe[0]);
|
||||
close(arg.pipe[1]);
|
||||
|
||||
if (hyper_watch_exec_pty(&container->exec) < 0)
|
||||
fprintf(stderr, "faile to watch container pty\n");
|
||||
|
||||
fprintf(stdout, "container %s init pid is %d\n", container->id, pid);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fprintf(stdout, "container %s init exit code %d\n", container->id, -1);
|
||||
|
||||
container->exec.code = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int hyper_start_containers(struct hyper_pod *pod)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* mount new proc directory */
|
||||
if (umount("/proc") < 0) {
|
||||
perror("umount proc filesystem failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount("proc", "/proc", "proc", 0, NULL) < 0) {
|
||||
perror("mount proc filesystem failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sethostname(pod->hostname, strlen(pod->hostname)) < 0) {
|
||||
perror("set host name failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < pod->c_num; i++)
|
||||
hyper_start_container(&pod->c[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int hyper_restart_containers(struct hyper_pod *pod)
|
||||
{
|
||||
int i;
|
||||
@@ -507,7 +534,7 @@ int hyper_restart_containers(struct hyper_pod *pod)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
+3
-2
@@ -39,9 +39,10 @@ struct hyper_container {
|
||||
|
||||
struct hyper_pod;
|
||||
|
||||
int hyper_start_containers(struct hyper_pod *pod);
|
||||
int hyper_start_container(struct hyper_container *container,
|
||||
int pidns, int utsns, int ipcns);
|
||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id);
|
||||
int hyper_restart_containers(struct hyper_pod *pod);
|
||||
//int hyper_restart_containers(struct hyper_pod *pod);
|
||||
void hyper_cleanup_container(struct hyper_pod *pod);
|
||||
|
||||
#endif
|
||||
|
||||
+95
-142
@@ -176,33 +176,93 @@ int hyper_dup_exec_tty(int to, struct hyper_exec *e)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hyper_exec_in_container(struct hyper_pod *pod,
|
||||
struct hyper_exec *exec)
|
||||
int hyper_watch_exec_pty(struct hyper_exec *exec)
|
||||
{
|
||||
global_exec = exec;
|
||||
|
||||
if (hyper_send_type_block(ctl.ctl.fd, EXECCMD, 1) < 0) {
|
||||
global_exec = NULL;
|
||||
fprintf(stderr, "tell pod init EXECCMD failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_add_tail(&exec->list, &pod->ce_head);
|
||||
if (exec->seq == 0)
|
||||
return 0;
|
||||
|
||||
fprintf(stdout, "init container exec pts event %p, ops %p, fd %d\n",
|
||||
fprintf(stdout, "hyper_init_event container pts event %p, ops %p, fd %d\n",
|
||||
&exec->e, &pts_ops, exec->e.fd);
|
||||
|
||||
if (hyper_init_event(&exec->e, &pts_ops, pod) < 0 ||
|
||||
if (hyper_init_event(&exec->e, &pts_ops, NULL) < 0 ||
|
||||
hyper_add_event(ctl.efd, &exec->e, EPOLLIN) < 0) {
|
||||
fprintf(stderr, "add pts master event failed\n");
|
||||
fprintf(stderr, "add container pts master event failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hyper_enter_container(struct hyper_pod *pod,
|
||||
struct hyper_exec *exec)
|
||||
{
|
||||
int pidns, ipcns, utsns, mntns, ret;
|
||||
struct hyper_container *c;
|
||||
char path[512];
|
||||
|
||||
ret = pidns = ipcns = utsns = mntns = -1;
|
||||
|
||||
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/pid", c->exec.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", c->exec.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", c->exec.pid);
|
||||
ipcns = open(path, O_RDONLY| O_CLOEXEC);
|
||||
if (ipcns < 0) {
|
||||
perror("fail to open ipcns of pod init");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(path, "/proc/%d/ns/mnt", c->exec.pid);
|
||||
mntns = open(path, O_RDONLY| O_CLOEXEC);
|
||||
if (mntns < 0) {
|
||||
perror("fail to open mntns of pod init");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (setns(pidns, CLONE_NEWPID) < 0 ||
|
||||
setns(utsns, CLONE_NEWUTS) < 0||
|
||||
setns(ipcns, CLONE_NEWIPC) <0 ||
|
||||
setns(mntns, CLONE_NEWNS) < 0) {
|
||||
perror("fail to enter container ns");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sprintf(path, "/tmp/hyper/%s/root/%s/", c->id, c->rootfs);
|
||||
fprintf(stdout, "root directory for container is %s, exec %s\n",
|
||||
path, exec->argv[0]);
|
||||
|
||||
/* TODO: wait for container finishing setup root */
|
||||
if (chroot(path) < 0) {
|
||||
perror("chroot for exec command failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
chdir("/");
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
close(pidns);
|
||||
close(ipcns);
|
||||
close(utsns);
|
||||
close(mntns);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
int hyper_request_restart_containers(struct hyper_pod *pod)
|
||||
{
|
||||
int i;
|
||||
@@ -241,6 +301,7 @@ int hyper_request_restart_containers(struct hyper_pod *pod)
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
int hyper_exec_cmd(char *json, int length)
|
||||
{
|
||||
@@ -267,15 +328,6 @@ int hyper_exec_cmd(char *json, int length)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (exec->id) {
|
||||
if (hyper_exec_in_container(pod, exec) < 0) {
|
||||
fprintf(stderr, "notify container exec failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, pipe) < 0) {
|
||||
perror("create pipe between pod init execcmd failed");
|
||||
return -1;
|
||||
@@ -299,14 +351,11 @@ int hyper_exec_cmd(char *json, int length)
|
||||
exec->pid = pid;
|
||||
fprintf(stdout, "create exec cmd %s pid %d\n", exec->argv[0], pid);
|
||||
|
||||
list_add_tail(&exec->list, &pod->pe_head);
|
||||
list_add_tail(&exec->list, &pod->exec_head);
|
||||
if (exec->seq == 0)
|
||||
return 0;
|
||||
|
||||
fprintf(stdout, "init pod exec pts event %p, ops %p, fd %d\n",
|
||||
&exec->e, &pts_ops, exec->e.fd);
|
||||
if (hyper_init_event(&exec->e, &pts_ops, pod) < 0 ||
|
||||
hyper_add_event(ctl.efd, &exec->e, EPOLLIN) < 0) {
|
||||
if (hyper_watch_exec_pty(exec) < 0) {
|
||||
fprintf(stderr, "add pts master event failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -314,6 +363,11 @@ int hyper_exec_cmd(char *json, int length)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (exec->id && hyper_enter_container(pod, exec) < 0) {
|
||||
fprintf(stderr, "enter container ns failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hyper_dup_exec_tty(pipe[1], exec) < 0) {
|
||||
fprintf(stderr, "dup pts to exec stdio failed\n");
|
||||
_exit(-1);
|
||||
@@ -330,106 +384,6 @@ int hyper_exec_cmd(char *json, int length)
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
int hyper_container_execcmd(struct hyper_pod *pod)
|
||||
{
|
||||
struct hyper_exec *exec = global_exec;
|
||||
struct hyper_container *container = NULL;
|
||||
int fd, pid, sock = pod->ctl.fd;
|
||||
char root[512]; int pipe[2];
|
||||
|
||||
global_exec = NULL;
|
||||
|
||||
container = hyper_find_container(pod, exec->id);
|
||||
if (container == NULL) {
|
||||
fprintf(stderr, "can not find container %s\n", exec->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sprintf(root, "/tmp/hyper/%s/devpts/", exec->id) < 0) {
|
||||
fprintf(stderr, "get container %s pts path failed\n", exec->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, pipe) < 0) {
|
||||
perror("create pipe between pod init execcmd failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "container init fork failed\n");
|
||||
return -1;
|
||||
} else if (pid > 0) {
|
||||
uint32_t type;
|
||||
|
||||
if (hyper_get_type_block(pipe[0], &type) < 0 || type != READY) {
|
||||
fprintf(stderr, "pod init get execcmd ready message failed\n");
|
||||
hyper_send_type_block(sock, ERROR, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(pipe[0]);
|
||||
close(pipe[1]);
|
||||
fprintf(stdout, "pod init get ready message\n");
|
||||
|
||||
exec->pid = pid;
|
||||
fprintf(stdout, "create exec cmd %s pid %d\n", exec->argv[0], pid);
|
||||
|
||||
if (hyper_send_type_block(sock, ACK, 0) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
close(pipe[0]);
|
||||
sprintf(root, "/proc/%d/ns/mnt", container->exec.pid);
|
||||
|
||||
fprintf(stdout, "container %s, init pid %d\n",
|
||||
exec->id, container->exec.pid);
|
||||
|
||||
fd = open(root, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("fail to open container mnt ns\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (syscall(SYS_setns, fd, CLONE_NEWNS) < 0) {
|
||||
perror("enter mnt ns failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
sprintf(root, "/tmp/hyper/%s/root/%s/",
|
||||
container->id, container->rootfs);
|
||||
|
||||
fprintf(stdout, "root directory for container is %s, exec %s\n",
|
||||
root, exec->argv[0]);
|
||||
|
||||
/* TODO: wait for container finishing setup root */
|
||||
if (chroot(root) < 0) {
|
||||
perror("chroot for exec command failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
chdir("/");
|
||||
|
||||
if (hyper_dup_exec_tty(pipe[1], exec)) {
|
||||
fprintf(stderr, "dup pts to stdio failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
close(pipe[1]);
|
||||
if (execvp(exec->argv[0], exec->argv) < 0)
|
||||
perror("exec failed");
|
||||
|
||||
_exit(-1);
|
||||
fail:
|
||||
hyper_send_type_block(pipe[1], ERROR, 0);
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
|
||||
int hyper_release_exec(struct hyper_exec *exec,
|
||||
struct hyper_pod *pod)
|
||||
{
|
||||
@@ -463,7 +417,7 @@ int hyper_release_exec(struct hyper_exec *exec,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hyper_request_restart_containers(pod) < 0) {
|
||||
if (hyper_start_containers(pod) < 0) {
|
||||
fprintf(stderr, "restart container failed\n");
|
||||
return -1;
|
||||
}
|
||||
@@ -503,15 +457,15 @@ struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq)
|
||||
{
|
||||
struct hyper_exec *exec;
|
||||
|
||||
list_for_each_entry(exec, &pod->ce_head, list) {
|
||||
fprintf(stdout, "container exec seq %" PRIu64 ", seq %" PRIu64 "\n",
|
||||
list_for_each_entry(exec, &pod->exec_head, list) {
|
||||
fprintf(stdout, "exec seq %" PRIu64 ", seq %" PRIu64 "\n",
|
||||
exec->seq, seq);
|
||||
if (exec->seq != seq)
|
||||
continue;
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
/*
|
||||
list_for_each_entry(exec, &pod->pe_head, list) {
|
||||
fprintf(stdout, "pod exec seq %" PRIu64 ", seq %" PRIu64 "\n",
|
||||
exec->seq, seq);
|
||||
@@ -520,18 +474,17 @@ struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq)
|
||||
|
||||
return exec;
|
||||
}
|
||||
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int hyper_send_exec_eof(int to, struct hyper_pod *pod,
|
||||
struct list_head *head, int pid,
|
||||
uint8_t code)
|
||||
int pid, uint8_t code)
|
||||
{
|
||||
struct hyper_exec *exec;
|
||||
uint8_t seq[12];
|
||||
|
||||
exec = hyper_find_exec_by_pid(head, pid);
|
||||
exec = hyper_find_exec_by_pid(&pod->exec_head, pid);
|
||||
if (exec == NULL) {
|
||||
fprintf(stdout, "can not find exec whose pid is %d\n",
|
||||
pid);
|
||||
@@ -562,8 +515,8 @@ void hyper_cleanup_exec(struct hyper_pod *pod)
|
||||
{
|
||||
struct hyper_exec *exec, *next;
|
||||
|
||||
list_for_each_entry_safe(exec, next, &pod->ce_head, list) {
|
||||
fprintf(stdout, "cleanup container exec seq %" PRIu64 "\n", exec->seq);
|
||||
list_for_each_entry_safe(exec, next, &pod->exec_head, list) {
|
||||
fprintf(stdout, "cleanup exec seq %" PRIu64 "\n", exec->seq);
|
||||
hyper_release_exec(exec, pod);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,8 +28,8 @@ int hyper_dup_exec_tty(int fd, struct hyper_exec *e);
|
||||
struct hyper_exec *hyper_find_exec_by_pid(struct list_head *head, int pid);
|
||||
struct hyper_exec *hyper_find_exec_by_seq(struct hyper_pod *pod, uint64_t seq);
|
||||
int hyper_send_exec_eof(int to, struct hyper_pod *pod,
|
||||
struct list_head *head, int pid,
|
||||
uint8_t code);
|
||||
int pid, uint8_t code);
|
||||
int hyper_watch_exec_pty(struct hyper_exec *exec);
|
||||
void hyper_cleanup_exec(struct hyper_pod *pod);
|
||||
|
||||
extern struct hyper_event_ops pts_ops;
|
||||
|
||||
+3
-2
@@ -40,8 +40,8 @@ struct hyper_pod {
|
||||
struct hyper_interface *iface;
|
||||
struct hyper_route *rt;
|
||||
char **dns;
|
||||
struct list_head pe_head;
|
||||
struct list_head ce_head;
|
||||
struct list_head exec_head;
|
||||
//struct list_head ce_head;
|
||||
char *hostname;
|
||||
char *tag;
|
||||
int init_pid;
|
||||
@@ -88,6 +88,7 @@ struct hyper_ctl {
|
||||
int hyper_mkdir(char *hyper_path);
|
||||
int hyper_open_serial(char *tty);
|
||||
struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id);
|
||||
int hyper_start_containers(struct hyper_pod *pod);
|
||||
|
||||
extern struct hyper_pod global_pod;
|
||||
extern struct hyper_ctl ctl;
|
||||
|
||||
+88
-88
@@ -29,8 +29,7 @@
|
||||
#include "container.h"
|
||||
|
||||
struct hyper_pod global_pod = {
|
||||
.ce_head = LIST_HEAD_INIT(global_pod.ce_head),
|
||||
.pe_head = LIST_HEAD_INIT(global_pod.pe_head),
|
||||
.exec_head = LIST_HEAD_INIT(global_pod.exec_head),
|
||||
};
|
||||
struct hyper_exec *global_exec;
|
||||
|
||||
@@ -39,8 +38,7 @@ struct hyper_exec *global_exec;
|
||||
struct hyper_ctl ctl;
|
||||
|
||||
static void hyper_cleanup_pod(struct hyper_pod *pod);
|
||||
static int hyper_handle_exit(struct hyper_pod *pod, int to,
|
||||
int container, int option);
|
||||
static int hyper_handle_exit(struct hyper_pod *pod);
|
||||
|
||||
static int hyper_set_win_size(char *json, int length)
|
||||
{
|
||||
@@ -112,15 +110,18 @@ static int pod_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
|
||||
case STOPPOD:
|
||||
fprintf(stdout, "get type STOPPOD, exit\n");
|
||||
hyper_cleanup_pod(pod);
|
||||
/*
|
||||
case RESTARTCONTAINER:
|
||||
fprintf(stdout, "%s get type RESTARTCONTAINER\n", __func__);
|
||||
if (hyper_restart_containers(pod) < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
||||
case EXECCMD:
|
||||
if (hyper_container_execcmd(pod) < 0)
|
||||
return -1;
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -128,14 +129,13 @@ static int pod_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hyper_handle_exit(struct hyper_pod *pod, int to,
|
||||
int container, int option)
|
||||
static int hyper_handle_exit(struct hyper_pod *pod)
|
||||
{
|
||||
int pid, status;
|
||||
/* pid + exit code */
|
||||
uint8_t data[5];
|
||||
|
||||
while ((pid = waitpid(-1, &status, option)) > 0) {
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
data[4] = 0;
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
@@ -147,7 +147,7 @@ static int hyper_handle_exit(struct hyper_pod *pod, int to,
|
||||
fprintf(stdout, "pid %d exit by signal, status %d\n",
|
||||
pid, WTERMSIG(status));
|
||||
}
|
||||
|
||||
/*
|
||||
if (container) {
|
||||
hyper_set_be32(data, pid);
|
||||
if (hyper_send_msg(to, FINISHCMD, 5, data) < 0) {
|
||||
@@ -157,35 +157,30 @@ static int hyper_handle_exit(struct hyper_pod *pod, int to,
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hyper_send_exec_eof(to, pod, &pod->pe_head, pid, data[4]) < 0)
|
||||
*/
|
||||
if (hyper_send_exec_eof(ctl.tty.fd, pod, pid, data[4]) < 0)
|
||||
fprintf(stderr, "signal_loop send eof failed\n");
|
||||
}
|
||||
|
||||
if (option == WNOHANG)
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
/* send ack message to hyper init. */
|
||||
/* send ack message to hyper init.
|
||||
if (hyper_send_type(to, ACK) < 0) {
|
||||
fprintf(stderr, "send ACK of STOPPOD to hyper init failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
*/
|
||||
}
|
||||
|
||||
static int signal_loop(struct hyper_event *de, int container)
|
||||
static int hyper_signal_loop(struct hyper_event *de)
|
||||
{
|
||||
int size, to;
|
||||
int size;
|
||||
struct signalfd_siginfo sinfo;
|
||||
struct hyper_pod *pod = de->ptr;
|
||||
|
||||
if (container)
|
||||
to = pod->ctl.fd;
|
||||
else
|
||||
to = ctl.tty.fd;
|
||||
|
||||
fprintf(stdout, "%s write to %d\n", __func__, to);
|
||||
fprintf(stdout, "%s write to ctl tty fd\n", __func__);
|
||||
|
||||
while (1) {
|
||||
size = read(de->fd, &sinfo, sizeof(struct signalfd_siginfo));
|
||||
@@ -207,12 +202,13 @@ static int signal_loop(struct hyper_event *de, int container)
|
||||
return 0;
|
||||
}
|
||||
|
||||
hyper_handle_exit(pod, to, container, WNOHANG);
|
||||
hyper_handle_exit(pod);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static int pod_signal_loop(struct hyper_event *de)
|
||||
{
|
||||
return signal_loop(de, 1);
|
||||
@@ -222,6 +218,7 @@ static int hyper_signal_loop(struct hyper_event *de)
|
||||
{
|
||||
return signal_loop(de, 0);
|
||||
}
|
||||
*/
|
||||
|
||||
static struct hyper_event_ops pod_ctl_pipe_ops = {
|
||||
.read = hyper_event_read,
|
||||
@@ -231,10 +228,12 @@ static struct hyper_event_ops pod_ctl_pipe_ops = {
|
||||
.len_offset = 4,
|
||||
};
|
||||
|
||||
/*
|
||||
static struct hyper_event_ops pod_signal_ops = {
|
||||
.read = pod_signal_loop,
|
||||
.hup = hyper_event_hup,
|
||||
};
|
||||
*/
|
||||
|
||||
static int pod_init_loop(struct hyper_pod *pod)
|
||||
{
|
||||
@@ -254,7 +253,7 @@ static int pod_init_loop(struct hyper_pod *pod)
|
||||
fprintf(stderr, "hyper add pod ctl pipe event failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
fprintf(stdout, "hyper_init_event pod signal event %p, ops %p, fd %d\n",
|
||||
&pod->sig, &pod_signal_ops, pod->sig.fd);
|
||||
if (hyper_init_event(&pod->sig, &pod_signal_ops, pod) < 0 ||
|
||||
@@ -262,7 +261,7 @@ static int pod_init_loop(struct hyper_pod *pod)
|
||||
fprintf(stderr, "hyper add pod tty pipe event failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*/
|
||||
events = calloc(MAXEVENTS, sizeof(*events));
|
||||
|
||||
while (1) {
|
||||
@@ -295,7 +294,6 @@ static int hyper_pod_init(void *data)
|
||||
{
|
||||
struct hyper_pod_arg *arg = data;
|
||||
struct hyper_pod *pod = arg->pod;
|
||||
sigset_t mask;
|
||||
|
||||
close(arg->ctl_pipe[0]);
|
||||
close(ctl.sig.fd);
|
||||
@@ -308,7 +306,7 @@ static int hyper_pod_init(void *data)
|
||||
perror("set pod init ctl pipe fd FD_CLOEXEC failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGCHLD);
|
||||
|
||||
@@ -322,30 +320,43 @@ static int hyper_pod_init(void *data)
|
||||
perror("create signalfd failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (hyper_start_containers(pod) < 0)
|
||||
*/
|
||||
/* mount new proc directory */
|
||||
if (umount("/proc") < 0) {
|
||||
perror("umount proc filesystem failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (mount("proc", "/proc", "proc", 0, NULL) < 0) {
|
||||
perror("mount proc filesystem failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (sethostname(pod->hostname, strlen(pod->hostname)) < 0) {
|
||||
perror("set host name failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fprintf(stdout, "pod ctl_pipe %d\n", arg->ctl_pipe[1]);
|
||||
if (hyper_send_type(arg->ctl_pipe[1], READY) < 0) {
|
||||
fprintf(stderr, "container init send ready message failed\n");
|
||||
goto fail;
|
||||
}
|
||||
loop:
|
||||
|
||||
pod_init_loop(pod);
|
||||
fprintf(stdout, "pod init exit\n");
|
||||
out:
|
||||
_exit(-1);
|
||||
|
||||
fail:
|
||||
hyper_send_type(arg->ctl_pipe[1], ERROR);
|
||||
goto loop;
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
|
||||
{
|
||||
struct hyper_buf *buf = &de->rbuf;
|
||||
struct hyper_pod *pod = de->ptr;
|
||||
uint32_t type, pid = 0;
|
||||
uint8_t code;
|
||||
uint32_t type;
|
||||
|
||||
/* container exec finish message */
|
||||
fprintf(stdout, "%s\n", __func__);
|
||||
@@ -358,6 +369,7 @@ static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
|
||||
* fd is block, and ACK is the last message, exit loop. */
|
||||
fprintf(stdout, "hyper_ctl_pipe_loop get ack\n");
|
||||
return 1;
|
||||
/*
|
||||
case FINISHCMD:
|
||||
pid = hyper_get_be32(buf->data + 8);
|
||||
code = buf->data[12];
|
||||
@@ -366,6 +378,7 @@ static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
fprintf(stdout, "get unknown type %" PRIu32"\n", type);
|
||||
break;
|
||||
@@ -374,57 +387,49 @@ static int hyper_ctl_pipe_handle(struct hyper_event *de, uint32_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hyper_setup_pty(struct hyper_pod *pod)
|
||||
int hyper_start_containers(struct hyper_pod *pod)
|
||||
{
|
||||
int i;
|
||||
char root[512];
|
||||
int i, pidns, ipcns, utsns, ret;
|
||||
struct hyper_container *c;
|
||||
char path[64];
|
||||
|
||||
ret = pidns = ipcns = utsns = -1;
|
||||
|
||||
fprintf(stdout, "%s\n", __func__);
|
||||
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;
|
||||
}
|
||||
|
||||
for (i = 0; i < pod->c_num; i++) {
|
||||
c = &pod->c[i];
|
||||
|
||||
sprintf(root, "/tmp/hyper/%s/devpts/", c->id);
|
||||
|
||||
if (hyper_mkdir(root) < 0) {
|
||||
perror("make container pts directroy failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mount("devpts", root, "devpts", MS_NOSUID,
|
||||
"newinstance,ptmxmode=0666,mode=0620") < 0) {
|
||||
perror("mount devpts failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_add_tail(&c->exec.list, &pod->ce_head);
|
||||
|
||||
if (hyper_setup_exec_tty(&c->exec) < 0) {
|
||||
fprintf(stderr, "setup container pts failed\n");
|
||||
return -1;
|
||||
}
|
||||
list_add_tail(&c->exec.list, &pod->exec_head);
|
||||
hyper_start_container(c, pidns, utsns, ipcns);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
ret = 0;
|
||||
out:
|
||||
close(pidns);
|
||||
close(utsns);
|
||||
close(ipcns);
|
||||
|
||||
static int hyper_watch_pty(struct hyper_pod *pod)
|
||||
{
|
||||
int i;
|
||||
struct hyper_container *c;
|
||||
|
||||
for (i = 0; i < pod->c_num; i++) {
|
||||
c = &pod->c[i];
|
||||
|
||||
fprintf(stdout, "hyper_init_event container pts event %p, ops %p, fd %d\n",
|
||||
&c->exec.e, &pts_ops, c->exec.e.fd);
|
||||
if (hyper_init_event(&c->exec.e, &pts_ops, pod) < 0 ||
|
||||
hyper_add_event(ctl.efd, &c->exec.e, EPOLLIN) < 0) {
|
||||
fprintf(stderr, "add container pts master event failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct hyper_event_ops hyper_ctl_pipe_ops = {
|
||||
@@ -449,11 +454,6 @@ static int hyper_setup_container(struct hyper_pod *pod)
|
||||
uint32_t type;
|
||||
void *stack;
|
||||
|
||||
if (hyper_setup_pty(pod) < 0) {
|
||||
fprintf(stderr, "setup pty failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, 0, arg.ctl_pipe) < 0) {
|
||||
perror("create pipe between hyper init and pod init failed");
|
||||
return -1;
|
||||
@@ -473,10 +473,10 @@ static int hyper_setup_container(struct hyper_pod *pod)
|
||||
perror("create container init process failed");
|
||||
return -1;
|
||||
}
|
||||
fprintf(stdout, "pod init pid %d\n", pod->init_pid);
|
||||
|
||||
close(arg.ctl_pipe[1]);
|
||||
ctl.ctl.fd = arg.ctl_pipe[0];
|
||||
fprintf(stdout, "pod init pid %d\n", pod->init_pid);
|
||||
|
||||
/* Wait for container start */
|
||||
if (hyper_get_type_block(ctl.ctl.fd, &type) < 0) {
|
||||
@@ -489,8 +489,8 @@ static int hyper_setup_container(struct hyper_pod *pod)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (hyper_watch_pty(pod) < 0) {
|
||||
fprintf(stderr, "watch pty failed\n");
|
||||
if (hyper_start_containers(pod) < 0) {
|
||||
fprintf(stderr, "start containers failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -724,13 +724,13 @@ static void hyper_term_all(struct hyper_pod *pod)
|
||||
|
||||
static void hyper_cleanup_pod(struct hyper_pod *pod)
|
||||
{
|
||||
close(pod->sig.fd);
|
||||
hyper_reset_event(&pod->sig);
|
||||
//close(pod->sig.fd);
|
||||
//hyper_reset_event(&pod->sig);
|
||||
|
||||
hyper_term_all(pod);
|
||||
hyper_handle_exit(pod, pod->ctl.fd, 1, 0);
|
||||
//hyper_handle_exit(pod, pod->ctl.fd, 1, 0);
|
||||
|
||||
pod->init_pid = 0;
|
||||
//pod->init_pid = 0;
|
||||
|
||||
close(pod->ctl.fd);
|
||||
hyper_reset_event(&pod->ctl);
|
||||
|
||||
Reference in New Issue
Block a user