From 36f64e652afc7fe3feac6d93468cbc4f3d53ec9a Mon Sep 17 00:00:00 2001 From: LiFeng Date: Tue, 21 Apr 2020 15:36:55 +0800 Subject: [PATCH] attach: seprate -i and -t flags Signed-off-by: LiFeng --- src/lxc/attach.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- src/lxc/attach_options.h | 2 + src/lxc/start.c | 1 + src/lxc/terminal.c | 14 ++++--- src/lxc/tools/lxc_attach.c | 17 +++++++- 5 files changed, 125 insertions(+), 9 deletions(-) diff --git a/src/lxc/attach.c b/src/lxc/attach.c index 1dd2b47..5539fb1 100644 --- a/src/lxc/attach.c +++ b/src/lxc/attach.c @@ -653,6 +653,9 @@ struct attach_clone_payload { struct lxc_proc_context_info *init_ctx; lxc_attach_exec_t exec_function; void *exec_payload; +#ifdef HAVE_ISULAD + struct lxc_terminal *terminal; +#endif }; static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) @@ -665,6 +668,49 @@ static void lxc_put_attach_clone_payload(struct attach_clone_payload *p) } } +#ifdef HAVE_ISULAD +static int isulad_set_attach_pipes(struct lxc_terminal *terminal) +{ + int ret = 0; + if (terminal->pipes[0][1] >= 0) { + close(terminal->pipes[0][1]); + terminal->pipes[0][1] = -1; + } + + if (terminal->pipes[0][0] >= 0) { + ret = dup2(terminal->pipes[0][0], STDIN_FILENO); + if (ret < 0) + goto out; + } + + if (terminal->pipes[1][0] >= 0) { + close(terminal->pipes[1][0]); + terminal->pipes[1][0] = -1; + } + + if (terminal->pipes[1][1] >= 0) { + ret = dup2(terminal->pipes[1][1], STDOUT_FILENO); + if (ret < 0) + goto out; + } + if (terminal->pipes[2][0] >= 0) { + close(terminal->pipes[2][0]); + terminal->pipes[2][0] = -1; + } + + if (terminal->pipes[2][1] >= 0) { + ret = dup2(terminal->pipes[2][1], STDERR_FILENO); + if (ret < 0) + goto out; + } + + setsid(); +out: + return ret; +} + +#endif + static int attach_child_main(struct attach_clone_payload *payload) { int lsm_fd, ret; @@ -933,6 +979,25 @@ static int attach_child_main(struct attach_clone_payload *payload) } if (options->attach_flags & LXC_ATTACH_TERMINAL) { + +#ifdef HAVE_ISULAD + /* isulad: dup2 pipe[0][0] to container stdin, pipe[1][1] to container stdout, pipe[2][1] to container stderr */ + if (payload->terminal->disable_pty) { + ret = isulad_set_attach_pipes(payload->terminal); + if (ret < 0) { + SYSERROR("Failed to prepare terminal file pipes"); + goto on_error; + } + } + + if(!payload->terminal->disable_pty && payload->terminal_slave_fd >= 0) { + ret = lxc_terminal_prepare_login(payload->terminal_slave_fd); + if (ret < 0) { + SYSERROR("Failed to prepare terminal file descriptor %d", payload->terminal_slave_fd); + goto on_error; + } + } +#else ret = lxc_terminal_prepare_login(payload->terminal_slave_fd); if (ret < 0) { SYSERROR("Failed to prepare terminal file descriptor %d", payload->terminal_slave_fd); @@ -940,6 +1005,7 @@ static int attach_child_main(struct attach_clone_payload *payload) } TRACE("Prepared terminal file descriptor %d", payload->terminal_slave_fd); +#endif } /* Avoid unnecessary syscalls. */ @@ -1016,6 +1082,9 @@ static int lxc_attach_terminal(struct lxc_conf *conf, free(terminal->init_fifo[2]); terminal->init_fifo[2] = safe_strdup(options->init_fifo[2]); } + + terminal->disable_pty = options->disable_pty; + terminal->open_stdin = options->open_stdin; #endif ret = lxc_terminal_create(terminal); @@ -1410,6 +1479,21 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, /* isulad: close errpipe */ close(conf->errpipe[1]); conf->errpipe[1] = -1; + /* isulad: close pipe after clone */ + if (terminal.pipes[0][0] >= 0) { + close(terminal.pipes[0][0]); + terminal.pipes[0][0] = -1; + } + + if (terminal.pipes[1][1] >= 0) { + close(terminal.pipes[1][1]); + terminal.pipes[1][1] = -1; + } + + if (terminal.pipes[2][1] >= 0) { + close(terminal.pipes[2][1]); + terminal.pipes[2][1] = -1; + } #endif lxc_proc_close_ns_fd(init_ctx); if (options->attach_flags & LXC_ATTACH_TERMINAL) @@ -1568,6 +1652,15 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, ret_parent = 0; to_cleanup_pid = -1; + #ifdef HAVE_ISULAD + // iSulad: close stdin pipe if we do not want open_stdin with container stdin + if (!terminal.open_stdin) { + if (terminal.pipes[0][1] > 0) { + close(terminal.pipes[0][1]); + terminal.pipes[0][1] = -1; + } + } + #endif if (options->attach_flags & LXC_ATTACH_TERMINAL) { ret = lxc_mainloop(&descr, -1); if (ret < 0) { @@ -1671,6 +1764,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, payload.terminal_slave_fd = terminal.slave; payload.exec_function = exec_function; payload.exec_payload = exec_payload; +#ifdef HAVE_ISULAD + payload.terminal = &terminal; +#endif pid = lxc_raw_clone(CLONE_PARENT, NULL); if (pid < 0) { @@ -1697,9 +1793,9 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, _exit(EXIT_FAILURE); } - if (options->attach_flags & LXC_ATTACH_TERMINAL) + if (options->attach_flags & LXC_ATTACH_TERMINAL) { lxc_attach_terminal_close_slave(&terminal); - + } /* Tell grandparent the pid of the pid of the newly created child. */ ret = lxc_write_nointr(ipc_sockets[1], &pid, sizeof(pid)); if (ret != sizeof(pid)) { diff --git a/src/lxc/attach_options.h b/src/lxc/attach_options.h index d5d4f44..5767560 100644 --- a/src/lxc/attach_options.h +++ b/src/lxc/attach_options.h @@ -121,6 +121,8 @@ typedef struct lxc_attach_options_t { char *init_fifo[3]; /* isulad: default fifos for the start */ int64_t timeout;/* isulad: Seconds for waiting on a container to attach/exec before it is killed*/ const char *suffix; + bool disable_pty; + bool open_stdin; } lxc_attach_options_t; /*! Default attach options to use */ diff --git a/src/lxc/start.c b/src/lxc/start.c index e099285..68a6116 100644 --- a/src/lxc/start.c +++ b/src/lxc/start.c @@ -1789,6 +1789,7 @@ static int do_start(void *data) * as it execs. */ #ifdef HAVE_ISULAD + close_prot_errno_disarm(status_fd); handler->ops->start(handler, handler->data, handler->daemonize ? handler->conf->errpipe[1] : -1); #else handler->ops->start(handler, handler->data); diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c index c0a4d1a..57def93 100644 --- a/src/lxc/terminal.c +++ b/src/lxc/terminal.c @@ -750,21 +750,23 @@ int lxc_terminal_io_cb(int fd, uint32_t events, void *data, return LXC_MAINLOOP_CONTINUE; } else if (fd == terminal->pipes[1][0] || fd == terminal->pipes[2][0]) { if (fd == terminal->pipes[1][0]) { - w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); + if (terminal->log_fd >= 0) { + w_log = isulad_lxc_terminal_write_log_file(terminal, "stdout", NULL, 0); + } terminal->pipes[1][0] = -EBADF; } else if (fd == terminal->pipes[2][0]) { - w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", NULL, 0); + if (terminal->log_fd >= 0) { + w_log = isulad_lxc_terminal_write_log_file(terminal, "stderr", NULL, 0); + } terminal->pipes[2][0] = -EBADF; } - if (w_log < 0) - TRACE("Failed to write %d bytes to terminal log", r); close(fd); - return LXC_MAINLOOP_CONTINUE; + return LXC_MAINLOOP_CLOSE; } else if (fd == terminal->pipes[0][1]) { TRACE("closed stdin pipe of container stdin"); terminal->pipes[0][1] = -EBADF; close(fd); - return LXC_MAINLOOP_CONTINUE; + return LXC_MAINLOOP_CLOSE; } else { ERROR("Handler received unexpected file descriptor"); } diff --git a/src/lxc/tools/lxc_attach.c b/src/lxc/tools/lxc_attach.c index a855a8d..da7a7d2 100644 --- a/src/lxc/tools/lxc_attach.c +++ b/src/lxc/tools/lxc_attach.c @@ -82,6 +82,8 @@ static const struct option my_longopts[] = { {"err-fifo", required_argument, 0, OPT_STDERR_FIFO}, {"suffix", required_argument, 0, OPT_ATTACH_SUFFIX}, {"timeout", required_argument, 0, OPT_ATTACH_TIMEOUT}, + {"disable-pty", no_argument, 0, OPT_DISABLE_PTY}, + {"open-stdin", no_argument, 0, OPT_OPEN_STDIN}, #endif LXC_COMMON_OPTIONS }; @@ -312,9 +314,14 @@ static int my_parser(struct lxc_arguments *args, int c, char *arg) } args->attach_timeout = (unsigned int)atoll(arg); break; + case OPT_DISABLE_PTY: + args->disable_pty = 1; + break; + case OPT_OPEN_STDIN: + args->open_stdin = 1; + break; #endif } - return 0; } @@ -614,6 +621,14 @@ int main(int argc, char *argv[]) attach_options.suffix = my_args.suffix; + if (my_args.disable_pty) { + attach_options.disable_pty = true; + } + + if (my_args.open_stdin) { + attach_options.open_stdin = true; + } + /* isulad: add do attach background */ if (attach_options.attach_flags & LXC_ATTACH_TERMINAL) wexit = do_attach_foreground(c, &command, &attach_options, &errmsg); -- 1.8.3.1