diff options
author | armando-migliaccio <armamig@gmail.com> | 2013-11-18 16:10:48 -0800 |
---|---|---|
committer | Yaguang Tang <yaguang.tang@canonical.com> | 2013-11-26 17:36:23 +0800 |
commit | ef9aec1cb6ec0d5fae699f9bb1f0d042530de5de (patch) | |
tree | c7974c8eb40606ef59b13da7608a408e6660504e /nova/network | |
parent | f7cfc1cc6ba51617d02dd2b55419fad52a51793b (diff) | |
download | nova-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.py | 1 | ||||
-rw-r--r-- | nova/network/neutronv2/api.py | 10 |
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) |