]> review.fuel-infra Code Review - openstack-build/cinder-build.git/commitdiff
Restore SIGPIPE default action for subprocesses
authorThierry Carrez <thierry@openstack.org>
Thu, 20 Sep 2012 12:21:00 +0000 (14:21 +0200)
committerThierry Carrez <thierry@openstack.org>
Thu, 20 Sep 2012 13:26:28 +0000 (15:26 +0200)
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 cinder.utils.execute and cinder-rootwrap
created subprocesses.

Fixes bug 1053364

Change-Id: I4b3307bd2f0f5d0da529d8b7d80fabae28c57732

bin/cinder-rootwrap
cinder/utils.py

index 04b8979fb196c71f1cd38e093df9c0035f04ef2d..3ea6cc3704111b9a11a83b484243196326c88163 100755 (executable)
@@ -34,6 +34,7 @@
 
 import ConfigParser
 import os
+import signal
 import subprocess
 import sys
 
@@ -42,6 +43,13 @@ RC_UNAUTHORIZED = 99
 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)
@@ -77,6 +85,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)
index bfcda366a2b3feedbd4f0cebd9411959d61aa2ac..113370c08b0a3ab2929aa1b02aa25e569e1c2a95 100644 (file)
@@ -33,6 +33,7 @@ import random
 import re
 import shlex
 import shutil
+import signal
 import socket
 import struct
 import sys
@@ -90,6 +91,12 @@ def fetchfile(url, target):
     execute('curl', '--fail', url, '-o', target)
 
 
+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, **kwargs):
     """Helper method to execute command with optional retry.
 
@@ -160,6 +167,7 @@ def execute(*cmd, **kwargs):
                                    stdout=_PIPE,
                                    stderr=_PIPE,
                                    close_fds=True,
+                                   preexec_fn=_subprocess_setup,
                                    shell=shell)
             result = None
             if process_input is not None: