commit: ad61940b03be2f24c0b54c1070a4923abe18e633 Author: Zac Medico <zmedico <AT> gentoo <DOT> org> AuthorDate: Fri Feb 9 16:22:45 2024 +0000 Commit: Zac Medico <zmedico <AT> gentoo <DOT> org> CommitDate: Fri Feb 9 23:52:11 2024 +0000 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=ad61940b
gpkg: Less aggressive subprocess.Popen kill in order to avoid BrokenPipeError Do not kill tar_stream_reader instances if we can successfully close them, since that can trigger BrokenPipeError during self.proc.stdin.close() calls, and this state is best avoided because it's unclear how the caller should handle the error. If a BrokenPipeError does occur then simply print a traceback and hope that the corresponding file descriptor is closed during garbage collection. Do not try to reverse the order of self.proc.kill() and self.proc.stdin.close() as in commit fba76a545f2 since that triggered pypy ci job hangs for which no reliable solution has been found so far. Bug: https://bugs.gentoo.org/923368 Signed-off-by: Zac Medico <zmedico <AT> gentoo.org> lib/portage/gpkg.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py index 031b3f87cb..f1d8f97f8e 100644 --- a/lib/portage/gpkg.py +++ b/lib/portage/gpkg.py @@ -1,7 +1,8 @@ -# Copyright 2001-2020 Gentoo Authors +# Copyright 2001-2024 Gentoo Authors # Distributed under the terms of the GNU General Public License v2 import tarfile +import traceback import io import threading import subprocess @@ -151,7 +152,10 @@ class tar_stream_writer: if self.proc is not None: self.killed = True self.proc.kill() - self.proc.stdin.close() + try: + self.proc.stdin.close() + except BrokenPipeError: + traceback.print_exc() self.close() def _cmd_read_thread(self): @@ -213,7 +217,7 @@ class tar_stream_writer: if self.proc is not None: self.proc.stdin.close() if self.proc.wait() != os.EX_OK: - if not self.error: + if not (self.killed or self.error): raise CompressorOperationFailed("compression failed") if self.read_thread.is_alive(): self.read_thread.join() @@ -349,7 +353,10 @@ class tar_stream_reader: if self.proc is not None: self.killed = True self.proc.kill() - self.proc.stdin.close() + try: + self.proc.stdin.close() + except BrokenPipeError: + traceback.print_exc() self.close() def read(self, bufsize=-1): @@ -986,11 +993,13 @@ class gpkg: try: image_safe = tar_safe_extract(image, "image") image_safe.extractall(decompress_dir) + image_tar.close() except Exception as ex: writemsg(colorize("BAD", "!!!Extract failed.")) raise finally: - image_tar.kill() + if not image_tar.closed: + image_tar.kill() def update_metadata(self, metadata, new_basename=None, force=False): """
