diff --git a/src/container.c b/src/container.c index d46c422..113585f 100644 --- a/src/container.c +++ b/src/container.c @@ -181,6 +181,39 @@ static int container_setup_mount(struct hyper_container *container) return 0; } +static int container_setup_dns(struct hyper_container *container) +{ + int fd; + struct stat st; + char *src = "/.oldroot/tmp/hyper/resolv.conf"; + + if (stat(src, &st) < 0) { + if (errno == ENOENT) { + fprintf(stdout, "no dns configured\n"); + return 0; + } + + perror("stat resolve.conf failed"); + return -1; + } + + hyper_mkdir("/etc"); + + fd = open("/etc/resolv.conf", O_CREAT| O_WRONLY, 0644); + if (fd < 0) { + perror("create /etc/resolv.conf failed"); + return -1; + } + close(fd); + + if (mount(src, "/etc/resolv.conf", NULL, MS_BIND, NULL) < 0) { + perror("bind to /etc/resolv.conf failed"); + return -1; + } + + return 0; +} + static int container_setup_workdir(struct hyper_container *container) { if (container->workdir && chdir(container->workdir) < 0) { @@ -339,6 +372,11 @@ static int hyper_container_init(void *data) goto fail; } + if (container_setup_dns(container) < 0) { + fprintf(stderr, "container sets up dns failed\n"); + goto fail; + } + if (container_setup_workdir(container) < 0) { fprintf(stderr, "container sets up work directory failed\n"); goto fail; diff --git a/src/hyper.h b/src/hyper.h index 8446eb0..1889ab0 100644 --- a/src/hyper.h +++ b/src/hyper.h @@ -37,16 +37,17 @@ struct hyper_pod { struct hyper_container *c; struct hyper_interface *iface; struct hyper_route *rt; + char **dns; struct list_head pe_head; struct list_head ce_head; char *hostname; char *tag; - char *channel; int init_pid; uint32_t c_num; uint32_t i_num; uint32_t r_num; uint32_t e_num; + uint32_t d_num; uint32_t type; uint32_t code; uint32_t remains; diff --git a/src/init.c b/src/init.c index d1f5175..e45b0bd 100644 --- a/src/init.c +++ b/src/init.c @@ -604,6 +604,11 @@ static int hyper_setup_pod(struct hyper_pod *pod) return -1; } + if (hyper_setup_dns(pod) < 0) { + fprintf(stderr, "setup network failed\n"); + return -1; + } + if (hyper_setup_shared(pod) < 0) { fprintf(stderr, "setup shared directory failed\n"); return -1; @@ -806,9 +811,9 @@ static int hyper_stop_pod(struct hyper_pod *pod) hyper_cleanup_exec(pod); hyper_cleanup_container(pod); hyper_cleanup_network(pod); + hyper_cleanup_dns(pod); hyper_cleanup_shared(pod); - free(pod->channel); free(pod->hostname); sync(); diff --git a/src/net.c b/src/net.c index 8804e25..8a59001 100644 --- a/src/net.c +++ b/src/net.c @@ -795,3 +795,55 @@ void hyper_cleanup_network(struct hyper_pod *pod) pod->i_num = 0; netlink_close(&rth); } + +int hyper_setup_dns(struct hyper_pod *pod) +{ + int i, fd, ret = -1; + char buf[28]; + + if (pod->dns == NULL) + return 0; + + fd = open("/tmp/hyper/resolv.conf", O_CREAT| O_TRUNC| O_WRONLY, 0644); + + if (fd < 0) { + perror("create /tmp/resolv.conf failed"); + return -1; + } + + for (i = 0; i < pod->d_num; i++) { + int size = snprintf(buf, sizeof(buf), "nameserver %s\n", pod->dns[i]); + int len = 0, l; + + if (size < 0) { + fprintf(stderr, "sprintf resolv.conf entry failed\n"); + goto out; + } + + while (len < size) { + l = write(fd, buf, size); + if (l < 0) { + perror("fail to write resolv.conf"); + goto out; + } + len += l; + } + } + + ret = 0; +out: + close(fd); + return ret; +} + +void hyper_cleanup_dns(struct hyper_pod *pod) +{ + int fd = open("/tmp/hyper/resolv.conf", O_WRONLY| O_TRUNC); + + if (fd < 0) { + perror("open /tmp/resolv.conf failed"); + return; + } + + close(fd); +} diff --git a/src/net.h b/src/net.h index 8b95a95..af8450f 100644 --- a/src/net.h +++ b/src/net.h @@ -48,6 +48,8 @@ void hyper_set_be64(uint8_t *buf, uint64_t val); uint64_t hyper_get_be64(uint8_t *buf); int hyper_setup_network(struct hyper_pod *pod); void hyper_cleanup_network(struct hyper_pod *pod); +int hyper_setup_dns(struct hyper_pod *pod); +void hyper_cleanup_dns(struct hyper_pod *pod); int hyper_get_type_block(int fd, uint32_t *type); int hyper_send_type(int fd, uint32_t type); int hyper_send_type_block(int fd, uint32_t type, int need_ack); diff --git a/src/parse.c b/src/parse.c index 160b034..f29e888 100644 --- a/src/parse.c +++ b/src/parse.c @@ -384,6 +384,32 @@ static int hyper_parse_routes(struct hyper_pod *pod, char *json, jsmntok_t *toks return i; } +static int hyper_parse_dns(struct hyper_pod *pod, char *json, jsmntok_t *toks) +{ + int i = 1, j; + + if (toks[i].type != JSMN_ARRAY) { + fprintf(stdout, "Dns format incorrect\n"); + return -1; + } + + pod->d_num = toks[i].size; + fprintf(stdout, "dns count %d\n", pod->d_num); + pod->dns = calloc(pod->d_num, sizeof(*pod->dns)); + + if (pod->dns == NULL) { + fprintf(stdout, "alloc memory for container failed\n"); + return -1; + } + + for (j = 0; j < pod->d_num; j++) { + pod->dns[j] = strdup(json_token_str(json, &toks[++i])); + fprintf(stdout, "pod dns %d: %s\n", j, pod->dns[j]); + } + + return i; +} + int hyper_parse_pod(struct hyper_pod *pod, char *json, int length) { int i, n, next = -1; @@ -437,9 +463,12 @@ realloc: goto out; i += next; - } else if (json_token_streq(json, t, "socket") && t->size == 1) { - pod->channel = strdup(json_token_str(json, &toks[++i])); - fprintf(stdout, "channel is %s\n", pod->channel); + } else if (json_token_streq(json, t, "dns") && t->size == 1) { + next = hyper_parse_dns(pod, json, t); + if (next < 0) + goto out; + + i += next; } else if (json_token_streq(json, t, "shareDir") && t->size == 1) { pod->tag = strdup(json_token_str(json, &toks[++i])); fprintf(stdout, "9p tag is %s\n", pod->tag);