Restore SIGPIPE default action for subprocesses
Python ignores SIGPIPE on startup, because it prefers to check every write and raise an IOError exception rather than taking the signal. Most Unix subprocesses don't expect to work this way. This patch (adapted from Colin Watson's post at http://tinyurl.com/2a7mzh5) sets SIGPIPE back to the default action for quantum.agent.linux.utils.execute, quantum.common.utils.execute and quantum-rootwrap created subprocesses. Fixes bug 1053364 Change-Id: Ib805f1f8846c245b75a5ea64278c840b823c1fb2
This commit is contained in:
parent
5a5dec2d65
commit
3bbf281b15
@ -38,6 +38,7 @@
|
||||
|
||||
import ConfigParser
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@ -47,6 +48,12 @@ RC_NOCOMMAND = 98
|
||||
RC_BADCONFIG = 97
|
||||
|
||||
|
||||
def _subprocess_setup():
|
||||
# Python installs a SIGPIPE handler by default. This is usually not what
|
||||
# non-Python subprocesses expect.
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Split arguments, require at least a command
|
||||
execname = sys.argv.pop(0)
|
||||
@ -84,6 +91,7 @@ if __name__ == '__main__':
|
||||
stdin=sys.stdin,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr,
|
||||
preexec_fn=_subprocess_setup,
|
||||
env=filtermatch.get_environment(userargs))
|
||||
obj.wait()
|
||||
sys.exit(obj.returncode)
|
||||
|
@ -21,6 +21,7 @@ import fcntl
|
||||
import logging
|
||||
import os
|
||||
import shlex
|
||||
import signal
|
||||
import socket
|
||||
import struct
|
||||
|
||||
@ -30,6 +31,12 @@ from eventlet.green import subprocess
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _subprocess_setup():
|
||||
# Python installs a SIGPIPE handler by default. This is usually not what
|
||||
# non-Python subprocesses expect.
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
|
||||
|
||||
def execute(cmd, root_helper=None, process_input=None, addl_env=None,
|
||||
check_exit_code=True, return_stderr=False):
|
||||
if root_helper:
|
||||
@ -42,6 +49,7 @@ def execute(cmd, root_helper=None, process_input=None, addl_env=None,
|
||||
env.update(addl_env)
|
||||
obj = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
preexec_fn=_subprocess_setup,
|
||||
env=env)
|
||||
|
||||
_stdout, _stderr = (process_input and
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import uuid
|
||||
|
||||
@ -47,6 +48,12 @@ def boolize(subject):
|
||||
return subject
|
||||
|
||||
|
||||
def _subprocess_setup():
|
||||
# Python installs a SIGPIPE handler by default. This is usually not what
|
||||
# non-Python subprocesses expect.
|
||||
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
|
||||
|
||||
|
||||
def execute(cmd, process_input=None, addl_env=None, check_exit_code=True):
|
||||
logging.debug("Running cmd: %s", cmd)
|
||||
env = os.environ.copy()
|
||||
@ -54,6 +61,7 @@ def execute(cmd, process_input=None, addl_env=None, check_exit_code=True):
|
||||
env.update(addl_env)
|
||||
obj = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
preexec_fn=_subprocess_setup,
|
||||
env=env)
|
||||
result = None
|
||||
if process_input is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user