summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Erdfelt <johannes.erdfelt@rackspace.com>2012-02-01 17:07:16 +0000
committerJohannes Erdfelt <johannes.erdfelt@rackspace.com>2012-02-01 18:21:23 +0000
commit093e4d38d511c7bb8d48fceebbfd8e350b533075 (patch)
tree57e4061e63ada48f3d1a03755a49b8759f75138f
parent8908d8ba499220c7495871eebcdd259d6dcdfb9d (diff)
downloadnova-093e4d38d511c7bb8d48fceebbfd8e350b533075.tar.gz
nova-093e4d38d511c7bb8d48fceebbfd8e350b533075.tar.xz
nova-093e4d38d511c7bb8d48fceebbfd8e350b533075.zip
Make sure multiple calls to _get_session() aren't nested
Fixes bug 924918 async_call_plugin() acquires a xenapi session as does the nested call to get_xenapi_host(). This can cause a deadlock if multiple greenthreads all block waiting for the outer sessions to be freed to allocate the inner session. This change moves the call to get_xenapi_host() to outside the with statement to ensure calls to _get_session() aren't nested. Change-Id: I8f5490f40a9ccaf74a276187f66519a5d5f52b2e
-rw-r--r--nova/virt/xenapi_conn.py6
1 files changed, 5 insertions, 1 deletions
diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py
index 6b67b8b88..6fda205d0 100644
--- a/nova/virt/xenapi_conn.py
+++ b/nova/virt/xenapi_conn.py
@@ -544,10 +544,14 @@ class XenAPISession(object):
def async_call_plugin(self, plugin, fn, args):
"""Call Async.host.call_plugin on a background thread."""
+ # NOTE(johannes): Fetch host before we acquire a session. Since
+ # _get_session() acquires a session too, it can result in a deadlock
+ # if multiple greenthreads race with each other. See bug 924918
+ host = self.get_xenapi_host()
with self._get_session() as session:
return tpool.execute(self._unwrap_plugin_exceptions,
session.xenapi.Async.host.call_plugin,
- self.get_xenapi_host(), plugin, fn, args)
+ host, plugin, fn, args)
def wait_for_task(self, task, uuid=None):
"""Return the result of the given task. The task is polled