133 lines
4.4 KiB
Diff
133 lines
4.4 KiB
Diff
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
|
|
|