Explorar o código

- Don't cleanup file descriptors on first supervisord invocation:
this is a lame workaround for Snow Leopard systems that use
libdispatch and are receiving "Illegal instruction" messages at
supervisord startup time. Restarting supervisor may still cause a
crash on these systems.

Chris McDonough %!s(int64=15) %!d(string=hai) anos
pai
achega
ee5cad57f5
Modificáronse 3 ficheiros con 37 adicións e 3 borrados
  1. 6 0
      CHANGES.txt
  2. 4 1
      src/supervisor/supervisord.py
  3. 27 2
      src/supervisor/tests/test_supervisord.py

+ 6 - 0
CHANGES.txt

@@ -1,5 +1,11 @@
 Next Release
 
+  - Don't cleanup file descriptors on first supervisord invocation:
+    this is a lame workaround for Snow Leopard systems that use
+    libdispatch and are receiving "Illegal instruction" messages at
+    supervisord startup time.  Restarting supervisor may still cause a
+    crash on these systems.
+
   - Got rid of Medusa hashbang headers in various files to ease RPM
     packaging.
 

+ 4 - 1
src/supervisor/supervisord.py

@@ -67,7 +67,10 @@ class Supervisor:
         self.ticks = {}
 
     def main(self):
-        self.options.cleanup_fds()
+        if not self.options.first:
+            # prevent crash on libdispatch-based systems, at least for the
+            # first request
+            self.options.cleanup_fds()
         info_messages = []
         critical_messages = []
         warn_messages = []

+ 27 - 2
src/supervisor/tests/test_supervisord.py

@@ -70,7 +70,7 @@ class SupervisordTests(unittest.TestCase):
     def _makeOne(self, options):
         return self._getTargetClass()(options)
 
-    def test_main(self):
+    def test_main_first(self):
         options = DummyOptions()
         pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
         gconfigs = [DummyPGroupConfig(options,'foo', pconfigs=[pconfig])]
@@ -80,7 +80,7 @@ class SupervisordTests(unittest.TestCase):
         supervisord = self._makeOne(options)
         supervisord.main()
         self.assertEqual(options.environment_processed, True)
-        self.assertEqual(options.fds_cleaned_up, True)
+        self.assertEqual(options.fds_cleaned_up, False)
         self.assertEqual(options.rlimits_set, True)
         self.assertEqual(options.make_logger_messages,
                          (['setuid_called'], [], ['rlimits_set']))
@@ -95,6 +95,31 @@ class SupervisordTests(unittest.TestCase):
         self.assertEqual(options.pidfile_written, True)
         self.assertEqual(options.cleaned_up, True)
 
+    def test_main_notfirst(self):
+        options = DummyOptions()
+        pconfig = DummyPConfig(options, 'foo', 'foo', '/bin/foo')
+        gconfigs = [DummyPGroupConfig(options,'foo', pconfigs=[pconfig])]
+        options.process_group_configs = gconfigs
+        options.test = True
+        options.first = False
+        supervisord = self._makeOne(options)
+        supervisord.main()
+        self.assertEqual(options.environment_processed, True)
+        self.assertEqual(options.fds_cleaned_up, True)
+        self.failIf(hasattr(options, 'rlimits_set'))
+        self.assertEqual(options.make_logger_messages,
+                         (['setuid_called'], [], []))
+        self.assertEqual(options.autochildlogdir_cleared, True)
+        self.assertEqual(len(supervisord.process_groups), 1)
+        self.assertEqual(supervisord.process_groups['foo'].config.options,
+                         options)
+        self.assertEqual(options.environment_processed, True)
+        self.assertEqual(options.httpservers_opened, True)
+        self.assertEqual(options.signals_set, True)
+        self.assertEqual(options.daemonized, False)
+        self.assertEqual(options.pidfile_written, True)
+        self.assertEqual(options.cleaned_up, True)
+
     def test_reap(self):
         options = DummyOptions()
         options.waitpid_return = 1, 1