Note: This bug is displayed in read-only format because
the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Cause:
subprocess.Popen.communicate() doesn't catch EINTR error if it is called without timeout and if there is only one PIPE (stdout or stderr)
Consequence:
subprocess.Popen.communicate() fails with IOError
Fix:
Make subprocess.Popen.communicate() handle EINTR errors if the process has only one pipe
Result:
subprocess.Popen.communicate() now works properly when only one pipe is used
Description of problem:
Popen.communicate() raises IOError when the underlying read fails with EINTR due to a signal handler firing. It only happens when one of stdout or stderr is piped (therefore a possible workaround is to pipe both stdout and stderr and ignore the one that is not needed).
We see this intermittently in our Beaker self-test suite, where we execute lsof and read its stdout.
Traceback (most recent call last):
File "/usr/lib/python2.6/site-packages/nose/suite.py", line 208, in run
self.setUp()
File "/usr/lib/python2.6/site-packages/nose/suite.py", line 291, in setUp
self.setupContext(ancestor)
File "/usr/lib/python2.6/site-packages/nose/suite.py", line 314, in setupContext
try_run(context, names)
File "/usr/lib/python2.6/site-packages/nose/util.py", line 469, in try_run
return func()
File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 337, in setup_package
process.start()
File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 148, in start
self._wait_for_listen(self.listen_port)
File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 158, in _wait_for_listen
if check_listen(self.listen_port):
File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 109, in check_listen
stdout=subprocess.PIPE).communicate()
File "/usr/lib64/python2.6/subprocess.py", line 723, in communicate
stdout = self.stdout.read()
IOError: [Errno 4] Interrupted system call
The upstream bug is: http://bugs.python.org/issue12493
Fixed upstream in Python 2.7: http://hg.python.org/cpython/rev/6a28ccde2f1b
Version-Release number of selected component (if applicable):
python-2.6.6-52.el6.x86_64
How reproducible:
easily
Steps to Reproduce:
The upstream test suite has a reliable reproducer, here is an example based on that:
Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess, sys, signal
>>> def handler(signum, frame): pass
...
>>> signal.signal(signal.SIGALRM, handler)
0
>>> p = subprocess.Popen('sleep 20', shell=True, stdout=subprocess.PIPE)
>>> signal.alarm(1) ; p.communicate()
0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/subprocess.py", line 723, in communicate
stdout = self.stdout.read()
IOError: [Errno 4] Interrupted system call
>>>
Actual results:
Popen.communicate() call raises IOError due to EINTR.
Expected results:
Popen.communicate() should retry after EINTR and successfully return a result.
Additional info:
Looks related to bug 1065537 (probably the upstream patch for this bug depends on that one).
Comment 2Bohuslav "Slavek" Kabrda
2014-11-25 07:08:41 UTC
devel_ack+, we can fix this with the referenced patch.
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.
For information on the advisory, and where to find the updated
files, follow the link below.
If the solution does not work for you, open a new bug report.
https://rhn.redhat.com/errata/RHSA-2015-1330.html
Description of problem: Popen.communicate() raises IOError when the underlying read fails with EINTR due to a signal handler firing. It only happens when one of stdout or stderr is piped (therefore a possible workaround is to pipe both stdout and stderr and ignore the one that is not needed). We see this intermittently in our Beaker self-test suite, where we execute lsof and read its stdout. Traceback (most recent call last): File "/usr/lib/python2.6/site-packages/nose/suite.py", line 208, in run self.setUp() File "/usr/lib/python2.6/site-packages/nose/suite.py", line 291, in setUp self.setupContext(ancestor) File "/usr/lib/python2.6/site-packages/nose/suite.py", line 314, in setupContext try_run(context, names) File "/usr/lib/python2.6/site-packages/nose/util.py", line 469, in try_run return func() File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 337, in setup_package process.start() File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 148, in start self._wait_for_listen(self.listen_port) File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 158, in _wait_for_listen if check_listen(self.listen_port): File "/usr/lib/python2.6/site-packages/bkr/inttest/__init__.py", line 109, in check_listen stdout=subprocess.PIPE).communicate() File "/usr/lib64/python2.6/subprocess.py", line 723, in communicate stdout = self.stdout.read() IOError: [Errno 4] Interrupted system call The upstream bug is: http://bugs.python.org/issue12493 Fixed upstream in Python 2.7: http://hg.python.org/cpython/rev/6a28ccde2f1b Version-Release number of selected component (if applicable): python-2.6.6-52.el6.x86_64 How reproducible: easily Steps to Reproduce: The upstream test suite has a reliable reproducer, here is an example based on that: Python 2.6.6 (r266:84292, Nov 21 2013, 10:50:32) [GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import subprocess, sys, signal >>> def handler(signum, frame): pass ... >>> signal.signal(signal.SIGALRM, handler) 0 >>> p = subprocess.Popen('sleep 20', shell=True, stdout=subprocess.PIPE) >>> signal.alarm(1) ; p.communicate() 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.6/subprocess.py", line 723, in communicate stdout = self.stdout.read() IOError: [Errno 4] Interrupted system call >>> Actual results: Popen.communicate() call raises IOError due to EINTR. Expected results: Popen.communicate() should retry after EINTR and successfully return a result. Additional info: Looks related to bug 1065537 (probably the upstream patch for this bug depends on that one).