NSX-MH: do update port on backend outside of db transaction

This should remove a cause for "Lock wait timeout" errors caused
by untimely eventlet yields.
This patch also adjust the DHCP handler for this plugin in
accordance with changes in network scheduling strategies.

Change-Id: I978985086d173d293a68eb37719db896f00b0e93
This commit is contained in:
Salvatore Orlando 2015-03-30 13:48:39 -07:00
parent 5aab7b792d
commit cd009f663b
2 changed files with 34 additions and 40 deletions

View File

@ -43,13 +43,7 @@ def handle_network_dhcp_access(plugin, context, network, action):
def handle_port_dhcp_access(plugin, context, port_data, action):
active_port = (cfg.CONF.NSX.metadata_mode == config.MetadataModes.INDIRECT
and port_data.get('device_owner') == const.DEVICE_OWNER_DHCP
and port_data.get('fixed_ips', []))
if active_port:
subnet_id = port_data['fixed_ips'][0]['subnet_id']
subnet = plugin.get_subnet(context, subnet_id)
_notify_rpc_agent(context, {'subnet': subnet}, 'subnet.update.end')
pass
def handle_port_metadata_access(plugin, context, port, is_delete=False):

View File

@ -1234,7 +1234,9 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
self._delete_port_queue_mapping(context, ret_port['id'])
self._process_port_queue_mapping(context, ret_port,
port_queue_id)
LOG.debug("Updating port: %s", port)
self._process_portbindings_create_and_update(context,
port['port'],
ret_port)
nsx_switch_id, nsx_port_id = nsx_utils.get_nsx_switch_and_port_id(
context.session, self.cluster, id)
# Convert Neutron security groups identifiers into NSX security
@ -1244,41 +1246,39 @@ class NsxPluginV2(addr_pair_db.AllowedAddressPairsMixin,
context.session, self.cluster, neutron_sg_id) for
neutron_sg_id in (ret_port[ext_sg.SECURITYGROUPS] or [])]
if nsx_port_id:
try:
switchlib.update_port(
self.cluster, nsx_switch_id, nsx_port_id,
id, tenant_id,
ret_port['name'],
ret_port['device_id'],
ret_port['admin_state_up'],
ret_port['mac_address'],
ret_port['fixed_ips'],
ret_port[psec.PORTSECURITY],
nsx_sec_profile_ids,
ret_port[qos.QUEUE],
ret_port.get(mac_ext.MAC_LEARNING),
ret_port.get(addr_pair.ADDRESS_PAIRS))
# Perform the NSX operation outside of the DB transaction
LOG.debug("Updating port %s on NSX backend", ret_port['id'])
if nsx_port_id:
try:
switchlib.update_port(
self.cluster, nsx_switch_id, nsx_port_id,
id, tenant_id,
ret_port['name'],
ret_port['device_id'],
ret_port['admin_state_up'],
ret_port['mac_address'],
ret_port['fixed_ips'],
ret_port[psec.PORTSECURITY],
nsx_sec_profile_ids,
ret_port[qos.QUEUE],
ret_port.get(mac_ext.MAC_LEARNING),
ret_port.get(addr_pair.ADDRESS_PAIRS))
# Update the port status from nsx. If we fail here hide it
# since the port was successfully updated but we were not
# able to retrieve the status.
ret_port['status'] = switchlib.get_port_status(
self.cluster, nsx_switch_id,
nsx_port_id)
# FIXME(arosen) improve exception handling.
except Exception:
ret_port['status'] = constants.PORT_STATUS_ERROR
LOG.exception(_LE("Unable to update port id: %s."),
nsx_port_id)
# If nsx_port_id is not in database or in nsx put in error state.
else:
# Update the port status from nsx. If we fail here hide it
# since the port was successfully updated but we were not
# able to retrieve the status.
ret_port['status'] = switchlib.get_port_status(
self.cluster, nsx_switch_id,
nsx_port_id)
# FIXME(arosen) improve exception handling.
except Exception:
ret_port['status'] = constants.PORT_STATUS_ERROR
LOG.exception(_LE("Unable to update port id: %s."),
nsx_port_id)
self._process_portbindings_create_and_update(context,
port['port'],
ret_port)
# If nsx_port_id is not in database or in nsx put in error state.
else:
ret_port['status'] = constants.PORT_STATUS_ERROR
return ret_port
def delete_port(self, context, id, l3_port_check=True,