lxc/0018-IO-fix-io-data-miss-when-exec-with-pipes.patch

133 lines
4.4 KiB
Diff
Raw Normal View History

From 9502363455188344dcfd7d1202cd48b7b554a5de Mon Sep 17 00:00:00 2001
From: Li Feng <lifeng2221dd1@zoho.com.cn>
Date: Wed, 20 Jan 2021 14:22:33 +0800
Subject: [PATCH 18/18] IO: fix io data miss when exec with pipes
Signed-off-by: Li Feng <lifeng2221dd1@zoho.com.cn>
---
src/lxc/attach.c | 4 ++--
src/lxc/mainloop.c | 14 ++++++++++++++
src/lxc/mainloop.h | 2 ++
src/lxc/start.c | 4 ++--
src/lxc/terminal.c | 12 ++++++++----
5 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/src/lxc/attach.c b/src/lxc/attach.c
index 87e23c229..c5fc56150 100644
--- a/src/lxc/attach.c
+++ b/src/lxc/attach.c
@@ -1754,7 +1754,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
}
#endif
if (options->attach_flags & LXC_ATTACH_TERMINAL) {
- ret = lxc_mainloop(&descr, -1);
+ ret = isulad_safe_mainloop(&descr, -1);
if (ret < 0) {
ret_parent = -1;
to_cleanup_pid = attached_pid;
@@ -1763,7 +1763,7 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
#ifdef HAVE_ISULAD
// do lxc_mainloop to make sure we do not lose any output
- (void)lxc_mainloop(&isulad_descr, 100);
+ (void)isulad_safe_mainloop(&isulad_descr, 100);
if (g_attach_timeout_state == ATTACH_TIMEOUT && err_msg != NULL && *err_msg == NULL) {
*err_msg = safe_strdup("Attach exceeded timeout");
}
diff --git a/src/lxc/mainloop.c b/src/lxc/mainloop.c
index 6d4c5935a..35186f4b5 100644
--- a/src/lxc/mainloop.c
+++ b/src/lxc/mainloop.c
@@ -141,3 +141,17 @@ void lxc_mainloop_close(struct lxc_epoll_descr *descr)
close_prot_errno_disarm(descr->epfd);
}
+
+int isulad_safe_mainloop(struct lxc_epoll_descr *descr, int timeout_ms)
+{
+ int ret;
+
+ ret = lxc_mainloop(descr, timeout_ms);
+
+ // There are stdout and stderr channels, and two epolls should be performed to prevent
+ // one of the channels from exiting first, causing the other channel to not receive data,
+ // resulting in data loss
+ (void)lxc_mainloop(descr, 100);
+
+ return ret;
+}
\ No newline at end of file
diff --git a/src/lxc/mainloop.h b/src/lxc/mainloop.h
index 8afac60d3..dad79188c 100644
--- a/src/lxc/mainloop.h
+++ b/src/lxc/mainloop.h
@@ -34,4 +34,6 @@ extern void lxc_mainloop_close(struct lxc_epoll_descr *descr);
define_cleanup_function(struct lxc_epoll_descr *, lxc_mainloop_close);
+extern int isulad_safe_mainloop(struct lxc_epoll_descr *descr, int timeout_ms);
+
#endif
diff --git a/src/lxc/start.c b/src/lxc/start.c
index 50a1a8203..e6e217042 100644
--- a/src/lxc/start.c
+++ b/src/lxc/start.c
@@ -590,13 +590,13 @@ int lxc_poll(const char *name, struct lxc_handler *handler)
}
#endif
- ret = lxc_mainloop(&descr, -1);
+ ret = isulad_safe_mainloop(&descr, -1);
close_prot_errno_disarm(descr.epfd);
if (ret < 0 || !handler->init_died)
goto out_mainloop_console;
if (has_console)
- ret = lxc_mainloop(&descr_console, 100);
+ ret = isulad_safe_mainloop(&descr_console, 100);
out_mainloop_console:
if (has_console) {
diff --git a/src/lxc/terminal.c b/src/lxc/terminal.c
index a4c6ad0c8..1e467f5a6 100644
--- a/src/lxc/terminal.c
+++ b/src/lxc/terminal.c
@@ -679,19 +679,22 @@ static void lxc_forward_data_to_fifo(struct lxc_list *list, bool is_err, const c
struct lxc_list *it = NULL;
struct lxc_list *next = NULL;
struct lxc_fifos_fd *elem = NULL;
+ ssize_t w = 0;
lxc_list_for_each_safe(it, list, next) {
elem = it->elem;
if (is_err) {
if (elem->err_fd >= 0) {
- if (lxc_write_nointr_for_fifo(elem->err_fd, buf, r) < 0) {
- ERROR("Failed to write to fifo fd %d with error: %s", elem->err_fd, strerror(errno));
+ w = lxc_write_nointr_for_fifo(elem->err_fd, buf, r);
+ if (w != r) {
+ WARN("Failed to write to fifo fd %d with error: %s", elem->err_fd, strerror(errno));
}
}
} else {
if (elem->out_fd >= 0) {
- if (lxc_write_nointr_for_fifo(elem->out_fd, buf, r) < 0) {
- ERROR("Failed to write to fifo fd %d with error: %s", elem->out_fd, strerror(errno));
+ w = lxc_write_nointr_for_fifo(elem->out_fd, buf, r);
+ if (w != r) {
+ WARN("Failed to write to fifo fd %d with error: %s", elem->out_fd, strerror(errno));
}
}
}
@@ -1673,6 +1676,7 @@ int lxc_terminal_create(struct lxc_terminal *terminal)
ERROR("Failed to create stdin pipe");
goto err;
}
+
/* for stdout */
if (pipe2(terminal->pipes[1], O_CLOEXEC)) {
ERROR("Failed to create stdout pipe");
--
2.25.1