diff --git a/0018-IO-fix-io-data-miss-when-exec-with-pipes.patch b/0018-IO-fix-io-data-miss-when-exec-with-pipes.patch new file mode 100644 index 0000000000000000000000000000000000000000..73040ceb4b7d7e69bafdfbd329dad63e76ffebc4 --- /dev/null +++ b/0018-IO-fix-io-data-miss-when-exec-with-pipes.patch @@ -0,0 +1,132 @@ +From 9502363455188344dcfd7d1202cd48b7b554a5de Mon Sep 17 00:00:00 2001 +From: Li Feng +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 +--- + 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 + diff --git a/lxc.spec b/lxc.spec index fb6856f1c7a99361547240f7e2e6970c15caf47e..52e1867d2812163504ba805f91ef66348cf4058c 100644 --- a/lxc.spec +++ b/lxc.spec @@ -1,4 +1,4 @@ -%global _release 2021010501 +%global _release 2021012001 Name: lxc Version: 4.0.3 @@ -25,6 +25,7 @@ Patch0014: 0014-api-add-get-container-metrics-api.patch Patch0015: 0015-Streaming-IO-solution-optimization-and-enhancement.patch Patch0016: 0016-avoid-using-void-pointers-in-caclulation.patch Patch0017: 0017-fix-compilation-errors-without-libcap.patch +Patch0018: 0018-IO-fix-io-data-miss-when-exec-with-pipes.patch BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath BuildRequires: pkgconfig(libseccomp) @@ -196,6 +197,12 @@ make check %{_mandir}/*/man7/%{name}* %changelog +* Wed Jan 21 2021 lifeng - 4.0.3-2021012001 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: fix io data miss when exec with pipes + * Tue Jan 2021 wujing - 4.0.3-2021010501 - Type:enhancement - ID:NA diff --git a/series.conf b/series.conf index 2dc36903d74196f10bafa84d0a4184bc5588ecde..fcd7814d0f55c8a0976139662456376030406c46 100644 --- a/series.conf +++ b/series.conf @@ -15,3 +15,4 @@ 0015-Streaming-IO-solution-optimization-and-enhancement.patch 0016-avoid-using-void-pointers-in-caclulation.patch 0017-fix-compilation-errors-without-libcap.patch +0018-IO-fix-io-data-miss-when-exec-with-pipes.patch