diff --git a/src/container.c b/src/container.c index 3eaabeb..beb6b3d 100644 --- a/src/container.c +++ b/src/container.c @@ -586,69 +586,82 @@ struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id) return container; } + list_for_each_entry(container, &pod->dyn_containers, dyn) { + if (strlen(container->id) != strlen(id)) + continue; + + if (strncmp(container->id, id, strlen(id))) + continue; + + return container; + } + return NULL; } -void hyper_cleanup_container(struct hyper_pod *pod) +void hyper_cleanup_container(struct hyper_container *c) { - int i, j; - struct hyper_container *c; + int i; struct volume *vol; struct env *env; struct fsmap *map; struct sysctl *sys; char root[512]; - for (i = 0; i < pod->c_num; i++) { - c = &pod->c[i]; + sprintf(root, "/tmp/hyper/%s/devpts/", c->id); + if (umount(root) < 0 && umount2(root, MNT_DETACH)) + perror("umount devpts failed"); - sprintf(root, "/tmp/hyper/%s/devpts/", c->id); - if (umount(root) < 0 && umount2(root, MNT_DETACH)) - perror("umount devpts failed"); + free(c->id); + free(c->rootfs); + free(c->image); + free(c->workdir); + free(c->fstype); - free(c->id); - free(c->rootfs); - free(c->image); - free(c->workdir); - free(c->fstype); - - for (j = 0; j < c->vols_num; j++) { - vol = &(c->vols[j]); - free(vol->device); - free(vol->mountpoint); - free(vol->fstype); - } - free(c->vols); - - for (j = 0; j < c->envs_num; j++) { - env = &(c->envs[j]); - free(env->env); - free(env->value); - } - free(c->envs); - - for (j = 0; j < c->sys_num; j++) { - sys = &(c->sys[j]); - free(sys->path); - free(sys->value); - } - free(c->sys); - - for (j = 0; j < c->maps_num; j++) { - map = &(c->maps[j]); - free(map->source); - free(map->path); - } - free(c->maps); - close(c->ns); - - free(c->exec.id); - for (i = 0; i < c->exec.argc; i++) { - //fprintf(stdout, "argv %d %s\n", i, exec->argv[i]); - free(c->exec.argv[i]); - } - free(c->exec.argv); + for (i = 0; i < c->vols_num; i++) { + vol = &(c->vols[i]); + free(vol->device); + free(vol->mountpoint); + free(vol->fstype); } + free(c->vols); + + for (i = 0; i < c->envs_num; i++) { + env = &(c->envs[i]); + free(env->env); + free(env->value); + } + free(c->envs); + + for (i = 0; i < c->sys_num; i++) { + sys = &(c->sys[i]); + free(sys->path); + free(sys->value); + } + free(c->sys); + + for (i = 0; i < c->maps_num; i++) { + map = &(c->maps[i]); + free(map->source); + free(map->path); + } + free(c->maps); + close(c->ns); + + free(c->exec.id); + for (i = 0; i < c->exec.argc; i++) { + //fprintf(stdout, "argv %d %s\n", i, exec->argv[i]); + free(c->exec.argv[i]); + } + free(c->exec.argv); +} + +void hyper_cleanup_containers(struct hyper_pod *pod) +{ + int i; + + for (i = 0; i < pod->c_num; i++) + hyper_cleanup_container(&pod->c[i]); free(pod->c); pod->c = NULL; diff --git a/src/container.h b/src/container.h index 05b7fdb..85e5575 100644 --- a/src/container.h +++ b/src/container.h @@ -42,6 +42,7 @@ struct hyper_container { int sys_num; int ns; uint32_t code; + struct list_head dyn; struct hyper_exec exec; }; @@ -50,6 +51,7 @@ struct hyper_pod; int hyper_start_container(struct hyper_container *container, int utsns, int ipcns, struct hyper_pod *pod); struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id); -void hyper_cleanup_container(struct hyper_pod *pod); +void hyper_cleanup_container(struct hyper_container *container); +void hyper_cleanup_containers(struct hyper_pod *pod); #endif diff --git a/src/exec.c b/src/exec.c index 84041c8..cbd1a5a 100644 --- a/src/exec.c +++ b/src/exec.c @@ -548,6 +548,15 @@ int hyper_release_exec(struct hyper_exec *exec, if (exec->code) pod->code = exec->code; + if (exec->init == 2) { // dynamic container + struct hyper_container *c = container_of(exec, struct hyper_container, exec); + // TODO send finish of this container and full cleanup + hyper_cleanup_container(c); + list_del(&c->dyn); + free(c); + return 0; + } + if (--pod->remains > 0) return 0; diff --git a/src/hyper.h b/src/hyper.h index b3ed4c9..f7344b4 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -41,6 +41,7 @@ struct hyper_pod { struct hyper_interface *iface; struct hyper_route *rt; char **dns; + struct list_head dyn_containers; struct list_head exec_head; //struct list_head ce_head; char *hostname; diff --git a/src/init.c b/src/init.c index eb078f1..9afe188 100644 --- a/src/init.c +++ b/src/init.c @@ -29,6 +29,7 @@ #include "container.h" struct hyper_pod global_pod = { + .dyn_containers = LIST_HEAD_INIT(global_pod.dyn_containers), .exec_head = LIST_HEAD_INIT(global_pod.exec_head), }; struct hyper_exec *global_exec; @@ -690,6 +691,7 @@ static int hyper_start_pod(char *json, int length) static int hyper_new_container(char *json, int length) { int ret; + struct hyper_container *c; struct hyper_pod *pod = &global_pod; fprintf(stdout, "call hyper_new_container, json %s, len %d\n", json, length); @@ -697,19 +699,21 @@ static int hyper_new_container(char *json, int length) if (!pod->init_pid) fprintf(stdout, "the pod is not created yet\n"); - if (hyper_parse_new_container(pod, json, length) < 0) { + c = hyper_parse_new_container(pod, json, length); + if (c == NULL) { fprintf(stderr, "parse container json failed\n"); return -1; } - ret = hyper_start_container_stage0(&pod->c[pod->c_num - 1], pod); + ret = hyper_start_container_stage0(c, pod); if (ret < 0) { //TODO full grace cleanup - pod->remains -= 1; - pod->c_num -= 1; + hyper_cleanup_container(c); + free(c); return ret; } + list_add_tail(&c->dyn, &pod->dyn_containers); return 0; } @@ -977,7 +981,7 @@ static void hyper_cleanup_shared(struct hyper_pod *pod) void hyper_cleanup_pod(struct hyper_pod *pod) { - hyper_cleanup_container(pod); + hyper_cleanup_containers(pod); hyper_cleanup_network(pod); hyper_cleanup_shared(pod); hyper_cleanup_dns(pod); diff --git a/src/parse.c b/src/parse.c index 113852b..ec902d9 100644 --- a/src/parse.c +++ b/src/parse.c @@ -530,7 +530,7 @@ out: return next; } -int hyper_parse_new_container(struct hyper_pod *pod, char *json, int length) +struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length) { int n; jsmn_parser p; @@ -553,26 +553,24 @@ realloc: goto fail; } - c = realloc(pod->c, (pod->c_num + 1) * sizeof(*pod->c)); + c = calloc(1, sizeof(*c)); if (c == NULL) { fprintf(stdout, "alloc memory for container failed\n"); goto fail; } - pod->c = c; - memset(&pod->c[pod->c_num], 0, sizeof(pod->c[pod->c_num])); // trick: toks-1, TODO: change all "i = 1" to "i = 0" - if (hyper_parse_container(pod, &pod->c[pod->c_num], json, toks-1) < 0) + if (hyper_parse_container(pod, c, json, toks-1) < 0) goto fail; - pod->remains += 1; - pod->c_num += 1; + c->exec.init = 2; // dynamic container type free(toks); - return 0; + return c; fail: free(toks); - return -1; + free(c); + return NULL; } int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length) diff --git a/src/parse.h b/src/parse.h index e4db51e..717895a 100644 --- a/src/parse.h +++ b/src/parse.h @@ -11,6 +11,6 @@ int json_token_streq(char *js, jsmntok_t *t, char *s); int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length); int hyper_parse_write_file(struct hyper_writter *writter, char *json, int length); int hyper_parse_read_file(struct hyper_reader *reader, char *json, int length); -int hyper_parse_new_container(struct hyper_pod *pod, char *json, int length); +struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length); #endif