summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenkata anil <anilvenkata@redhat.com>2019-01-02 05:11:12 -0500
committervenkata anil <anilvenkata@redhat.com>2019-01-03 23:41:30 -0500
commit811650783d32accd2b49f907ddc520955146962c (patch)
treed4de998894869c87096830a430b4c41d396c7f54
parentd987a4a84c40ac905a1295341c0e05a73c7b6b1c (diff)
Avoid eventlet_backdoor listing on same port
Oslo.service is binding to same port when we provide a port range as eventlet is internally setting SO_REUSEPORT flag (starting from eventlet version v0.20). And there is a flag (reuse_port) introduced in v0.22 to give control to user to avoid SO_REUSEPORT. In this patch, first we try passing reuse_port=False, if this fails then directly open socket and listen instead of eventlist.listen. Closes-Bug: #1810280 Change-Id: Idc842acc7e430199c76fe12785b0bf0e7a58e121
Notes
Notes (review): Code-Review+2: Ben Nemec <openstack@nemebean.com> Code-Review+2: ChangBo Guo(gcb) <glongwave@gmail.com> Workflow+1: ChangBo Guo(gcb) <glongwave@gmail.com> Code-Review+2: Zane Bitter <zbitter@redhat.com> Code-Review+1: Hervé Beraud <hberaud@redhat.com> Verified+2: Zuul Submitted-by: Zuul Submitted-at: Thu, 17 Jan 2019 13:52:22 +0000 Reviewed-on: https://review.openstack.org/627952 Project: openstack/oslo.service Branch: refs/heads/master
-rw-r--r--oslo_service/eventlet_backdoor.py21
-rw-r--r--oslo_service/tests/test_eventlet_backdoor.py8
2 files changed, 25 insertions, 4 deletions
diff --git a/oslo_service/eventlet_backdoor.py b/oslo_service/eventlet_backdoor.py
index f4ecbf4..a82d5e2 100644
--- a/oslo_service/eventlet_backdoor.py
+++ b/oslo_service/eventlet_backdoor.py
@@ -21,13 +21,13 @@ import gc
21import logging 21import logging
22import os 22import os
23import pprint 23import pprint
24import socket
25import sys 24import sys
26import traceback 25import traceback
27 26
28import eventlet.backdoor 27import eventlet.backdoor
29import greenlet 28import greenlet
30 29
30from eventlet.green import socket
31from oslo_service._i18n import _ 31from oslo_service._i18n import _
32from oslo_service import _options 32from oslo_service import _options
33 33
@@ -121,11 +121,24 @@ def _parse_port_range(port_range):
121 port_range, ex, _options.help_for_backdoor_port) 121 port_range, ex, _options.help_for_backdoor_port)
122 122
123 123
124def _listen(host, start_port, end_port, listen_func): 124def _listen_func(host, port):
125 # eventlet is setting SO_REUSEPORT by default from v0.20.
126 # But we can configure it by passing reuse_port argument
127 # from v0.22
128 try:
129 return eventlet.listen((host, port), reuse_port=False)
130 except TypeError:
131 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
132 sock.bind((host, port))
133 sock.listen(50)
134 return sock
135
136
137def _listen(host, start_port, end_port):
125 try_port = start_port 138 try_port = start_port
126 while True: 139 while True:
127 try: 140 try:
128 return listen_func((host, try_port)) 141 return _listen_func(host, try_port)
129 except socket.error as exc: 142 except socket.error as exc:
130 if (exc.errno != errno.EADDRINUSE or 143 if (exc.errno != errno.EADDRINUSE or
131 try_port >= end_port): 144 try_port >= end_port):
@@ -169,7 +182,7 @@ def _initialize_if_enabled(conf):
169 182
170 if conf.backdoor_socket is None: 183 if conf.backdoor_socket is None:
171 start_port, end_port = _parse_port_range(str(conf.backdoor_port)) 184 start_port, end_port = _parse_port_range(str(conf.backdoor_port))
172 sock = _listen('localhost', start_port, end_port, eventlet.listen) 185 sock = _listen('localhost', start_port, end_port)
173 # In the case of backdoor port being zero, a port number is assigned by 186 # In the case of backdoor port being zero, a port number is assigned by
174 # listen(). In any case, pull the port number out here. 187 # listen(). In any case, pull the port number out here.
175 where_running = sock.getsockname()[1] 188 where_running = sock.getsockname()[1]
diff --git a/oslo_service/tests/test_eventlet_backdoor.py b/oslo_service/tests/test_eventlet_backdoor.py
index 4c00c57..480761e 100644
--- a/oslo_service/tests/test_eventlet_backdoor.py
+++ b/oslo_service/tests/test_eventlet_backdoor.py
@@ -106,6 +106,14 @@ class BackdoorPortTest(base.ServiceBaseTestCase):
106 eventlet_backdoor.initialize_if_enabled, self.conf) 106 eventlet_backdoor.initialize_if_enabled, self.conf)
107 107
108 @mock.patch.object(eventlet, 'spawn') 108 @mock.patch.object(eventlet, 'spawn')
109 def test_backdoor_port_range_inuse(self, spawn_mock):
110 self.config(backdoor_port='8800:8801')
111 port = eventlet_backdoor.initialize_if_enabled(self.conf)
112 self.assertEqual(8800, port)
113 port = eventlet_backdoor.initialize_if_enabled(self.conf)
114 self.assertEqual(8801, port)
115
116 @mock.patch.object(eventlet, 'spawn')
109 @mock.patch.object(eventlet, 'listen') 117 @mock.patch.object(eventlet, 'listen')
110 def test_backdoor_port_range(self, listen_mock, spawn_mock): 118 def test_backdoor_port_range(self, listen_mock, spawn_mock):
111 self.config(backdoor_port='8800:8899') 119 self.config(backdoor_port='8800:8899')