diff --git a/src/container.c b/src/container.c index aaea760..4e06a12 100644 --- a/src/container.c +++ b/src/container.c @@ -175,6 +175,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) { @@ -334,6 +367,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/init.c b/src/init.c index 588f13b..965ba26 100644 --- a/src/init.c +++ b/src/init.c @@ -539,6 +539,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; @@ -655,6 +660,7 @@ 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->hostname); diff --git a/src/net.c b/src/net.c index 7cc6de2..c184435 100644 --- a/src/net.c +++ b/src/net.c @@ -791,3 +791,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);