diff --git a/configure.ac b/configure.ac index 3b1b6dd..efec743 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([hyperstart], [0.2], [www.hyper.sh]) +AC_INIT([hyperstart], [0.3], [www.hyper.sh]) AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) AM_EXTRA_RECURSIVE_TARGETS([initrd cbfs]) AC_CONFIG_SRCDIR([src/init.c]) diff --git a/src/exec.c b/src/exec.c index 1fa18ec..7d47eef 100644 --- a/src/exec.c +++ b/src/exec.c @@ -524,6 +524,29 @@ free_exec: goto out; } +static int hyper_send_pod_finished(struct hyper_pod *pod) +{ + int ret = -1; + struct hyper_container *c; + uint8_t *data = NULL, *new; + int c_num = 0; + + list_for_each_entry(c, &pod->containers, list) { + c_num++; + new = realloc(data, c_num * 4); + if (new == NULL) + goto out; + + hyper_set_be32(new + ((c_num - 1) * 4), c->exec.code); + data = new; + } + + ret = hyper_send_msg_block(ctl.chan.fd, PODFINISHED, c_num * 4, data); +out: + free(data); + return ret; +} + int hyper_release_exec(struct hyper_exec *exec, struct hyper_pod *pod) { @@ -550,9 +573,11 @@ int hyper_release_exec(struct hyper_exec *exec, return 0; if (pod->type == STOPPOD) { - /* stop pod manually */ - hyper_send_type(ctl.chan.fd, ACK); - + /* stop pod manually, hyper doesn't care the pod finished codes */ + hyper_send_msg_block(ctl.chan.fd, ACK, 0, NULL); + } else if (pod->type == DESTROYPOD) { + /* shutdown vm manually, hyper doesn't care the pod finished codes */ + hyper_shutdown(); } else { /* send out pod finish message, hyper will decide if restart pod or not */ hyper_send_pod_finished(pod); @@ -563,7 +588,6 @@ int hyper_release_exec(struct hyper_exec *exec, } hyper_free_exec(exec); - return 0; } diff --git a/src/init.c b/src/init.c index 8925278..fe784e2 100644 --- a/src/init.c +++ b/src/init.c @@ -516,7 +516,7 @@ static int hyper_setup_container(struct hyper_pod *pod) fprintf(stdout, "pod init pid %d\n", pod->init_pid); /* Wait for container start */ - if (hyper_get_type_block(arg.ctl_pipe[0], &type) < 0) { + if (hyper_get_type(arg.ctl_pipe[0], &type) < 0) { perror("get container init ready message failed"); goto out; } @@ -669,6 +669,18 @@ static void hyper_print_uptime(void) close(fd); } +static int hyper_destroy_pod(struct hyper_pod *pod) +{ + if (pod->init_pid == 0) { + /* Pod stopped, just shutdown */ + hyper_shutdown(); + } else { + /* Kill pod */ + hyper_term_all(pod); + } + return 0; +} + static int hyper_start_pod(char *json, int length) { struct hyper_pod *pod = &global_pod; @@ -684,7 +696,7 @@ static int hyper_start_pod(char *json, int length) } if (hyper_setup_pod(pod) < 0) { - hyper_shutdown(pod); + hyper_destroy_pod(pod); return -1; } @@ -1151,7 +1163,7 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) //break; case DESTROYPOD: fprintf(stdout, "get DESTROYPOD message\n"); - hyper_shutdown(pod); + hyper_destroy_pod(pod); return 0; case EXECCMD: ret = hyper_exec_cmd((char *)buf->data + 8, len - 8); @@ -1183,9 +1195,9 @@ static int hyper_channel_handle(struct hyper_event *de, uint32_t len) } if (ret < 0) - hyper_send_type(de->fd, ERROR); + hyper_send_msg_block(de->fd, ERROR, 0, NULL); else - hyper_send_msg(de->fd, ACK, datalen, data); + hyper_send_msg_block(de->fd, ACK, datalen, data); free(data); return 0; diff --git a/src/net.c b/src/net.c index 865af9f..b4810c1 100644 --- a/src/net.c +++ b/src/net.c @@ -112,9 +112,9 @@ int hyper_get_type(int fd, uint32_t *type) return 0; } -int hyper_get_type_block(int fd, uint32_t *type) +int hyper_send_msg_block(int fd, uint32_t type, uint32_t len, uint8_t *data) { - int ret = 0, flags; + int ret, flags; flags = hyper_setfd_block(fd); if (flags < 0) { @@ -122,10 +122,7 @@ int hyper_get_type_block(int fd, uint32_t *type) return -1; } - ret = hyper_get_type(fd, type); - if (ret < 0) { - fprintf(stderr, "%s can not get type\n", __func__); - } + ret = hyper_send_msg(fd, type, len, data); if (fcntl(fd, F_SETFL, flags) < 0) { perror("restore fd flag failed"); @@ -135,43 +132,6 @@ int hyper_get_type_block(int fd, uint32_t *type) return ret; } -int hyper_send_type_block(int fd, uint32_t type, int need_ack) -{ - int ret = 0, flags; - uint32_t t; - - flags = hyper_setfd_block(fd); - if (flags < 0) { - fprintf(stderr, "%s fail to set fd block\n", __func__); - return -1; - } - - ret = hyper_send_msg(fd, type, 0, NULL); - if (ret < 0) - goto out; - - if (need_ack == 0) - goto out; - - ret = hyper_get_type(fd, &t); - if (ret < 0) { - fprintf(stderr, "can not get type\n"); - goto out; - } - - fprintf(stdout, "get type %" PRIu32"\n", type); - - if (t != ACK) - ret = -1; -out: - if (fcntl(fd, F_SETFL, flags) < 0) { - perror("restore fd flag failed"); - return -1; - } - - return ret; -} - static int get_addr_ipv4(uint8_t *ap, const char *cp) { int i; diff --git a/src/net.h b/src/net.h index e096f21..c16fb8b 100644 --- a/src/net.h +++ b/src/net.h @@ -51,10 +51,9 @@ 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(int fd, uint32_t *type); -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); -int hyper_send_msg(int fd, uint32_t type, uint32_t len, - uint8_t *message); +int hyper_send_msg(int fd, uint32_t type, uint32_t len, uint8_t *data); +int hyper_send_msg_block(int fd, uint32_t type, uint32_t len, uint8_t *data); int hyper_send_data(int fd, uint8_t *data, uint32_t len); #endif diff --git a/src/util.c b/src/util.c index 225375e..5af7e50 100644 --- a/src/util.c +++ b/src/util.c @@ -339,7 +339,7 @@ int hyper_socketpair(int domain, int type, int protocol, int sv[2]) return 0; } -void hyper_unmount_all(void) +static void hyper_unmount_all(void) { FILE *mtab; struct mntent *mnt; @@ -384,38 +384,9 @@ void hyper_unmount_all(void) sync(); } -int hyper_send_pod_finished(struct hyper_pod *pod) +void hyper_shutdown() { - int ret = -1; - struct hyper_container *c; - uint8_t *data = NULL, *new; - int c_num = 0; - - list_for_each_entry(c, &pod->containers, list) { - c_num++; - new = realloc(data, c_num * 4); - if (new == NULL) - goto out; - - hyper_set_be32(new + ((c_num - 1) * 4), c->exec.code); - data = new; - } - - ret = hyper_send_msg(ctl.chan.fd, PODFINISHED, c_num * 4, data); -out: - free(data); - return ret; -} - -void hyper_shutdown(struct hyper_pod *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 */ - hyper_cleanup_exec(pod); - + hyper_send_msg_block(ctl.chan.fd, ACK, 0, NULL); hyper_unmount_all(); - reboot(LINUX_REBOOT_CMD_POWER_OFF); } diff --git a/src/util.h b/src/util.h index 5087d2f..dbaa352 100644 --- a/src/util.h +++ b/src/util.h @@ -24,8 +24,6 @@ int hyper_setfd_cloexec(int fd); 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_pod_finished(struct hyper_pod *pod); -void hyper_unmount_all(void); +void hyper_shutdown(void); int hyper_insmod(char *module); #endif