aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2024-02-09 08:22:45 -0800
committerZac Medico <zmedico@gentoo.org>2024-02-09 15:52:11 -0800
commitad61940b03be2f24c0b54c1070a4923abe18e633 (patch)
tree18e5b6c51ba93c569d339e75cec749c85e7c12ca
parenttest_gpkg_path_case: Add missing playground cleanup (diff)
downloadportage-ad61940b03be2f24c0b54c1070a4923abe18e633.tar.gz
portage-ad61940b03be2f24c0b54c1070a4923abe18e633.tar.bz2
portage-ad61940b03be2f24c0b54c1070a4923abe18e633.zip
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@gentoo.org>
-rw-r--r--lib/portage/gpkg.py19
1 files changed, 14 insertions, 5 deletions
diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py
index 031b3f87c..f1d8f97f8 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):
"""