summaryrefslogtreecommitdiff
path: root/nova/network
diff options
context:
space:
mode:
authorarmando-migliaccio <armamig@gmail.com>2013-11-18 16:10:48 -0800
committerYaguang Tang <yaguang.tang@canonical.com>2013-11-26 17:36:23 +0800
commitef9aec1cb6ec0d5fae699f9bb1f0d042530de5de (patch)
treec7974c8eb40606ef59b13da7608a408e6660504e /nova/network
parentf7cfc1cc6ba51617d02dd2b55419fad52a51793b (diff)
downloadnova-ef9aec1cb6ec0d5fae699f9bb1f0d042530de5de.tar.gz
Address infinite loop in nova compute when getting network info
Move the refresh_cache decorator to get_instance_nw_info. In fact, _get_instance_nw_info is called by the decorator itself, potentially causing an infinite loop in case nw_info is not of the expected value. This is also inline with the method's purpose, as stated by the docstring. At the same time, ensure that delete_port_for_instance and allocate_for_instance continue to refresh the cache by using the decorated version. Also, add a couple of debug traces that are friendly to the developer. Partial-bug: 1235435 Related-bug: 1251792 Change-Id: I06f8634ea241d05ac8fbcc290adf0cb23829f3e4 (cherry picked from commit 2e520496c369a8ef646820ec068cc4416ab50eca)
Diffstat (limited to 'nova/network')
-rw-r--r--nova/network/api.py1
-rw-r--r--nova/network/neutronv2/api.py10
2 files changed, 7 insertions, 4 deletions
diff --git a/nova/network/api.py b/nova/network/api.py
index a36a023167..cd3d6d08ee 100644
--- a/nova/network/api.py
+++ b/nova/network/api.py
@@ -68,6 +68,7 @@ def refresh_cache(f):
def update_instance_cache_with_nw_info(api, context, instance, nw_info=None,
update_cells=True):
try:
+ LOG.debug(_('Updating cache with info: %s'), nw_info)
if not isinstance(nw_info, network_model.NetworkInfo):
nw_info = None
if not nw_info:
diff --git a/nova/network/neutronv2/api.py b/nova/network/neutronv2/api.py
index ffb6d50010..a41924df6d 100644
--- a/nova/network/neutronv2/api.py
+++ b/nova/network/neutronv2/api.py
@@ -357,7 +357,7 @@ class API(base.Base):
msg = _("Failed to delete port %s")
LOG.exception(msg, port_id)
- nw_info = self._get_instance_nw_info(context, instance, networks=nets)
+ nw_info = self.get_instance_nw_info(context, instance, networks=nets)
# NOTE(danms): Only return info about ports we created in this run.
# In the initial allocation case, this will be everything we created,
# and in later runs will only be what was created that time. Thus,
@@ -438,7 +438,7 @@ class API(base.Base):
LOG.exception(_("Failed to delete neutron port %s") %
port_id)
- return self._get_instance_nw_info(context, instance)
+ return self.get_instance_nw_info(context, instance)
def list_ports(self, context, **search_opts):
"""List ports for the client based on search options."""
@@ -448,6 +448,7 @@ class API(base.Base):
"""Return the port for the client given the port id."""
return neutronv2.get_client(context).show_port(port_id)
+ @refresh_cache
def get_instance_nw_info(self, context, instance, networks=None):
"""Return network information for specified instance
and update cache.
@@ -458,8 +459,9 @@ class API(base.Base):
return result
def _get_instance_nw_info(self, context, instance, networks=None):
- LOG.debug(_('get_instance_nw_info() for %s'),
- instance['display_name'])
+ # keep this caching-free version of the get_instance_nw_info method
+ # because it is used by the caching logic itself.
+ LOG.debug(_('get_instance_nw_info() for %s'), instance['display_name'])
nw_info = self._build_network_info_model(context, instance, networks)
return network_model.NetworkInfo.hydrate(nw_info)