Merge "Sync eventlet_backdoor from oslo-incubator"
This commit is contained in:
@@ -1365,7 +1365,14 @@
|
||||
# Options defined in nova.openstack.common.eventlet_backdoor
|
||||
#
|
||||
|
||||
# port for eventlet backdoor to listen (integer value)
|
||||
# Enable eventlet backdoor. Acceptable values are 0, <port>
|
||||
# and <start>:<end>, where 0 results in listening on a random
|
||||
# tcp port number, <port> results in listening on the
|
||||
# specified port number and not enabling backdoorif it is in
|
||||
# use and <start>:<end> results in listening on the smallest
|
||||
# unused port number within the specified range of port
|
||||
# numbers. The chosen port is displayed in the service's log
|
||||
# file. (string value)
|
||||
#backdoor_port=<None>
|
||||
|
||||
|
||||
|
@@ -18,8 +18,11 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import errno
|
||||
import gc
|
||||
import os
|
||||
import pprint
|
||||
import socket
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
@@ -28,14 +31,34 @@ import eventlet.backdoor
|
||||
import greenlet
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova.openstack.common.gettextutils import _
|
||||
from nova.openstack.common import log as logging
|
||||
|
||||
help_for_backdoor_port = 'Acceptable ' + \
|
||||
'values are 0, <port> and <start>:<end>, where 0 results in ' + \
|
||||
'listening on a random tcp port number, <port> results in ' + \
|
||||
'listening on the specified port number and not enabling backdoor' + \
|
||||
'if it is in use and <start>:<end> results in listening on the ' + \
|
||||
'smallest unused port number within the specified range of port ' + \
|
||||
'numbers. The chosen port is displayed in the service\'s log file.'
|
||||
eventlet_backdoor_opts = [
|
||||
cfg.IntOpt('backdoor_port',
|
||||
cfg.StrOpt('backdoor_port',
|
||||
default=None,
|
||||
help='port for eventlet backdoor to listen')
|
||||
help='Enable eventlet backdoor. %s' % help_for_backdoor_port)
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(eventlet_backdoor_opts)
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EventletBackdoorConfigValueError(Exception):
|
||||
def __init__(self, port_range, help_msg, ex):
|
||||
msg = ('Invalid backdoor_port configuration %(range)s: %(ex)s. '
|
||||
'%(help)s' %
|
||||
{'range': port_range, 'ex': ex, 'help': help_msg})
|
||||
super(EventletBackdoorConfigValueError, self).__init__(msg)
|
||||
self.port_range = port_range
|
||||
|
||||
|
||||
def _dont_use_this():
|
||||
@@ -60,6 +83,33 @@ def _print_nativethreads():
|
||||
print()
|
||||
|
||||
|
||||
def _parse_port_range(port_range):
|
||||
if ':' not in port_range:
|
||||
start, end = port_range, port_range
|
||||
else:
|
||||
start, end = port_range.split(':', 1)
|
||||
try:
|
||||
start, end = int(start), int(end)
|
||||
if end < start:
|
||||
raise ValueError
|
||||
return start, end
|
||||
except ValueError as ex:
|
||||
raise EventletBackdoorConfigValueError(port_range, ex,
|
||||
help_for_backdoor_port)
|
||||
|
||||
|
||||
def _listen(host, start_port, end_port, listen_func):
|
||||
try_port = start_port
|
||||
while True:
|
||||
try:
|
||||
return listen_func((host, try_port))
|
||||
except socket.error as exc:
|
||||
if (exc.errno != errno.EADDRINUSE or
|
||||
try_port >= end_port):
|
||||
raise
|
||||
try_port += 1
|
||||
|
||||
|
||||
def initialize_if_enabled():
|
||||
backdoor_locals = {
|
||||
'exit': _dont_use_this, # So we don't exit the entire process
|
||||
@@ -72,6 +122,8 @@ def initialize_if_enabled():
|
||||
if CONF.backdoor_port is None:
|
||||
return None
|
||||
|
||||
start_port, end_port = _parse_port_range(str(CONF.backdoor_port))
|
||||
|
||||
# NOTE(johannes): The standard sys.displayhook will print the value of
|
||||
# the last expression and set it to __builtin__._, which overwrites
|
||||
# the __builtin__._ that gettext sets. Let's switch to using pprint
|
||||
@@ -82,8 +134,13 @@ def initialize_if_enabled():
|
||||
pprint.pprint(val)
|
||||
sys.displayhook = displayhook
|
||||
|
||||
sock = eventlet.listen(('localhost', CONF.backdoor_port))
|
||||
sock = _listen('localhost', start_port, end_port, eventlet.listen)
|
||||
|
||||
# In the case of backdoor port being zero, a port number is assigned by
|
||||
# listen(). In any case, pull the port number out here.
|
||||
port = sock.getsockname()[1]
|
||||
LOG.info(_('Eventlet backdoor listening on %(port)s for process %(pid)d') %
|
||||
{'port': port, 'pid': os.getpid()})
|
||||
eventlet.spawn_n(eventlet.backdoor.backdoor_server, sock,
|
||||
locals=backdoor_locals)
|
||||
return port
|
||||
|
Reference in New Issue
Block a user