Merge "NSX|V: add locking for interface management"

This commit is contained in:
Jenkins 2015-11-25 17:25:26 +00:00 committed by Gerrit Code Review
commit e87cd64ea8
2 changed files with 113 additions and 53 deletions

View File

@ -621,68 +621,82 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
self._add_router_services_on_available_edge(context, self._add_router_services_on_available_edge(context,
router_id) router_id)
def _base_add_router_interface(self, context, router_id, interface_info):
with locking.LockManager.get_lock("router", lock_file_prefix="bind-",
external=True):
return super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface(
context, router_id, interface_info)
def add_router_interface(self, context, router_id, interface_info): def add_router_interface(self, context, router_id, interface_info):
self.plugin._check_intf_number_of_router(context, router_id) self.plugin._check_intf_number_of_router(context, router_id)
edge_id = edge_utils.get_router_edge_id(context, router_id) edge_id = edge_utils.get_router_edge_id(context, router_id)
router_db = self.plugin._get_router(context, router_id) router_db = self.plugin._get_router(context, router_id)
if edge_id: if edge_id:
is_migrated = False is_migrated = False
with locking.LockManager.get_lock( with locking.LockManager.get_lock("router",
str(edge_id), lock_file_prefix="bind-",
lock_file_prefix=NSXV_ROUTER_RECONFIG): external=True):
router_ids = self.edge_manager.get_routers_on_same_edge( with locking.LockManager.get_lock(
context, router_id) str(edge_id),
info = super(nsx_v.NsxVPluginV2, lock_file_prefix=NSXV_ROUTER_RECONFIG,
self.plugin).add_router_interface( external=True):
context, router_id, interface_info) router_ids = self.edge_manager.get_routers_on_same_edge(
subnet = self.plugin.get_subnet(context, info['subnet_id']) context, router_id)
network_id = subnet['network_id'] info = super(nsx_v.NsxVPluginV2,
# Collect all conflict networks whose cidr are overlapped self.plugin).add_router_interface(
# with networks attached to the router and conflct routers context, router_id, interface_info)
# which has same network with the router's. subnet = self.plugin.get_subnet(context, info['subnet_id'])
conflict_network_ids, conflict_router_ids, _ = ( network_id = subnet['network_id']
self._get_conflict_network_and_router_ids_by_intf( # Collect all conflict networks whose cidr are overlapped
context, router_id)) # with networks attached to the router and conflct routers
# which has same network with the router's.
conflict_network_ids, conflict_router_ids, _ = (
self._get_conflict_network_and_router_ids_by_intf(
context, router_id))
_, new_conflict_router_ids = ( _, new_conflict_router_ids = (
self._get_available_and_conflicting_ids(context, self._get_available_and_conflicting_ids(context,
router_id)) router_id))
conflict_router_ids.extend(new_conflict_router_ids) conflict_router_ids.extend(new_conflict_router_ids)
conflict_router_ids = list(set(conflict_router_ids)) conflict_router_ids = list(set(conflict_router_ids))
interface_ports = ( interface_ports = (
self.plugin._get_router_interface_ports_by_network( self.plugin._get_router_interface_ports_by_network(
context, router_id, network_id)) context, router_id, network_id))
# Consider whether another subnet of the same network # Consider whether another subnet of the same network
# has been attached to the router. # has been attached to the router.
if len(interface_ports) > 1:
is_conflict = self.edge_manager.is_router_conflict_on_edge(
context, router_id, conflict_router_ids,
conflict_network_ids, 0)
else:
is_conflict = self.edge_manager.is_router_conflict_on_edge(
context, router_id, conflict_router_ids,
conflict_network_ids, 1)
if is_conflict:
if len(interface_ports) > 1: if len(interface_ports) > 1:
self._remove_router_services_on_edge( is_conflict = (
context, router_id) self.edge_manager.is_router_conflict_on_edge(
context, router_id, conflict_router_ids,
conflict_network_ids, 0))
else: else:
self._remove_router_services_on_edge( is_conflict = (
self.edge_manager.is_router_conflict_on_edge(
context, router_id, conflict_router_ids,
conflict_network_ids, 1))
if is_conflict:
if len(interface_ports) > 1:
self._remove_router_services_on_edge(
context, router_id)
else:
self._remove_router_services_on_edge(
context, router_id, network_id)
self._unbind_router_on_edge(context, router_id)
is_migrated = True
else:
address_groups = self.plugin._get_address_groups(
context, router_id, network_id) context, router_id, network_id)
self._unbind_router_on_edge(context, router_id) edge_utils.update_internal_interface(
is_migrated = True self.nsx_v, context, router_id,
else: network_id, address_groups,
address_groups = self.plugin._get_address_groups( router_db.admin_state_up)
context, router_id, network_id) if router_db.gw_port and router_db.enable_snat:
edge_utils.update_internal_interface( self._update_nat_rules_on_routers(
self.nsx_v, context, router_id, context, router_id, router_ids)
network_id, address_groups, router_db.admin_state_up) self._update_subnets_and_dnat_firewall_on_routers(
if router_db.gw_port and router_db.enable_snat: context, router_id, router_ids,
self._update_nat_rules_on_routers( allow_external=True)
context, router_id, router_ids)
self._update_subnets_and_dnat_firewall_on_routers(
context, router_id, router_ids, allow_external=True)
if is_migrated: if is_migrated:
self._bind_router_on_available_edge( self._bind_router_on_available_edge(
context, router_id, router_db.admin_state_up) context, router_id, router_db.admin_state_up)
@ -693,8 +707,8 @@ class RouterSharedDriver(router_driver.RouterBaseDriver):
self._add_router_services_on_available_edge(context, self._add_router_services_on_available_edge(context,
router_id) router_id)
else: else:
info = super(nsx_v.NsxVPluginV2, self.plugin).add_router_interface( info = self._base_add_router_interface(context, router_id,
context, router_id, interface_info) interface_info)
# bind and configure routing servie on an availab edge # bind and configure routing servie on an availab edge
self._bind_router_on_available_edge( self._bind_router_on_available_edge(
context, router_id, router_db.admin_state_up) context, router_id, router_db.admin_state_up)

View File

@ -1518,6 +1518,16 @@ def clear_gateway(nsxv_manager, context, router_id):
def update_external_interface( def update_external_interface(
nsxv_manager, context, router_id, ext_net_id,
ipaddr, netmask, secondary=None):
with locking.LockManager.get_lock(
str(router_id), lock_file_prefix='nsx-edge-interface-', external=True):
_update_external_interface(nsxv_manager, context, router_id,
ext_net_id, ipaddr, netmask,
secondary=secondary)
def _update_external_interface(
nsxv_manager, context, router_id, ext_net_id, nsxv_manager, context, router_id, ext_net_id,
ipaddr, netmask, secondary=None): ipaddr, netmask, secondary=None):
secondary = secondary or [] secondary = secondary or []
@ -1538,6 +1548,15 @@ def update_external_interface(
def update_internal_interface(nsxv_manager, context, router_id, int_net_id, def update_internal_interface(nsxv_manager, context, router_id, int_net_id,
address_groups, is_connected=True): address_groups, is_connected=True):
with locking.LockManager.get_lock(
str(router_id), lock_file_prefix='nsx-edge-interface-', external=True):
_update_internal_interface(nsxv_manager, context, router_id,
int_net_id, address_groups,
is_connected=is_connected)
def _update_internal_interface(nsxv_manager, context, router_id, int_net_id,
address_groups, is_connected=True):
# Get the pg/wire id of the network id # Get the pg/wire id of the network id
mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id) mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id)
if mappings: if mappings:
@ -1566,6 +1585,15 @@ def update_internal_interface(nsxv_manager, context, router_id, int_net_id,
def add_vdr_internal_interface(nsxv_manager, context, router_id, def add_vdr_internal_interface(nsxv_manager, context, router_id,
int_net_id, address_groups, is_connected=True): int_net_id, address_groups, is_connected=True):
with locking.LockManager.get_lock(
str(router_id), lock_file_prefix='nsx-edge-interface-', external=True):
_add_vdr_internal_interface(nsxv_manager, context, router_id,
int_net_id, address_groups,
is_connected=is_connected)
def _add_vdr_internal_interface(nsxv_manager, context, router_id,
int_net_id, address_groups, is_connected=True):
# Get the pg/wire id of the network id # Get the pg/wire id of the network id
mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id) mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id)
if mappings: if mappings:
@ -1592,6 +1620,16 @@ def add_vdr_internal_interface(nsxv_manager, context, router_id,
def update_vdr_internal_interface(nsxv_manager, context, router_id, int_net_id, def update_vdr_internal_interface(nsxv_manager, context, router_id, int_net_id,
address_groups, is_connected=True): address_groups, is_connected=True):
with locking.LockManager.get_lock(
str(router_id), lock_file_prefix='nsx-edge-interface-', external=True):
_update_vdr_internal_interface(nsxv_manager, context, router_id,
int_net_id, address_groups,
is_connected=is_connected)
def _update_vdr_internal_interface(nsxv_manager, context, router_id,
int_net_id, address_groups,
is_connected=True):
# Get the pg/wire id of the network id # Get the pg/wire id of the network id
mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id) mappings = nsx_db.get_nsx_switch_ids(context.session, int_net_id)
if mappings: if mappings:
@ -1612,6 +1650,14 @@ def update_vdr_internal_interface(nsxv_manager, context, router_id, int_net_id,
def delete_interface(nsxv_manager, context, router_id, network_id, def delete_interface(nsxv_manager, context, router_id, network_id,
dist=False, is_wait=True): dist=False, is_wait=True):
with locking.LockManager.get_lock(
str(router_id), lock_file_prefix='nsx-edge-interface-', external=True):
_delete_interface(nsxv_manager, context, router_id, network_id,
dist=dist, is_wait=is_wait)
def _delete_interface(nsxv_manager, context, router_id, network_id,
dist=False, is_wait=True):
# Get the pg/wire id of the network id # Get the pg/wire id of the network id
mappings = nsx_db.get_nsx_switch_ids(context.session, network_id) mappings = nsx_db.get_nsx_switch_ids(context.session, network_id)
if mappings: if mappings: