summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-05-17 20:51:50 +0000
committerGerrit Code Review <review@openstack.org>2012-05-17 20:51:50 +0000
commit289a1088f3f3b24f4f5bf069b9845daa10c77b7e (patch)
tree3c2142fa68bf6716144deeb6fe6d9a03fe681236
parent5a9e678cc08bc17d072ae1a4d23ab8bd7841ed4a (diff)
parentf799f7713052ac406e5ff8b72c959ba2d1c3fe58 (diff)
Merge "Add eventlet backdoor to facilitate troubleshooting."
-rw-r--r--nova/common/eventlet_backdoor.py69
-rw-r--r--nova/service.py5
2 files changed, 73 insertions, 1 deletions
diff --git a/nova/common/eventlet_backdoor.py b/nova/common/eventlet_backdoor.py
new file mode 100644
index 000000000..c2d4b74bf
--- /dev/null
+++ b/nova/common/eventlet_backdoor.py
@@ -0,0 +1,69 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright (c) 2012 Openstack, LLC.
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import gc
+import traceback
+
+import eventlet
+import eventlet.backdoor
+import greenlet
+
+from nova import flags
+from nova.openstack.common import cfg
+
+eventlet_backdoor_opts = [
+ cfg.IntOpt('backdoor_port',
+ default=None,
+ help='port for eventlet backdoor to listen')
+ ]
+
+FLAGS = flags.FLAGS
+FLAGS.register_opts(eventlet_backdoor_opts)
+
+
+def dont_use_this():
+ print "Don't use this, just disconnect instead"
+
+
+def find_objects(t):
+ return filter(lambda o: isinstance(o, t), gc.get_objects())
+
+
+def print_greenthreads():
+ for i, gt in enumerate(find_objects(greenlet.greenlet)):
+ print i, gt
+ traceback.print_stack(gt.gr_frame)
+ print
+
+
+backdoor_locals = {
+ '_': None, # So it doesn't interfere with the global
+ 'exit': dont_use_this, # So we don't exit the entire process
+ 'quit': dont_use_this, # So we don't exit the entire process
+ 'fo': find_objects,
+ 'pgt': print_greenthreads,
+}
+
+
+def initialize_if_enabled():
+ if FLAGS.backdoor_port is None:
+ return
+
+ eventlet.spawn(eventlet.backdoor.backdoor_server,
+ eventlet.listen(('localhost', FLAGS.backdoor_port)),
+ locals=backdoor_locals)
diff --git a/nova/service.py b/nova/service.py
index 7d5db5a0a..6ff50d98e 100644
--- a/nova/service.py
+++ b/nova/service.py
@@ -27,6 +27,7 @@ import signal
import eventlet
import greenlet
+from nova.common import eventlet_backdoor
from nova import context
from nova import db
from nova import exception
@@ -80,7 +81,7 @@ service_opts = [
help='IP address for OpenStack Volume API to listen'),
cfg.IntOpt('osapi_volume_listen_port',
default=8776,
- help='port for os volume api to listen'),
+ help='port for os volume api to listen')
]
FLAGS = flags.FLAGS
@@ -431,6 +432,8 @@ def serve(*servers):
for server in servers:
_launcher.launch_server(server)
+ eventlet_backdoor.initialize_if_enabled()
+
def wait():
LOG.debug(_('Full set of FLAGS:'))