Merge "Break down _bind_port_if_needed in ML2"
This commit is contained in:
commit
bf800f9c6c
@ -266,9 +266,29 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
|
||||
def _bind_port_if_needed(self, context, allow_notify=False,
|
||||
need_notify=False):
|
||||
plugin_context = context._plugin_context
|
||||
port_id = context.current['id']
|
||||
# Binding limit does not need to be tunable because no
|
||||
# more than a couple of attempts should ever be required in
|
||||
# normal operation.
|
||||
for count in range(1, MAX_BIND_TRIES + 1):
|
||||
if count > 1:
|
||||
# multiple attempts shouldn't happen very often so we log each
|
||||
# attempt after the 1st.
|
||||
greenthread.sleep(0) # yield
|
||||
LOG.info(_LI("Attempt %(count)s to bind port %(port)s"),
|
||||
{'count': count, 'port': context.current['id']})
|
||||
context, need_notify, try_again = self._attempt_binding(
|
||||
context, need_notify)
|
||||
if not try_again:
|
||||
if allow_notify and need_notify:
|
||||
self._notify_port_updated(context)
|
||||
return context
|
||||
|
||||
LOG.error(_LE("Failed to commit binding results for %(port)s "
|
||||
"after %(max)s tries"),
|
||||
{'port': context.current['id'], 'max': MAX_BIND_TRIES})
|
||||
return context
|
||||
|
||||
def _attempt_binding(self, context, need_notify):
|
||||
# Since the mechanism driver bind_port() calls must be made
|
||||
# outside a DB transaction locking the port state, it is
|
||||
# possible (but unlikely) that the port's state could change
|
||||
@ -277,41 +297,22 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
# thread commits its results, the already committed results are
|
||||
# used. If attributes such as binding:host_id,
|
||||
# binding:profile, or binding:vnic_type are updated
|
||||
# concurrently, this loop retries binding using the new
|
||||
# values.
|
||||
count = 0
|
||||
while True:
|
||||
# concurrently, the try_again flag is returned to indicate that
|
||||
# the commit was unsuccessful.
|
||||
plugin_context = context._plugin_context
|
||||
port_id = context.current['id']
|
||||
binding = context._binding
|
||||
try_again = False
|
||||
# First, determine whether it is necessary and possible to
|
||||
# bind the port.
|
||||
binding = context._binding
|
||||
if (binding.vif_type != portbindings.VIF_TYPE_UNBOUND
|
||||
or not binding.host):
|
||||
# We either don't need to bind the port, or can't, so
|
||||
# notify if needed and return.
|
||||
if allow_notify and need_notify:
|
||||
self._notify_port_updated(context)
|
||||
return context
|
||||
|
||||
# Limit binding attempts to avoid any possibility of
|
||||
# infinite looping and to ensure an error is logged
|
||||
# instead. This does not need to be tunable because no
|
||||
# more than a couple attempts should ever be required in
|
||||
# normal operation. Log at info level if not 1st attempt.
|
||||
count += 1
|
||||
if count > MAX_BIND_TRIES:
|
||||
LOG.error(_LE("Failed to commit binding results for %(port)s "
|
||||
"after %(max)s tries"),
|
||||
{'port': port_id, 'max': MAX_BIND_TRIES})
|
||||
return context
|
||||
if count > 1:
|
||||
greenthread.sleep(0) # yield
|
||||
LOG.info(_LI("Attempt %(count)s to bind port %(port)s"),
|
||||
{'count': count, 'port': port_id})
|
||||
# We either don't need to bind the port or can't
|
||||
return context, need_notify, try_again
|
||||
|
||||
# The port isn't already bound and the necessary
|
||||
# information is available, so attempt to bind the port.
|
||||
bind_context = self._bind_port(context)
|
||||
|
||||
# Now try to commit result of attempting to bind the port.
|
||||
new_context, did_commit = self._commit_port_binding(
|
||||
plugin_context, port_id, binding, bind_context)
|
||||
@ -321,13 +322,16 @@ class Ml2Plugin(db_base_plugin_v2.NeutronDbPluginV2,
|
||||
# transaction that completed before the deletion.
|
||||
LOG.debug("Port %s has been deleted concurrently",
|
||||
port_id)
|
||||
return context
|
||||
need_notify = False
|
||||
return context, need_notify, try_again
|
||||
# Need to notify if we succeed and our results were
|
||||
# committed.
|
||||
if did_commit and (new_context._binding.vif_type !=
|
||||
portbindings.VIF_TYPE_BINDING_FAILED):
|
||||
need_notify = True
|
||||
context = new_context
|
||||
return new_context, need_notify, try_again
|
||||
try_again = True
|
||||
return new_context, need_notify, try_again
|
||||
|
||||
def _bind_port(self, orig_context):
|
||||
# Construct a new PortContext from the one from the previous
|
||||
|
Loading…
Reference in New Issue
Block a user