From 29c1823334219c03b1ef4d6b4965529b73ff071b Mon Sep 17 00:00:00 2001 From: LiFeng Date: Mon, 13 Apr 2020 21:39:35 +0800 Subject: [PATCH 17/49] attach: add_terminal_fifos: Add terminal fifos dynamically Signed-off-by: LiFeng --- src/lxc/commands.c | 94 +++++++++++++++++++++++++++++++++++++++++++++----- src/lxc/commands.h | 8 +++++ src/lxc/lxccontainer.c | 24 +++++++++++++ src/lxc/terminal.c | 57 ++++++++++++++++++++++++++++++ src/lxc/terminal.h | 4 +++ 5 files changed, 178 insertions(+), 9 deletions(-) diff --git a/src/lxc/commands.c b/src/lxc/commands.c index 991bca2..0ffc5c7 100644 --- a/src/lxc/commands.c +++ b/src/lxc/commands.c @@ -75,15 +75,18 @@ static const char *lxc_cmd_str(lxc_cmd_t cmd) [LXC_CMD_GET_CONFIG_ITEM] = "get_config_item", [LXC_CMD_GET_NAME] = "get_name", [LXC_CMD_GET_LXCPATH] = "get_lxcpath", - [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", - [LXC_CMD_CONSOLE_LOG] = "console_log", + [LXC_CMD_ADD_STATE_CLIENT] = "add_state_client", + [LXC_CMD_CONSOLE_LOG] = "console_log", [LXC_CMD_SERVE_STATE_CLIENTS] = "serve_state_clients", [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = "seccomp_notify_add_listener", [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = "add_bpf_device_cgroup", - [LXC_CMD_FREEZE] = "freeze", - [LXC_CMD_UNFREEZE] = "unfreeze", - [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd", + [LXC_CMD_FREEZE] = "freeze", + [LXC_CMD_UNFREEZE] = "unfreeze", + [LXC_CMD_GET_CGROUP2_FD] = "get_cgroup2_fd", [LXC_CMD_GET_INIT_PIDFD] = "get_init_pidfd", +#ifdef HAVE_ISULAD + [LXC_CMD_SET_TERMINAL_FIFOS] = "set_terminal_fifos", +#endif }; if (cmd >= LXC_CMD_MAX) @@ -1388,6 +1391,76 @@ static int lxc_cmd_get_cgroup2_fd_callback(int fd, struct lxc_cmd_req *req, return 0; } +#ifdef HAVE_ISULAD +/* + * isulad: lxc_cmd_set_terminal_fifos: Set the fifos used for the container as terminal input/output + * + * @hashed_sock_name: hashed socket name + * + * Returns 0 when success, else when fail. + */ +int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, const char *in_fifo, + const char *out_fifo, const char *err_fifo) +{ + int ret = 0, stopped = 0; + int len = 0; + char *tmp = NULL; + const char *split = "&&&&", *none_fifo_name = "none"; + const char *cmd_in_fifo = in_fifo ? in_fifo : none_fifo_name; + const char *cmd_out_fifo = out_fifo ? out_fifo : none_fifo_name; + const char *cmd_err_fifo = err_fifo ? err_fifo : none_fifo_name; + + if (len + strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + + strlen(split) + strlen(cmd_err_fifo) == SIZE_MAX) + return -1; + len += strlen(cmd_in_fifo) + strlen(split) + strlen(cmd_out_fifo) + strlen(split) + strlen(cmd_err_fifo) + 1; + tmp = malloc(len); + if (tmp == NULL) + return -1; + ret = snprintf(tmp, len, "%s%s%s%s%s", cmd_in_fifo, split, cmd_out_fifo, split, cmd_err_fifo); + if (ret < 0 || ret >= len) { + ERROR("Failed to snprintf in fifo of command"); + free(tmp); + return -1; + } + + struct lxc_cmd_rr cmd = { + .req = { + .cmd = LXC_CMD_SET_TERMINAL_FIFOS, + .datalen = strlen(tmp)+1, + .data = tmp, + }, + }; + + ret = lxc_cmd(name, &cmd, &stopped, lxcpath, NULL); + if (ret < 0) { + ERROR("Failed to send command to container"); + free(tmp); + return -1; + } + + if (cmd.rsp.ret != 0) { + ERROR("Command response error:%d", cmd.rsp.ret); + free(tmp); + return -1; + } + + free(tmp); + return 0; +} + +static int lxc_cmd_set_terminal_fifos_callback(int fd, struct lxc_cmd_req *req, + struct lxc_handler *handler, struct lxc_epoll_descr *descr) +{ + struct lxc_cmd_rsp rsp; + memset(&rsp, 0, sizeof(rsp)); + + rsp.ret = lxc_terminal_add_fifos(handler->conf, req->data);; + + return lxc_cmd_rsp_send(fd, &rsp); +} +#endif + static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, struct lxc_handler *handler, struct lxc_epoll_descr *descr) @@ -1410,11 +1483,14 @@ static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, [LXC_CMD_CONSOLE_LOG] = lxc_cmd_console_log_callback, [LXC_CMD_SERVE_STATE_CLIENTS] = lxc_cmd_serve_state_clients_callback, [LXC_CMD_SECCOMP_NOTIFY_ADD_LISTENER] = lxc_cmd_seccomp_notify_add_listener_callback, - [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback, - [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback, - [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback, - [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback, + [LXC_CMD_ADD_BPF_DEVICE_CGROUP] = lxc_cmd_add_bpf_device_cgroup_callback, + [LXC_CMD_FREEZE] = lxc_cmd_freeze_callback, + [LXC_CMD_UNFREEZE] = lxc_cmd_unfreeze_callback, + [LXC_CMD_GET_CGROUP2_FD] = lxc_cmd_get_cgroup2_fd_callback, [LXC_CMD_GET_INIT_PIDFD] = lxc_cmd_get_init_pidfd_callback, +#ifdef HAVE_ISULAD + [LXC_CMD_SET_TERMINAL_FIFOS] = lxc_cmd_set_terminal_fifos_callback, +#endif }; if (req->cmd >= LXC_CMD_MAX) diff --git a/src/lxc/commands.h b/src/lxc/commands.h index 9e52484..95815e6 100644 --- a/src/lxc/commands.h +++ b/src/lxc/commands.h @@ -38,6 +38,9 @@ typedef enum { LXC_CMD_UNFREEZE, LXC_CMD_GET_CGROUP2_FD, LXC_CMD_GET_INIT_PIDFD, +#ifdef HAVE_ISULAD + LXC_CMD_SET_TERMINAL_FIFOS, +#endif LXC_CMD_MAX, } lxc_cmd_t; @@ -130,4 +133,9 @@ extern int lxc_cmd_freeze(const char *name, const char *lxcpath, int timeout); extern int lxc_cmd_unfreeze(const char *name, const char *lxcpath, int timeout); extern int lxc_cmd_get_cgroup2_fd(const char *name, const char *lxcpath); +#ifdef HAVE_ISULAD +extern int lxc_cmd_set_terminal_fifos(const char *name, const char *lxcpath, + const char *in_fifo, const char *out_fifo, const char *err_fifo); +#endif + #endif /* __commands_h */ diff --git a/src/lxc/lxccontainer.c b/src/lxc/lxccontainer.c index e27b63b..d0e6e2b 100644 --- a/src/lxc/lxccontainer.c +++ b/src/lxc/lxccontainer.c @@ -5421,6 +5421,29 @@ static bool do_lxcapi_want_open_stdin(struct lxc_container *c, bool state) } WRAP_API_1(bool, lxcapi_want_open_stdin, bool) + +/* isulad add clean resources */ +static bool do_lxcapi_add_terminal_fifo(struct lxc_container *c, const char *in_fifo, const char *out_fifo, const char *err_fifo) +{ + bool ret = true; + + if (!c || !c->lxc_conf) + return false; + if (container_mem_lock(c)) { + ERROR("Error getting mem lock"); + return false; + } + + if (lxc_cmd_set_terminal_fifos(c->name, c->config_path, in_fifo, out_fifo, err_fifo)) { + ERROR("Error set console fifos"); + ret = false; + } + + container_mem_unlock(c); + return ret; +} + +WRAP_API_3(bool, lxcapi_add_terminal_fifo, const char *, const char *, const char *) #endif struct lxc_container *lxc_container_new(const char *name, const char *configpath) @@ -5567,6 +5590,7 @@ struct lxc_container *lxc_container_new(const char *name, const char *configpath #ifdef HAVE_ISULAD c->set_container_info_file = lxcapi_set_container_info_file; c->set_terminal_init_fifos = lxcapi_set_terminal_default_fifos; + c->add_terminal_fifos = lxcapi_add_terminal_fifo; #endif return c; diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index 775743d..4d7c2cd 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -1607,6 +1607,63 @@ err: lxc_terminal_delete(terminal); return -ENODEV; } + +/* isulad: add fifos dynamic*/ +int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames) +{ + int ret = 0; + struct lxc_terminal *terminal = &conf->console; + int fifofd_in = -1; + char *tmp = NULL, *saveptr = NULL, *in = NULL, *out = NULL, *err = NULL; + const char *none_fifo_name = "none"; + + tmp = safe_strdup(fifonames); + + in = strtok_r(tmp, "&&&&", &saveptr); + if (!in) { + ret = -1; + goto free_out; + } + if (strcmp(in, none_fifo_name) == 0) + in = NULL; + + out = strtok_r(NULL, "&&&&", &saveptr); + if (!out) { + ret = -1; + goto free_out; + } + if (strcmp(out, none_fifo_name) == 0) + out = NULL; + + err = strtok_r(NULL, "&&&&", &saveptr); + if (!err) { + ret = -1; + goto free_out; + } + if (strcmp(err, none_fifo_name) == 0) + err = NULL; + + ret = lxc_terminal_set_fifo(terminal, in, out, err, &fifofd_in); + if (ret < 0) { + ERROR("Faild to set fifos to console config"); + ret = -1; + goto free_out; + } + + if (lxc_mainloop_add_handler(terminal->descr, fifofd_in, + lxc_terminal_io_cb, terminal)) { + ERROR("console fifo not added to mainloop"); + lxc_terminal_delete_fifo(fifofd_in, &terminal->fifos); + ret = -1; + goto free_out; + } + +free_out: + if (tmp) + free(tmp); + return ret; +} + #else int lxc_terminal_create(struct lxc_terminal *terminal) { diff --git a/src/lxc/terminal.h b/src/lxc/terminal.h index dfc03c6..b4160b3 100644 --- a/src/lxc/terminal.h +++ b/src/lxc/terminal.h @@ -274,4 +274,8 @@ extern void lxc_terminal_init(struct lxc_terminal *terminal); extern int lxc_terminal_map_ids(struct lxc_conf *c, struct lxc_terminal *terminal); +#ifdef HAVE_ISULAD +int lxc_terminal_add_fifos(struct lxc_conf *conf, const char *fifonames); +#endif + #endif /* __LXC_TERMINAL_H */ -- 1.8.3.1