From c3160aea0a7d54790939c15979933c524aa6682f Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 12 Nov 2015 22:42:15 +0800 Subject: [PATCH 1/8] refactor parsing json Signed-off-by: Gao feng --- src/parse.c | 234 ++++++++++++++++++++++++++++------------------------ 1 file changed, 126 insertions(+), 108 deletions(-) diff --git a/src/parse.c b/src/parse.c index 621379d..967eaf7 100644 --- a/src/parse.c +++ b/src/parse.c @@ -30,7 +30,7 @@ int json_token_streq(char *js, jsmntok_t *t, char *s) static int container_parse_cmd(struct hyper_container *c, char *json, jsmntok_t *toks) { - int i = 1, j; + int i = 0, j; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "cmd need array"); @@ -47,8 +47,8 @@ static int container_parse_cmd(struct hyper_container *c, char *json, jsmntok_t c->exec.argv[c->exec.argc] = NULL; - for (j = 0; j < c->exec.argc; j++) { - i++; + i++; + for (j = 0; j < c->exec.argc; j++, i++) { c->exec.argv[j] = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "container init arg %d %s\n", j, c->exec.argv[j]); } @@ -58,7 +58,7 @@ static int container_parse_cmd(struct hyper_container *c, char *json, jsmntok_t static int container_parse_volumes(struct hyper_container *c, char *json, jsmntok_t *toks) { - int i = 1, j; + int i = 0, j; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "volume need array\n"); @@ -73,17 +73,17 @@ static int container_parse_volumes(struct hyper_container *c, char *json, jsmnto return -1; } + i++; for (j = 0; j < c->vols_num; j++) { int i_volume, next_volume; - i++; if (toks[i].type != JSMN_OBJECT) { fprintf(stdout, "volume array need object\n"); return -1; } next_volume = toks[i].size; - for (i_volume = 0; i_volume < next_volume; i_volume++) { - i++; + i++; + for (i_volume = 0; i_volume < next_volume; i_volume++, i++) { if (json_token_streq(json, &toks[i], "device")) { c->vols[j].device = strdup(json_token_str(json, &toks[++i])); @@ -101,7 +101,9 @@ static int container_parse_volumes(struct hyper_container *c, char *json, jsmnto c->vols[j].readonly = 1; fprintf(stdout, "volume %d readonly %d\n", j, c->vols[j].readonly); } else { - fprintf(stdout, "in voulmes incorrect %s\n", json_token_str(json, &toks[i])); + fprintf(stdout, "get unknown section %s in voulmes\n", + json_token_str(json, &toks[i])); + return -1; } } } @@ -111,7 +113,7 @@ static int container_parse_volumes(struct hyper_container *c, char *json, jsmnto static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_t *toks) { - int i = 1, j; + int i = 0, j; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "envs need array\n"); @@ -127,17 +129,17 @@ static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_ return -1; } + i++; for (j = 0; j < c->maps_num; j++) { int i_map, next_map; - i++; if (toks[i].type != JSMN_OBJECT) { fprintf(stdout, "fsmap array need object\n"); return -1; } next_map = toks[i].size; - for (i_map = 0; i_map < next_map; i_map++) { - i++; + i++; + for (i_map = 0; i_map < next_map; i_map++, i++) { if (json_token_streq(json, &toks[i], "source")) { c->maps[j].source = strdup(json_token_str(json, &toks[++i])); @@ -153,6 +155,7 @@ static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_ } else { fprintf(stdout, "in maps incorrect %s\n", json_token_str(json, &toks[i])); + return -1; } } } @@ -162,7 +165,7 @@ static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_ static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t *toks) { - int i = 1, j; + int i = 0, j; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "encs need array\n"); @@ -178,17 +181,17 @@ static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t return -1; } + i++; for (j = 0; j < c->envs_num; j++) { int i_env, next_env; - i++; if (toks[i].type != JSMN_OBJECT) { fprintf(stdout, "env array need object\n"); return -1; } next_env = toks[i].size; - for (i_env = 0; i_env < next_env; i_env++) { - i++; + i++; + for (i_env = 0; i_env < next_env; i_env++, i++) { if (json_token_streq(json, &toks[i], "env")) { c->envs[j].env = strdup(json_token_str(json, &toks[++i])); @@ -198,7 +201,9 @@ static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "envs %d value %s\n", j, c->envs[j].value); } else { - fprintf(stdout, "in envs incorrect %s\n", json_token_str(json, &toks[i])); + fprintf(stdout, "get unknown section %s in envs\n", + json_token_str(json, &toks[i])); + return -1; } } } @@ -208,7 +213,7 @@ static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t static int container_parse_sysctl(struct hyper_container *c, char *json, jsmntok_t *toks) { - int i = 1, j; + int i = 0, j; char *p; if (toks[i].type != JSMN_OBJECT) { @@ -225,6 +230,7 @@ static int container_parse_sysctl(struct hyper_container *c, char *json, jsmntok return -1; } + i++; for (j = 0; j < c->sys_num; j++) { c->sys[j].path = strdup(json_token_str(json, &toks[++i])); while((p = strchr(c->sys[j].path, '.')) != NULL) { @@ -240,7 +246,7 @@ static int container_parse_sysctl(struct hyper_container *c, char *json, jsmntok static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container *c, char *json, jsmntok_t *toks) { - int i = 1, j, next, next_container; + int i = 0, j, next, next_container; jsmntok_t *t; if (toks[i].type != JSMN_OBJECT) { @@ -258,76 +264,71 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * next_container = toks[i].size; fprintf(stdout, "next container %d\n", next_container); - + i++; for (j = 0; j < next_container; j++) { - i++; t = &toks[i]; fprintf(stdout, "%d name %s\n", i, json_token_str(json, t)); if (json_token_streq(json, t, "id") && t->size == 1) { - i++; - c->id = strdup(json_token_str(json, &toks[i])); + c->id = strdup(json_token_str(json, &toks[++i])); c->exec.id = strdup(c->id); fprintf(stdout, "container id %s\n", c->id); + i++; } else if (json_token_streq(json, t, "cmd") && t->size == 1) { - next = container_parse_cmd(c, json, &toks[i]); + next = container_parse_cmd(c, json, &toks[++i]); if (next < 0) return -1; i += next; } else if (json_token_streq(json, t, "rootfs") && t->size == 1) { - i++; - c->rootfs = strdup(json_token_str(json, &toks[i])); + c->rootfs = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "container rootfs %s\n", c->rootfs); + i++; } else if (json_token_streq(json, t, "tty") && t->size == 1) { - i++; - c->exec.seq = json_token_ll(json, &toks[i]); + c->exec.seq = json_token_ll(json, &toks[++i]); fprintf(stdout, "container seq %" PRIu64 "\n", c->exec.seq); + i++; } else if (json_token_streq(json, t, "stderr") && t->size == 1) { - i++; - c->exec.errseq = json_token_ll(json, &toks[i]); + c->exec.errseq = json_token_ll(json, &toks[++i]); fprintf(stdout, "container stderr seq %" PRIu64 "\n", c->exec.errseq); + i++; } else if (json_token_streq(json, t, "workdir") && t->size == 1) { - i++; - c->workdir = strdup(json_token_str(json, &toks[i])); + c->workdir = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "container workdir %s\n", c->workdir); + i++; } else if (json_token_streq(json, t, "image") && t->size == 1) { - i++; - c->image = strdup(json_token_str(json, &toks[i])); + c->image = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "container image %s\n", c->image); - } else if (json_token_streq(json, t, "fstype") && t->size == 1) { i++; - c->fstype = strdup(json_token_str(json, &toks[i])); + } else if (json_token_streq(json, t, "fstype") && t->size == 1) { + c->fstype = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "container fstype %s\n", c->fstype); + i++; } else if (json_token_streq(json, t, "volumes") && t->size == 1) { - next = container_parse_volumes(c, json, &toks[i]); + next = container_parse_volumes(c, json, &toks[++i]); if (next < 0) return -1; i += next; } else if (json_token_streq(json, t, "fsmap") && t->size == 1) { - next = container_parse_fsmap(c, json, &toks[i]); + next = container_parse_fsmap(c, json, &toks[++i]); if (next < 0) return -1; i += next; } else if (json_token_streq(json, t, "envs") && t->size == 1) { - next = container_parse_envs(c, json, &toks[i]); + next = container_parse_envs(c, json, &toks[++i]); if (next < 0) return -1; i += next; } else if (json_token_streq(json, t, "sysctl") && t->size == 1) { - next = container_parse_sysctl(c, json, &toks[i]); + next = container_parse_sysctl(c, json, &toks[++i]); if (next < 0) return -1; i += next; } else if (json_token_streq(json, t, "restartPolicy") && t->size == 1) { + fprintf(stdout, "restart policy %s\n", json_token_str(json, &toks[++i])); i++; -/* - if (json_token_streq(json, &toks[i], "always") && t->size == 1) - c->exec.flags = POLICY_ALWAYS; - else if (json_token_streq(json, &toks[i], "onFailure") && t->size == 1) - c->exec.flags = POLICY_ONFAILURE; - else - c->exec.flags = POLICY_NEVER; -*/ - fprintf(stdout, "restartPolicy %s\n", json_token_str(json, &toks[i])); + } else { + fprintf(stdout, "get unknown section %s in container\n", + json_token_str(json, t)); + return -1; } } @@ -336,7 +337,7 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t *toks) { - int i = 1, j, next; + int i = 0, j, next; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "format incorrect\n"); @@ -352,6 +353,7 @@ static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t * return -1; } + i++; for (j = 0; j < pod->c_num; j++) { next = hyper_parse_container(pod, &pod->c[j], json, toks + i); if (next < 0) @@ -365,7 +367,7 @@ static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t * static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t *toks) { - int i = 1, j, next_if; + int i = 0, j, next_if; struct hyper_interface *iface; if (toks[i].type != JSMN_ARRAY) { @@ -382,19 +384,19 @@ static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t * return -1; } + i++; for (j = 0; j < pod->i_num; j++) { int i_if; - iface = &pod->iface[j]; - i++; + if (toks[i].type != JSMN_OBJECT) { fprintf(stdout, "network array need object\n"); return -1; } next_if = toks[i].size; - for (i_if = 0; i_if < next_if; i_if++) { - i++; + i++; + for (i_if = 0; i_if < next_if; i_if++, i++) { if (json_token_streq(json, &toks[i], "device")) { iface->device = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "net device is %s\n", iface->device); @@ -404,6 +406,10 @@ static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t * } else if (json_token_streq(json, &toks[i], "netMask")) { iface->mask = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "net mask is %s\n", iface->mask); + } else { + fprintf(stderr, "get unknown section %s in interfaces\n", + json_token_str(json, &toks[i])); + return -1; } } } @@ -413,7 +419,7 @@ static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t * static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks) { - int i = 1, j, next_rt; + int i = 0, j, next_rt; struct hyper_route *rt; if (toks[i].type != JSMN_ARRAY) { @@ -430,19 +436,19 @@ static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks return -1; } + i++; for (j = 0; j < pod->r_num; j++) { int i_rt; rt = &pod->rt[j]; - i++; if (toks[i].type != JSMN_OBJECT) { fprintf(stdout, "routes array need object\n"); return -1; } next_rt = toks[i].size; - for (i_rt = 0; i_rt < next_rt; i_rt++) { - i++; + i++; + for (i_rt = 0; i_rt < next_rt; i_rt++, i++) { if (json_token_streq(json, &toks[i], "dest")) { rt->dst = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "route %d dest is %s\n", j, rt->dst); @@ -452,6 +458,10 @@ static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks } else if (json_token_streq(json, &toks[i], "device")) { rt->device = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "route %d device is %s\n", j, rt->device); + } else { + fprintf(stderr, "get unknown section %s in routes\n", + json_token_str(json, &toks[i])); + return -1; } } } @@ -461,7 +471,7 @@ static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks static int hyper_parse_dns(struct hyper_pod *pod, char *json, jsmntok_t *toks) { - int i = 1, j; + int i = 0, j; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "Dns format incorrect\n"); @@ -477,8 +487,9 @@ static int hyper_parse_dns(struct hyper_pod *pod, char *json, jsmntok_t *toks) return -1; } - for (j = 0; j < pod->d_num; j++) { - pod->dns[j] = strdup(json_token_str(json, &toks[++i])); + i++; + for (j = 0; j < pod->d_num; j++, i++) { + pod->dns[j] = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "pod dns %d: %s\n", j, pod->dns[j]); } @@ -516,34 +527,36 @@ realloc: fprintf(stdout, "jsmn parse successed, n is %d\n", n); next = 0; - for (i = 0; i < n; i++) { + for (i = 0; i < n;) { jsmntok_t *t = &toks[i]; fprintf(stdout, "token %d, type is %d, size is %d\n", i, t->type, t->size); - if (t->type != JSMN_STRING) + if (t->type != JSMN_STRING) { + i++; continue; + } if (json_token_streq(json, t, "containers") && t->size == 1) { - next = hyper_parse_containers(pod, json, t); + next = hyper_parse_containers(pod, json, &toks[++i]); if (next < 0) goto out; i += next; } else if (json_token_streq(json, t, "interfaces") && t->size == 1) { - next = hyper_parse_interfaces(pod, json, t); + next = hyper_parse_interfaces(pod, json, &toks[++i]); if (next < 0) goto out; i += next; } else if (json_token_streq(json, t, "routes") && t->size == 1) { - next = hyper_parse_routes(pod, json, t); + next = hyper_parse_routes(pod, json, &toks[++i]); if (next < 0) goto out; i += next; } else if (json_token_streq(json, t, "dns") && t->size == 1) { - next = hyper_parse_dns(pod, json, t); + next = hyper_parse_dns(pod, json, &toks[++i]); if (next < 0) goto out; @@ -551,16 +564,24 @@ realloc: } else if (json_token_streq(json, t, "shareDir") && t->size == 1) { pod->share_tag = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "share tag is %s\n", pod->share_tag); + i++; } else if (json_token_streq(json, t, "hostname") && t->size == 1) { pod->hostname = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "hostname is %s\n", pod->hostname); + i++; } else if (json_token_streq(json, t, "restartPolicy") && t->size == 1) { i++; - if (json_token_streq(json, &toks[i], "always") && t->size == 1) + if (json_token_streq(json, &toks[i], "always") && toks[i].size == 1) pod->policy = POLICY_ALWAYS; - else if (json_token_streq(json, &toks[i], "onFailure") && t->size == 1) + else if (json_token_streq(json, &toks[i], "onFailure") && toks[i].size == 1) pod->policy = POLICY_ONFAILURE; fprintf(stdout, "restartPolicy is %" PRIu8 "\n", pod->policy); + i++; + } else { + fprintf(stdout, "get unknown section %s in pod\n", + json_token_str(json, &toks[i])); + next = -1; + break; } } @@ -602,8 +623,7 @@ realloc: goto fail; } - // trick: toks-1, TODO: change all "i = 1" to "i = 0" - if (hyper_parse_container(pod, c, json, toks-1) < 0) + if (hyper_parse_container(pod, c, json, toks) < 0) goto fail; c->exec.init = 2; // dynamic container type @@ -618,7 +638,7 @@ fail: int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length) { - int i, n, ret = 0; + int i, n, ret = -1; jsmn_parser p; int toks_num = 10; jsmntok_t *toks = NULL; @@ -627,7 +647,7 @@ realloc: toks = realloc(toks, toks_num * sizeof(jsmntok_t)); if (toks == NULL) { fprintf(stderr, "allocate tokens for winsize failed\n"); - goto fail; + goto out; } jsmn_init(&p); @@ -640,7 +660,7 @@ realloc: goto realloc; } - goto fail; + goto out; } for (i = 0; i < n; i++) { @@ -650,31 +670,35 @@ realloc: continue; if (i++ == n) - goto fail; + goto out; + if (json_token_streq(json, t, "tty")) { if (toks[i].type != JSMN_STRING) - goto fail; + goto out; ws->tty = strdup(json_token_str(json, &toks[i])); } else if (json_token_streq(json, t, "seq")) { if (toks[i].type != JSMN_PRIMITIVE) - goto fail; + goto out; ws->seq = json_token_ll(json, &toks[i]); } else if (json_token_streq(json, t, "row")) { if (toks[i].type != JSMN_PRIMITIVE) - goto fail; + goto out; ws->row = json_token_int(json, &toks[i]); } else if (json_token_streq(json, t, "column")) { if (toks[i].type != JSMN_PRIMITIVE) - goto fail; + goto out; ws->column = json_token_int(json, &toks[i]); + } else { + fprintf(stderr, "get unknown section %s in winsize\n", + json_token_str(json, t)); + goto out; } } + + ret = 0; out: free(toks); return ret; -fail: - ret = -1; - goto out; } struct hyper_exec *hyper_parse_execcmd(char *json, int length) @@ -723,22 +747,14 @@ realloc: continue; if (json_token_streq(json, t, "container")) { - if (i++ == n) - goto fail; - - exec->id = strdup(json_token_str(json, &toks[i])); + exec->id = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "get container %s\n", exec->id); } else if (json_token_streq(json, t, "seq")) { - if (i++ == n) - goto fail; has_seq = 1; - exec->seq = json_token_ll(json, &toks[i]); + exec->seq = json_token_ll(json, &toks[++i]); fprintf(stdout, "get seq %"PRIu64"\n", exec->seq); } else if (json_token_streq(json, t, "cmd")) { - if (i++ == n) - goto fail; - - if (toks[i].type != JSMN_ARRAY) { + if (toks[++i].type != JSMN_ARRAY) { fprintf(stdout, "execcmd need array\n"); goto fail; } @@ -753,6 +769,10 @@ realloc: } else if (j < exec->argc) { exec->argv[j++] = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "argv %d, %s\n", j - 1, exec->argv[j - 1]); + } else { + fprintf(stderr, "get unknown section %s in exec cmd\n", + json_token_str(json, t)); + goto fail; } } @@ -817,20 +837,19 @@ int hyper_parse_write_file(struct hyper_writter *writter, char *json, int length if (t->type != JSMN_STRING) continue; - if (json_token_streq(json, t, "container")) { - if (i++ == n) - goto fail; + if (i++ == n) + goto fail; + if (json_token_streq(json, t, "container")) { writter->id = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "writefile get container %s\n", writter->id); } else if (json_token_streq(json, t, "file")) { - if (i++ == n) - goto fail; - writter->file = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "writefile get file %s\n", writter->file); } else { - fprintf(stderr, "in writefile incorrect %s\n", json_token_str(json, &toks[i])); + fprintf(stderr, "get unknown section %s in writefile\n", + json_token_str(json, t)); + goto fail; } } @@ -881,20 +900,19 @@ int hyper_parse_read_file(struct hyper_reader *reader, char *json, int length) if (t->type != JSMN_STRING) continue; - if (json_token_streq(json, t, "container")) { - if (i++ == n) - goto fail; + if (i++ == n) + goto fail; + if (json_token_streq(json, t, "container")) { reader->id = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "readfile get container %s\n", reader->id); } else if (json_token_streq(json, t, "file")) { - if (i++ == n) - goto fail; - reader->file = strdup(json_token_str(json, &toks[i])); fprintf(stdout, "readfile get file %s\n", reader->file); } else { - fprintf(stdout, "in readfile incorrect %s\n", json_token_str(json, &toks[i])); + fprintf(stdout, "get unknown section %s in readfile\n", + json_token_str(json, t)); + goto fail; } } From 25da342f75d2315a294d9ec18550c9639189cdcd Mon Sep 17 00:00:00 2001 From: Gao feng Date: Thu, 12 Nov 2015 23:26:58 +0800 Subject: [PATCH 2/8] introduce hyper_free_container Signed-off-by: Gao feng --- src/container.c | 20 +++++++++++++------- src/container.h | 1 + 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/container.c b/src/container.c index beb6b3d..f376e84 100644 --- a/src/container.c +++ b/src/container.c @@ -599,18 +599,13 @@ struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id) return NULL; } -void hyper_cleanup_container(struct hyper_container *c) +void hyper_free_container(struct hyper_container *c) { int i; struct volume *vol; struct env *env; struct fsmap *map; struct sysctl *sys; - char root[512]; - - 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); @@ -646,7 +641,6 @@ void hyper_cleanup_container(struct hyper_container *c) free(map->path); } free(c->maps); - close(c->ns); free(c->exec.id); for (i = 0; i < c->exec.argc; i++) { @@ -656,6 +650,18 @@ void hyper_cleanup_container(struct hyper_container *c) free(c->exec.argv); } +void hyper_cleanup_container(struct hyper_container *c) +{ + char root[512]; + + sprintf(root, "/tmp/hyper/%s/devpts/", c->id); + if (umount(root) < 0 && umount2(root, MNT_DETACH)) + perror("umount devpts failed"); + + close(c->ns); + hyper_free_container(c); +} + void hyper_cleanup_containers(struct hyper_pod *pod) { int i; diff --git a/src/container.h b/src/container.h index 85e5575..1da5327 100644 --- a/src/container.h +++ b/src/container.h @@ -53,5 +53,6 @@ int hyper_start_container(struct hyper_container *container, struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id); void hyper_cleanup_container(struct hyper_container *container); void hyper_cleanup_containers(struct hyper_pod *pod); +void hyper_free_container(struct hyper_container *c); #endif From a46092a90aff0115f7441de3868c417d15c92e05 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 Nov 2015 11:59:43 +0800 Subject: [PATCH 3/8] free allocated memory in parse_container Signed-off-by: Gao feng --- src/container.c | 52 +-------------- src/parse.c | 169 +++++++++++++++++++++++++++++++++++++++--------- src/parse.h | 1 + 3 files changed, 139 insertions(+), 83 deletions(-) diff --git a/src/container.c b/src/container.c index f376e84..decd47c 100644 --- a/src/container.c +++ b/src/container.c @@ -16,6 +16,7 @@ #include "util.h" #include "hyper.h" +#include "parse.h" static int container_setup_volume(struct hyper_container *container) { @@ -599,57 +600,6 @@ struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id) return NULL; } -void hyper_free_container(struct hyper_container *c) -{ - int i; - struct volume *vol; - struct env *env; - struct fsmap *map; - struct sysctl *sys; - - free(c->id); - free(c->rootfs); - free(c->image); - free(c->workdir); - free(c->fstype); - - 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); - - 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_container(struct hyper_container *c) { char root[512]; diff --git a/src/parse.c b/src/parse.c index 967eaf7..31fb2de 100644 --- a/src/parse.c +++ b/src/parse.c @@ -37,15 +37,14 @@ static int container_parse_cmd(struct hyper_container *c, char *json, jsmntok_t return -1; } - c->exec.argc = toks[i].size; - - c->exec.argv = calloc(c->exec.argc + 1, sizeof(*c->exec.argv)); + c->exec.argv = calloc(toks[i].size + 1, sizeof(*c->exec.argv)); if (c->exec.argv == NULL) { fprintf(stderr, "allocate memory for exec argv failed\n"); return -1; } c->exec.argv[c->exec.argc] = NULL; + c->exec.argc = toks[i].size; i++; for (j = 0; j < c->exec.argc; j++, i++) { @@ -56,6 +55,33 @@ static int container_parse_cmd(struct hyper_container *c, char *json, jsmntok_t return i; } +static void container_free_cmd(struct hyper_container *c) +{ + int i; + + for (i = 0; i < c->exec.argc; i++) { + free(c->exec.argv[i]); + } + + free(c->exec.argv); + c->exec.argv = NULL; + c->exec.argc = 0; +} + +static void container_free_volumes(struct hyper_container *c) +{ + int i; + + for (i = 0; i < c->vols_num; i++) { + free(c->vols[i].device); + free(c->vols[i].mountpoint); + free(c->vols[i].fstype); + } + free(c->vols); + c->vols = NULL; + c->vols_num = 0; +} + static int container_parse_volumes(struct hyper_container *c, char *json, jsmntok_t *toks) { int i = 0, j; @@ -64,15 +90,16 @@ static int container_parse_volumes(struct hyper_container *c, char *json, jsmnto fprintf(stdout, "volume need array\n"); return -1; } - c->vols_num = toks[i].size; - fprintf(stdout, "volumes num %d\n", c->vols_num); - c->vols = calloc(c->vols_num, sizeof(*c->vols)); + c->vols = calloc(toks[i].size, sizeof(*c->vols)); if (c->vols == NULL) { fprintf(stderr, "allocate memory for volume failed\n"); return -1; } + c->vols_num = toks[i].size; + fprintf(stdout, "volumes num %d\n", c->vols_num); + i++; for (j = 0; j < c->vols_num; j++) { int i_volume, next_volume; @@ -111,6 +138,19 @@ static int container_parse_volumes(struct hyper_container *c, char *json, jsmnto return i; } +void container_free_fsmap(struct hyper_container *c) +{ + int i; + + for (i = 0; i < c->maps_num; i++) { + free(c->maps[i].source); + free(c->maps[i].path); + } + free(c->maps); + c->maps = NULL; + c->maps_num = 0; +} + static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_t *toks) { int i = 0, j; @@ -120,15 +160,15 @@ static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_ return -1; } - c->maps_num = toks[i].size; - fprintf(stdout, "fsmap num %d\n", c->maps_num); - - c->maps = calloc(c->maps_num, sizeof(*c->maps)); + c->maps = calloc(toks[i].size, sizeof(*c->maps)); if (c->maps == NULL) { fprintf(stderr, "allocate memory for fsmap failed\n"); return -1; } + c->maps_num = toks[i].size; + fprintf(stdout, "fsmap num %d\n", c->maps_num); + i++; for (j = 0; j < c->maps_num; j++) { int i_map, next_map; @@ -163,6 +203,20 @@ static int container_parse_fsmap(struct hyper_container *c, char *json, jsmntok_ return i; } +static void container_free_envs(struct hyper_container *c) +{ + int i; + + for (i = 0; i < c->envs_num; i++) { + free(c->envs[i].env); + free(c->envs[i].value); + } + + free(c->envs); + c->envs = NULL; + c->envs_num = 0; +} + static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t *toks) { int i = 0, j; @@ -172,15 +226,15 @@ static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t return -1; } - c->envs_num = toks[i].size; - fprintf(stdout, "envs num %d\n", c->envs_num); - - c->envs = calloc(c->envs_num, sizeof(*c->envs)); + c->envs = calloc(toks[i].size, sizeof(*c->envs)); if (c->envs == NULL) { fprintf(stderr, "allocate memory for env failed\n"); return -1; } + c->envs_num = toks[i].size; + fprintf(stdout, "envs num %d\n", c->envs_num); + i++; for (j = 0; j < c->envs_num; j++) { int i_env, next_env; @@ -211,6 +265,20 @@ static int container_parse_envs(struct hyper_container *c, char *json, jsmntok_t return i; } +static void container_free_sysctl(struct hyper_container *c) +{ + int i; + + for (i = 0; i < c->sys_num; i++) { + free(c->sys[i].path); + free(c->sys[i].value); + } + + free(c->sys); + c->sys = NULL; + c->sys_num = 0; +} + static int container_parse_sysctl(struct hyper_container *c, char *json, jsmntok_t *toks) { int i = 0, j; @@ -221,15 +289,15 @@ static int container_parse_sysctl(struct hyper_container *c, char *json, jsmntok return -1; } - c->sys_num = toks[i].size; - fprintf(stdout, "sysctl size %d\n", c->sys_num); - - c->sys = calloc(c->sys_num, sizeof(*c->sys)); + c->sys = calloc(toks[i].size, sizeof(*c->sys)); if (c->sys == NULL) { fprintf(stderr, "allocate memory for sysctl failed\n"); return -1; } + c->sys_num = toks[i].size; + fprintf(stdout, "sysctl size %d\n", c->sys_num); + i++; for (j = 0; j < c->sys_num; j++) { c->sys[j].path = strdup(json_token_str(json, &toks[++i])); @@ -242,9 +310,35 @@ static int container_parse_sysctl(struct hyper_container *c, char *json, jsmntok return i; } +void hyper_free_container(struct hyper_container *c) +{ + free(c->id); + c->id = NULL; + + free(c->rootfs); + c->rootfs = NULL; + + free(c->image); + c->image = NULL; + + free(c->workdir); + c->workdir = NULL; + + free(c->fstype); + c->fstype = NULL; + + free(c->exec.id); + c->exec.id = NULL; + + container_free_volumes(c); + container_free_envs(c); + container_free_sysctl(c); + container_free_fsmap(c); + container_free_cmd(c); +} static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container *c, - char *json, jsmntok_t *toks) + char *json, jsmntok_t *toks) { int i = 0, j, next, next_container; jsmntok_t *t; @@ -276,7 +370,7 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * } else if (json_token_streq(json, t, "cmd") && t->size == 1) { next = container_parse_cmd(c, json, &toks[++i]); if (next < 0) - return -1; + goto fail; i += next; } else if (json_token_streq(json, t, "rootfs") && t->size == 1) { c->rootfs = strdup(json_token_str(json, &toks[++i])); @@ -305,22 +399,22 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * } else if (json_token_streq(json, t, "volumes") && t->size == 1) { next = container_parse_volumes(c, json, &toks[++i]); if (next < 0) - return -1; + goto fail; i += next; } else if (json_token_streq(json, t, "fsmap") && t->size == 1) { next = container_parse_fsmap(c, json, &toks[++i]); if (next < 0) - return -1; + goto fail; i += next; } else if (json_token_streq(json, t, "envs") && t->size == 1) { next = container_parse_envs(c, json, &toks[++i]); if (next < 0) - return -1; + goto fail; i += next; } else if (json_token_streq(json, t, "sysctl") && t->size == 1) { next = container_parse_sysctl(c, json, &toks[++i]); if (next < 0) - return -1; + goto fail; i += next; } else if (json_token_streq(json, t, "restartPolicy") && t->size == 1) { fprintf(stdout, "restart policy %s\n", json_token_str(json, &toks[++i])); @@ -328,41 +422,52 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * } else { fprintf(stdout, "get unknown section %s in container\n", json_token_str(json, t)); - return -1; + goto fail; } } return i; + +fail: + hyper_free_container(c); + return -1; } static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t *toks) { - int i = 0, j, next; + int i = 0, j = 0, next; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "format incorrect\n"); return -1; } - pod->remains = pod->c_num = toks[i].size; - fprintf(stdout, "container count %d\n", pod->c_num); - - pod->c = calloc(pod->c_num, sizeof(*pod->c)); + pod->c = calloc(toks[i].size, sizeof(*pod->c)); if (pod->c == NULL) { fprintf(stdout, "alloc memory for container failed\n"); - return -1; + goto fail; } + pod->remains = pod->c_num = toks[i].size; + fprintf(stdout, "container count %d\n", pod->c_num); + i++; for (j = 0; j < pod->c_num; j++) { next = hyper_parse_container(pod, &pod->c[j], json, toks + i); if (next < 0) - return -1; + goto fail; i += next; } return i; +fail: + for (; j > 0; j--) + hyper_free_container(&pod->c[j]); + + free(pod->c); + pod->c = NULL; + return -1; } static int hyper_parse_interfaces(struct hyper_pod *pod, char *json, jsmntok_t *toks) diff --git a/src/parse.h b/src/parse.h index 717895a..24c75dd 100644 --- a/src/parse.h +++ b/src/parse.h @@ -12,5 +12,6 @@ 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); struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length); +void hyper_free_container(struct hyper_container *c); #endif From 6d3265a7fb3c4db6d2f14f3dcdfcfa7ffd2d3069 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 Nov 2015 14:44:36 +0800 Subject: [PATCH 4/8] free tty of winsize is parse failed Signed-off-by: Gao feng --- src/parse.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/parse.c b/src/parse.c index 31fb2de..04fbca2 100644 --- a/src/parse.c +++ b/src/parse.c @@ -748,6 +748,7 @@ int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length) int toks_num = 10; jsmntok_t *toks = NULL; + memset(ws, 0, sizeof(*ws)); realloc: toks = realloc(toks, toks_num * sizeof(jsmntok_t)); if (toks == NULL) { @@ -775,28 +776,28 @@ realloc: continue; if (i++ == n) - goto out; + goto fail; if (json_token_streq(json, t, "tty")) { if (toks[i].type != JSMN_STRING) - goto out; + goto fail; ws->tty = strdup(json_token_str(json, &toks[i])); } else if (json_token_streq(json, t, "seq")) { if (toks[i].type != JSMN_PRIMITIVE) - goto out; + goto fail; ws->seq = json_token_ll(json, &toks[i]); } else if (json_token_streq(json, t, "row")) { if (toks[i].type != JSMN_PRIMITIVE) - goto out; + goto fail; ws->row = json_token_int(json, &toks[i]); } else if (json_token_streq(json, t, "column")) { if (toks[i].type != JSMN_PRIMITIVE) - goto out; + goto fail; ws->column = json_token_int(json, &toks[i]); } else { fprintf(stderr, "get unknown section %s in winsize\n", json_token_str(json, t)); - goto out; + goto fail; } } @@ -804,6 +805,10 @@ realloc: out: free(toks); return ret; +fail: + free(ws->tty); + ws->tty = NULL; + goto out; } struct hyper_exec *hyper_parse_execcmd(char *json, int length) From 0c997dbe8581f17edffee182f55ec6e45a889e7e Mon Sep 17 00:00:00 2001 From: Gao feng Date: Fri, 13 Nov 2015 16:32:12 +0800 Subject: [PATCH 5/8] use list to store containers Signed-off-by: Gao feng --- src/container.c | 33 +++++++++----------------------- src/container.h | 2 +- src/exec.c | 2 -- src/hyper.h | 3 +-- src/init.c | 21 ++++++++++---------- src/parse.c | 51 +++++++++++++++++++++++++------------------------ src/util.c | 20 ++++++++++++++----- 7 files changed, 62 insertions(+), 70 deletions(-) diff --git a/src/container.c b/src/container.c index decd47c..60c678c 100644 --- a/src/container.c +++ b/src/container.c @@ -572,29 +572,16 @@ fail: struct hyper_container *hyper_find_container(struct hyper_pod *pod, char *id) { - int i; - struct hyper_container *container; + struct hyper_container *c; - for (i = 0; i < pod->c_num; i++) { - container = &pod->c[i]; - - if (strlen(container->id) != strlen(id)) + list_for_each_entry(c, &pod->containers, list) { + if (strlen(c->id) != strlen(id)) continue; - if (strncmp(container->id, id, strlen(id))) + if (strncmp(c->id, id, strlen(id))) continue; - 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 c; } return NULL; @@ -614,12 +601,10 @@ void hyper_cleanup_container(struct hyper_container *c) void hyper_cleanup_containers(struct hyper_pod *pod) { - int i; + struct hyper_container *c, *n; - for (i = 0; i < pod->c_num; i++) - hyper_cleanup_container(&pod->c[i]); + list_for_each_entry_safe(c, n, &pod->containers, list) + hyper_cleanup_container(c); - free(pod->c); - pod->c = NULL; - pod->c_num = 0; + pod->remains = 0; } diff --git a/src/container.h b/src/container.h index 1da5327..a74f963 100644 --- a/src/container.h +++ b/src/container.h @@ -42,7 +42,7 @@ struct hyper_container { int sys_num; int ns; uint32_t code; - struct list_head dyn; + struct list_head list; struct hyper_exec exec; }; diff --git a/src/exec.c b/src/exec.c index ae4e5de..14d51e1 100644 --- a/src/exec.c +++ b/src/exec.c @@ -549,8 +549,6 @@ int hyper_release_exec(struct hyper_exec *exec, 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; } diff --git a/src/hyper.h b/src/hyper.h index f4f45bf..8142c48 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -41,12 +41,11 @@ struct hyper_pod { struct hyper_interface *iface; struct hyper_route *rt; char **dns; - struct list_head dyn_containers; + struct list_head containers; struct list_head exec_head; char *hostname; char *share_tag; int init_pid; - uint32_t c_num; uint32_t i_num; uint32_t r_num; uint32_t e_num; diff --git a/src/init.c b/src/init.c index 3eeba6b..2cb20b8 100644 --- a/src/init.c +++ b/src/init.c @@ -29,7 +29,7 @@ #include "container.h" struct hyper_pod global_pod = { - .dyn_containers = LIST_HEAD_INIT(global_pod.dyn_containers), + .containers = LIST_HEAD_INIT(global_pod.containers), .exec_head = LIST_HEAD_INIT(global_pod.exec_head), }; struct hyper_exec *global_exec; @@ -144,6 +144,7 @@ static void hyper_term_all(struct hyper_pod *pod) DIR *dp; struct dirent *de; pid_t *pids = NULL; + struct hyper_container *c; dp = opendir("/proc"); if (dp == NULL) @@ -175,9 +176,8 @@ static void hyper_term_all(struct hyper_pod *pod) free(pids); closedir(dp); - for (index = 0; index < pod->c_num; index++) { - hyper_kill_process(pod->c[index].exec.pid); - } + list_for_each_entry(c, &pod->containers, list) + hyper_kill_process(c->exec.pid); } static int hyper_handle_exit(struct hyper_pod *pod) @@ -466,13 +466,13 @@ out: int hyper_start_containers(struct hyper_pod *pod) { - int i, ret = 0; + struct hyper_container *c; - for (i = 0; i < pod->c_num; i++) { - ret = hyper_start_container_stage0(&pod->c[i], pod); - if (ret) - return ret; + list_for_each_entry(c, &pod->containers, list) { + if (hyper_start_container_stage0(c, pod) < 0) + return -1; } + return 0; } @@ -709,11 +709,10 @@ static int hyper_new_container(char *json, int length) if (ret < 0) { //TODO full grace cleanup hyper_cleanup_container(c); - free(c); return ret; } - list_add_tail(&c->dyn, &pod->dyn_containers); + list_add_tail(&c->list, &pod->containers); return 0; } diff --git a/src/parse.c b/src/parse.c index 04fbca2..3cf7869 100644 --- a/src/parse.c +++ b/src/parse.c @@ -335,12 +335,16 @@ void hyper_free_container(struct hyper_container *c) container_free_sysctl(c); container_free_fsmap(c); container_free_cmd(c); + + list_del_init(&c->list); + free(c); } -static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container *c, +static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container **container, char *json, jsmntok_t *toks) { int i = 0, j, next, next_container; + struct hyper_container *c = NULL; jsmntok_t *t; if (toks[i].type != JSMN_OBJECT) { @@ -348,6 +352,12 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * return -1; } + c = calloc(1, sizeof(*c)); + if (c == NULL) { + fprintf(stdout, "alloc memory for container failed\n"); + return -1; + } + c->exec.init = 1; c->exec.code = -1; c->exec.e.fd = -1; @@ -355,6 +365,7 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * c->exec.ptyfd = -1; c->exec.errfd = -1; c->ns = -1; + INIT_LIST_HEAD(&c->list); next_container = toks[i].size; fprintf(stdout, "next container %d\n", next_container); @@ -426,47 +437,44 @@ static int hyper_parse_container(struct hyper_pod *pod, struct hyper_container * } } + *container = c; return i; - fail: hyper_free_container(c); + *container = NULL; return -1; } static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t *toks) { - int i = 0, j = 0, next; + int i = 0, j = 0, next, c_num; + struct hyper_container *c, *n; if (toks[i].type != JSMN_ARRAY) { fprintf(stdout, "format incorrect\n"); return -1; } - pod->c = calloc(toks[i].size, sizeof(*pod->c)); - if (pod->c == NULL) { - fprintf(stdout, "alloc memory for container failed\n"); - goto fail; - } - - pod->remains = pod->c_num = toks[i].size; - fprintf(stdout, "container count %d\n", pod->c_num); + c_num = toks[i].size; + fprintf(stdout, "container count %d\n", c_num); i++; - for (j = 0; j < pod->c_num; j++) { - next = hyper_parse_container(pod, &pod->c[j], json, toks + i); + for (j = 0; j < c_num; j++) { + next = hyper_parse_container(pod, &c, json, toks + i); if (next < 0) goto fail; + /* Pod created containers, Add to list immediately */ + list_add_tail(&c->list, &pod->containers); i += next; } + pod->remains = c_num; return i; fail: - for (; j > 0; j--) - hyper_free_container(&pod->c[j]); + list_for_each_entry_safe(c, n, &pod->containers, list) + hyper_free_container(c); - free(pod->c); - pod->c = NULL; return -1; } @@ -722,13 +730,7 @@ realloc: goto fail; } - c = calloc(1, sizeof(*c)); - if (c == NULL) { - fprintf(stdout, "alloc memory for container failed\n"); - goto fail; - } - - if (hyper_parse_container(pod, c, json, toks) < 0) + if (hyper_parse_container(pod, &c, json, toks) < 0) goto fail; c->exec.init = 2; // dynamic container type @@ -737,7 +739,6 @@ realloc: fail: free(toks); - free(c); return NULL; } diff --git a/src/util.c b/src/util.c index 1ff507d..5223e36 100644 --- a/src/util.c +++ b/src/util.c @@ -386,13 +386,23 @@ void hyper_unmount_all(void) int hyper_send_finish(struct hyper_pod *pod) { - int i, ret; - uint8_t *data = calloc(pod->c_num, 4); + int ret = -1; + struct hyper_container *c; + uint8_t *data = NULL, *new; + int c_num = 0; - for (i = 0; i < pod->c_num; i++) - hyper_set_be32(data + (i * 4), pod->c[i].exec.code); + list_for_each_entry(c, &pod->containers, list) { + c_num++; + new = realloc(data, c_num * 4); + if (new == NULL) + goto out; - ret = hyper_send_msg(ctl.chan.fd, FINISH, pod->c_num * 4, data); + hyper_set_be32(new + ((c_num - 1) * 4), c->exec.code); + data = new; + } + + ret = hyper_send_msg(ctl.chan.fd, FINISH, c_num * 4, data); +out: free(data); return ret; } From b7c88467e279a9db68005bfa89b35fcbfb44f584 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 16 Nov 2015 12:10:01 +0800 Subject: [PATCH 6/8] Add remains when start container successfully Signed-off-by: Gao feng --- src/exec.c | 8 +------- src/hyper.h | 1 + src/init.c | 13 ++++++++----- src/parse.c | 2 -- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/exec.c b/src/exec.c index 14d51e1..b1f078f 100644 --- a/src/exec.c +++ b/src/exec.c @@ -545,13 +545,7 @@ int hyper_release_exec(struct hyper_exec *exec, fprintf(stdout, "%s container init exited, type %d, remains %d, policy %d\n", __func__, pod->type, pod->remains, pod->policy); - 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); - return 0; - } - + // TODO send finish of this container and full cleanup if (--pod->remains > 0) return 0; diff --git a/src/hyper.h b/src/hyper.h index 8142c48..083867f 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -51,6 +51,7 @@ struct hyper_pod { uint32_t e_num; uint32_t d_num; uint32_t type; + /* how many containers are running */ uint32_t remains; uint8_t policy; int efd; diff --git a/src/init.c b/src/init.c index 2cb20b8..fe431b3 100644 --- a/src/init.c +++ b/src/init.c @@ -457,6 +457,8 @@ int hyper_start_container_stage0(struct hyper_container *c, struct hyper_pod *po goto out; } + /* container process is spawned and ready to execute */ + pod->remains++; ret = 0; out: close(arg.ctl_pipe[0]); @@ -696,8 +698,10 @@ static int hyper_new_container(char *json, int length) fprintf(stdout, "call hyper_new_container, json %s, len %d\n", json, length); - if (!pod->init_pid) + if (!pod->init_pid) { fprintf(stdout, "the pod is not created yet\n"); + return -1; + } c = hyper_parse_new_container(pod, json, length); if (c == NULL) { @@ -705,15 +709,14 @@ static int hyper_new_container(char *json, int length) return -1; } + list_add_tail(&c->list, &pod->containers); ret = hyper_start_container_stage0(c, pod); if (ret < 0) { //TODO full grace cleanup hyper_cleanup_container(c); - return ret; } - list_add_tail(&c->list, &pod->containers); - return 0; + return ret; } static int hyper_cmd_write_file(char *json, int length) @@ -1114,7 +1117,7 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) hyper_print_uptime(); break; case STOPPOD: - ret = hyper_stop_pod(pod); + hyper_stop_pod(pod); return 0; //break; case DESTROYPOD: diff --git a/src/parse.c b/src/parse.c index 3cf7869..bdddbda 100644 --- a/src/parse.c +++ b/src/parse.c @@ -469,7 +469,6 @@ static int hyper_parse_containers(struct hyper_pod *pod, char *json, jsmntok_t * i += next; } - pod->remains = c_num; return i; fail: list_for_each_entry_safe(c, n, &pod->containers, list) @@ -733,7 +732,6 @@ realloc: if (hyper_parse_container(pod, &c, json, toks) < 0) goto fail; - c->exec.init = 2; // dynamic container type free(toks); return c; From a2086298f688480a73aef5172bb5911a821e8378 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Mon, 16 Nov 2015 14:02:00 +0800 Subject: [PATCH 7/8] rename FINISH to PODFINISHED Signed-off-by: Gao feng --- src/exec.c | 2 +- src/hyper.h | 4 ++-- src/util.c | 6 +++--- src/util.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/exec.c b/src/exec.c index b1f078f..029e482 100644 --- a/src/exec.c +++ b/src/exec.c @@ -555,7 +555,7 @@ int hyper_release_exec(struct hyper_exec *exec, } else { /* send out pod finish message, hyper will decide if restart pod or not */ - hyper_send_finish(pod); + hyper_send_pod_finished(pod); } hyper_cleanup_pod(pod); diff --git a/src/hyper.h b/src/hyper.h index 083867f..1a82276 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -17,13 +17,13 @@ enum { DESTROYPOD, RESTARTCONTAINER, EXECCMD, - FINISHCMD, + CMDFINISHED, READY, ACK, ERROR, WINSIZE, PING, - FINISH, + PODFINISHED, NEXT, WRITEFILE, READFILE, diff --git a/src/util.c b/src/util.c index 5223e36..225375e 100644 --- a/src/util.c +++ b/src/util.c @@ -384,7 +384,7 @@ void hyper_unmount_all(void) sync(); } -int hyper_send_finish(struct hyper_pod *pod) +int hyper_send_pod_finished(struct hyper_pod *pod) { int ret = -1; struct hyper_container *c; @@ -401,7 +401,7 @@ int hyper_send_finish(struct hyper_pod *pod) data = new; } - ret = hyper_send_msg(ctl.chan.fd, FINISH, c_num * 4, data); + ret = hyper_send_msg(ctl.chan.fd, PODFINISHED, c_num * 4, data); out: free(data); return ret; @@ -409,7 +409,7 @@ out: void hyper_shutdown(struct hyper_pod *pod) { - hyper_send_finish(pod); + hyper_send_pod_finished(pod); /* vm will shutdown immediately after we call reboot, * no chance to send out eof message in release exec. * send it out by ourself */ diff --git a/src/util.h b/src/util.h index c285a9d..5087d2f 100644 --- a/src/util.h +++ b/src/util.h @@ -25,7 +25,7 @@ int hyper_setfd_block(int fd); int hyper_setfd_nonblock(int fd); int hyper_socketpair(int domain, int type, int protocol, int sv[2]); void hyper_shutdown(struct hyper_pod *pod); -int hyper_send_finish(struct hyper_pod *pod); +int hyper_send_pod_finished(struct hyper_pod *pod); void hyper_unmount_all(void); int hyper_insmod(char *module); #endif From 0887e9a6ded7ed0fac9b023df50f9dfcda840b87 Mon Sep 17 00:00:00 2001 From: Gao feng Date: Wed, 18 Nov 2015 18:50:07 +0800 Subject: [PATCH 8/8] support kill container Signed-off-by: Gao feng --- src/hyper.h | 6 ++++++ src/init.c | 26 ++++++++++++++++++++++ src/parse.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/parse.h | 1 + 4 files changed, 95 insertions(+) diff --git a/src/hyper.h b/src/hyper.h index 1a82276..7845342 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -28,6 +28,7 @@ enum { WRITEFILE, READFILE, NEWCONTAINER, + KILLCONTAINER, }; enum { @@ -65,6 +66,11 @@ struct hyper_win_size { uint64_t seq; }; +struct hyper_killer { + char *id; + int signal; +}; + struct hyper_reader { char *id; char *file; diff --git a/src/init.c b/src/init.c index fe431b3..49eddd6 100644 --- a/src/init.c +++ b/src/init.c @@ -719,6 +719,29 @@ static int hyper_new_container(char *json, int length) return ret; } +static int hyper_kill_container(char *json, int length) +{ + struct hyper_killer killer; + struct hyper_container *c; + struct hyper_pod *pod = &global_pod; + int ret = -1; + + if (hyper_parse_kill_container(&killer, json, length) < 0) { + goto out; + } + + c = hyper_find_container(pod, killer.id); + if (c == NULL) { + fprintf(stderr, "can not find container whose id is %s\n", killer.id); + goto out; + } + + kill(c->exec.pid, killer.signal); + ret = 0; +out: + return ret; +} + static int hyper_cmd_write_file(char *json, int length) { struct hyper_writter writter; @@ -1145,6 +1168,9 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) case NEWCONTAINER: ret = hyper_new_container((char *)buf->data + 8, len - 8); break; + case KILLCONTAINER: + ret = hyper_kill_container((char *)buf->data + 8, len - 8); + break; default: ret = -1; break; diff --git a/src/parse.c b/src/parse.c index bdddbda..c728326 100644 --- a/src/parse.c +++ b/src/parse.c @@ -740,6 +740,68 @@ fail: return NULL; } +int hyper_parse_kill_container(struct hyper_killer *killer, char *json, int length) +{ + int i, n, ret = -1; + jsmn_parser p; + int toks_num = 10; + jsmntok_t *toks = NULL; + + memset(killer, 0, sizeof(*killer)); +realloc: + toks = realloc(toks, toks_num * sizeof(jsmntok_t)); + if (toks == NULL) { + fprintf(stderr, "allocate tokens for kill container failed\n"); + goto out; + } + + jsmn_init(&p); + + n = jsmn_parse(&p, json, length, toks, toks_num); + if (n < 0) { + fprintf(stdout, "jsmn parse failed, n is %d\n", n); + if (n == JSMN_ERROR_NOMEM) { + toks_num *= 2; + goto realloc; + } + + goto out; + } + + for (i = 0; i < n; i++) { + jsmntok_t *t = &toks[i]; + + if (t->type != JSMN_STRING) + continue; + + if (i++ == n) + goto fail; + + if (json_token_streq(json, t, "container")) { + if (toks[i].type != JSMN_STRING) + goto fail; + killer->id = strdup(json_token_str(json, &toks[i])); + } else if (json_token_streq(json, t, "signal")) { + if (toks[i].type != JSMN_PRIMITIVE) + goto fail; + killer->signal = json_token_int(json, &toks[i]); + } else { + fprintf(stderr, "get unknown section %s in kill container\n", + json_token_str(json, t)); + goto fail; + } + } + + ret = 0; +out: + free(toks); + return ret; +fail: + free(killer->id); + killer->id = NULL; + goto out; +} + int hyper_parse_winsize(struct hyper_win_size *ws, char *json, int length) { int i, n, ret = -1; diff --git a/src/parse.h b/src/parse.h index 24c75dd..52f91f9 100644 --- a/src/parse.h +++ b/src/parse.h @@ -9,6 +9,7 @@ struct hyper_exec *hyper_parse_execcmd(char *json, int length); char *json_token_str(char *js, jsmntok_t *t); 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_kill_container(struct hyper_killer *killer, 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); struct hyper_container *hyper_parse_new_container(struct hyper_pod *pod, char *json, int length);