Undo the eventlet monkey patch for the privileged daemon
Change-Id: I422125b137a3beadb0a79f5944a19fce62f093d6 Closes-Bug: #1887506
This commit is contained in:
parent
071ab48007
commit
1dc378c76f
@ -6,7 +6,7 @@ cffi==1.7.0
|
||||
debtcollector==1.2.0
|
||||
docutils==0.11
|
||||
dulwich==0.15.0
|
||||
eventlet==0.18.2
|
||||
eventlet==0.21.0
|
||||
extras==1.0.0
|
||||
fixtures==3.0.0
|
||||
gitdb==0.6.4
|
||||
|
@ -57,6 +57,7 @@ import tempfile
|
||||
import threading
|
||||
|
||||
import eventlet
|
||||
from eventlet import patcher
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import encodeutils
|
||||
@ -75,6 +76,25 @@ if platform.system() == 'Linux':
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
EVENTLET_MODULES = ('os', 'select', 'socket', 'thread', 'time', 'MySQLdb',
|
||||
'builtins', 'subprocess')
|
||||
EVENTLET_LIBRARIES = []
|
||||
|
||||
|
||||
def _null():
|
||||
return []
|
||||
|
||||
|
||||
for module in EVENTLET_MODULES:
|
||||
if hasattr(patcher, '_green_%s_modules' % module):
|
||||
method = getattr(patcher, '_green_%s_modules' % module)
|
||||
elif hasattr(patcher, '_green_%s' % module):
|
||||
method = getattr(patcher, '_green_%s' % module)
|
||||
else:
|
||||
method = _null()
|
||||
EVENTLET_LIBRARIES.append((module, method))
|
||||
|
||||
|
||||
@enum.unique
|
||||
class StdioFd(enum.IntEnum):
|
||||
# NOTE(gus): We can't use sys.std*.fileno() here. sys.std*
|
||||
@ -258,6 +278,21 @@ def replace_logging(handler, log_root=None):
|
||||
log_root.addHandler(handler)
|
||||
|
||||
|
||||
def un_monkey_patch():
|
||||
for eventlet_mod_name, func_modules in EVENTLET_LIBRARIES:
|
||||
if not eventlet.patcher.is_monkey_patched(eventlet_mod_name):
|
||||
continue
|
||||
|
||||
for name, mod in func_modules():
|
||||
patched_mod = sys.modules.get(name)
|
||||
orig_mod = eventlet.patcher.original(name)
|
||||
for attr_name in mod.__patched__:
|
||||
patched_attr = getattr(mod, attr_name, None)
|
||||
unpatched_attr = getattr(orig_mod, attr_name, None)
|
||||
if patched_attr is not None:
|
||||
setattr(patched_mod, attr_name, unpatched_attr)
|
||||
|
||||
|
||||
class ForkingClientChannel(_ClientChannel):
|
||||
def __init__(self, context):
|
||||
"""Start privsep daemon using fork()
|
||||
@ -279,6 +314,7 @@ class ForkingClientChannel(_ClientChannel):
|
||||
|
||||
if os.fork() == 0:
|
||||
# child
|
||||
un_monkey_patch()
|
||||
|
||||
channel = comm.ServerChannel(sock_b)
|
||||
sock_a.close()
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
|
||||
import copy
|
||||
import eventlet
|
||||
import fixtures
|
||||
import functools
|
||||
import logging as pylogging
|
||||
@ -215,3 +216,30 @@ class ClientChannelTestCase(base.BaseTestCase):
|
||||
with mock.patch.object(daemon.LOG, 'warning') as mock_warning:
|
||||
self.client_channel.out_of_band([daemon.Message.PING])
|
||||
mock_warning.assert_called_once()
|
||||
|
||||
|
||||
class UnMonkeyPatch(base.BaseTestCase):
|
||||
|
||||
def test_un_monkey_patch(self):
|
||||
self.assertFalse(any(
|
||||
eventlet.patcher.is_monkey_patched(eventlet_mod_name)
|
||||
for eventlet_mod_name in daemon.EVENTLET_MODULES))
|
||||
|
||||
eventlet.monkey_patch()
|
||||
self.assertTrue(any(
|
||||
eventlet.patcher.is_monkey_patched(eventlet_mod_name)
|
||||
for eventlet_mod_name in daemon.EVENTLET_MODULES))
|
||||
|
||||
daemon.un_monkey_patch()
|
||||
for eventlet_mod_name, func_modules in daemon.EVENTLET_LIBRARIES:
|
||||
if not eventlet.patcher.is_monkey_patched(eventlet_mod_name):
|
||||
continue
|
||||
|
||||
for name, green_mod in func_modules():
|
||||
orig_mod = eventlet.patcher.original(name)
|
||||
patched_mod = sys.modules.get(name)
|
||||
for attr_name in green_mod.__patched__:
|
||||
un_monkey_patched_attr = getattr(patched_mod, attr_name,
|
||||
None)
|
||||
original_attr = getattr(orig_mod, attr_name, None)
|
||||
self.assertEqual(un_monkey_patched_attr, original_attr)
|
||||
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
other:
|
||||
- |
|
||||
The ``oslo.privsep`` client can be called from a program using eventlet.
|
||||
If ``eventlet.monkey_patch``, some libraries will be patched, for example
|
||||
``threading`` or ``os``. When the root daemon is forked from the client
|
||||
process, those libraries remain patched. Now, when the daemon is forked
|
||||
from the client process, those libraries and methods are restored to the
|
||||
original values. The goal is to prevent some timeouts when using eventlet
|
||||
threads (user threads); system threads are preemptive and the code does
|
||||
not need to care about the executor token.
|
@ -7,6 +7,6 @@ oslo.i18n>=3.15.3 # Apache-2.0
|
||||
oslo.config>=5.2.0 # Apache-2.0
|
||||
oslo.utils>=3.33.0 # Apache-2.0
|
||||
cffi>=1.7.0 # MIT
|
||||
eventlet!=0.18.3,!=0.20.1,>=0.18.2 # MIT
|
||||
eventlet>=0.21.0 # MIT
|
||||
greenlet>=0.4.14 # MIT
|
||||
msgpack>=0.6.0 # Apache-2.0
|
||||
|
Loading…
x
Reference in New Issue
Block a user