diff --git a/src/api.h b/src/api.h index 453c1f47..43421b67 100644 --- a/src/api.h +++ b/src/api.h @@ -32,6 +32,13 @@ enum { PROCESSASYNCEVENT, }; +// "hyperstart" is the special container ID for adding processes. +// +// The processes will be execve()-ed in the same namespaces as the +// hyperstart(init) process rather than in any container. +// This operation is "hyperstart-exec" +#define HYPERSTART_EXEC_CONTAINER "hyperstart" + /* * control message format * | ctrl id | length | payload (length-8) | diff --git a/src/container.h b/src/container.h index 91a7f95c..bcfc948e 100644 --- a/src/container.h +++ b/src/container.h @@ -2,6 +2,7 @@ #define _CONTAINER_H_ #include "exec.h" +#include "api.h" struct volume { char *device; @@ -61,4 +62,7 @@ void hyper_cleanup_container(struct hyper_container *container, struct hyper_pod void hyper_cleanup_containers(struct hyper_pod *pod); void hyper_free_container(struct hyper_container *c); +static inline int hyper_has_container(struct hyper_pod *pod, const char *id) { + return strcmp(id, HYPERSTART_EXEC_CONTAINER) == 0 || hyper_find_container(pod, id) != NULL; +} #endif diff --git a/src/exec.c b/src/exec.c index 114ff6d9..9c36b103 100644 --- a/src/exec.c +++ b/src/exec.c @@ -599,7 +599,7 @@ int hyper_exec_cmd(struct hyper_pod *pod, char *json, int length) return -1; } - if (hyper_find_container(pod, exec->container_id) == NULL) { + if (!hyper_has_container(pod, exec->container_id)) { fprintf(stderr, "call hyper_exec_cmd, no such container: %s\n", exec->container_id); hyper_free_exec(exec); return -1; @@ -646,6 +646,11 @@ int hyper_run_process(struct hyper_exec *exec) perror("fork prerequisite process failed"); goto close_tty; } else if (pid == 0) { + if (strcmp(exec->container_id, HYPERSTART_EXEC_CONTAINER) == 0) { + hyper_send_type(pipe[1], getpid()); + hyper_exec_process(exec, &io); + _exit(125); + } hyper_do_exec_cmd(exec, pipe[1], &io); } fprintf(stdout, "prerequisite process pid %d\n", pid); diff --git a/src/init.c b/src/init.c index b8666e2c..c83d8952 100644 --- a/src/init.c +++ b/src/init.c @@ -472,6 +472,22 @@ static int hyper_setup_shared(struct hyper_pod *pod) } #endif +static int hyper_setup_virtual_hyperstart_exec_container(struct hyper_pod *pod) +{ + if (hyper_mkdir("/tmp/hyper/" HYPERSTART_EXEC_CONTAINER, 0755) < 0) { + perror("create virtual hyperstart-exec container directory failed"); + return -1; + } + + // for creating ptymaster when adding process with terminal=true + if (symlink("/dev/pts", "/tmp/hyper/" HYPERSTART_EXEC_CONTAINER "/devpts") < 0) { + perror("create virtual hyperstart-exec container's /dev symlink failed"); + return -1; + } + + return 0; +} + static int hyper_setup_pod(struct hyper_pod *pod) { /* create sandbox directory */ @@ -505,6 +521,10 @@ static int hyper_setup_pod(struct hyper_pod *pod) return -1; } + if (hyper_setup_virtual_hyperstart_exec_container(pod) < 0) { + return -1; + } + return 0; } @@ -599,7 +619,7 @@ static int hyper_new_container(struct hyper_pod *pod, char *json, int length) return -1; } - if (hyper_find_container(pod, c->id) != NULL) { + if (hyper_has_container(pod, c->id)) { fprintf(stderr, "container id conflicts"); hyper_cleanup_container(c, pod); return -1;