Fix - restart VLAN interface on underlying device change

When a change is needed on bond, os-net-config write the
configuration and restart nic and bond. But it does not
restart vlan on top of the bond. The results is that  all
routes for vlan interfaces are lost.

This moves the processing of VLAN's so that it run's
after any interfaces, bridges, bonds etc. Then
concatenates the restart lists from other interfaces and
do a check if 'PHYSDEV' of a VLAN interface is being
restarted.

Closes-Bug: #1806128
Related: RHBZ#1654987
Change-Id: I246da54cf02d06466f52d210f89d82ca9e2a6ef2
This commit is contained in:
Harald Jensås 2018-11-30 10:54:06 +01:00
parent 122684cf30
commit 19067b4e77
2 changed files with 66 additions and 28 deletions

View File

@ -15,6 +15,7 @@
# under the License.
import glob
import itertools
import logging
import netaddr
import os
@ -1124,34 +1125,6 @@ class IfcfgNetConfig(os_net_config.NetConfig):
if iface_name not in restart_interfaces:
apply_routes.append((iface_name, route6_data))
for vlan_name, vlan_data in self.vlan_data.items():
route_data = self.route_data.get(vlan_name, '')
route6_data = self.route6_data.get(vlan_name, '')
vlan_path = self.root_dir + ifcfg_config_path(vlan_name)
vlan_route_path = self.root_dir + route_config_path(vlan_name)
vlan_route6_path = self.root_dir + route6_config_path(vlan_name)
all_file_names.append(vlan_path)
all_file_names.append(vlan_route_path)
all_file_names.append(vlan_route6_path)
if utils.diff(vlan_path, vlan_data):
if self.ifcfg_requires_restart(vlan_path, vlan_data):
restart_vlans.append(vlan_name)
else:
apply_interfaces.append(
(vlan_name, vlan_path, vlan_data))
update_files[vlan_path] = vlan_data
else:
logger.info('No changes required for vlan interface: %s' %
vlan_name)
if utils.diff(vlan_route_path, route_data):
update_files[vlan_route_path] = route_data
if vlan_name not in restart_vlans:
apply_routes.append((vlan_name, route_data))
if utils.diff(vlan_route6_path, route6_data):
update_files[vlan_route6_path] = route6_data
if vlan_name not in restart_vlans:
apply_routes.append((vlan_name, route6_data))
for bridge_name, bridge_data in self.bridge_data.items():
route_data = self.route_data.get(bridge_name, '')
route6_data = self.route6_data.get(bridge_name, '')
@ -1314,6 +1287,45 @@ class IfcfgNetConfig(os_net_config.NetConfig):
if interface_name not in restart_interfaces:
apply_routes.append((interface_name, route6_data))
# NOTE(hjensas): Process the VLAN's last so that we know if the vlan's
# parent interface is being restarted.
for vlan_name, vlan_data in self.vlan_data.items():
route_data = self.route_data.get(vlan_name, '')
route6_data = self.route6_data.get(vlan_name, '')
vlan_path = self.root_dir + ifcfg_config_path(vlan_name)
vlan_route_path = self.root_dir + route_config_path(vlan_name)
vlan_route6_path = self.root_dir + route6_config_path(vlan_name)
all_file_names.append(vlan_path)
all_file_names.append(vlan_route_path)
all_file_names.append(vlan_route6_path)
restarts_concatenated = itertools.chain(restart_interfaces,
restart_bridges,
restart_linux_bonds,
restart_linux_teams)
if (self.parse_ifcfg(vlan_data).get('PHYSDEV') in
restarts_concatenated):
if vlan_name not in restart_vlans:
restart_vlans.append(vlan_name)
update_files[vlan_path] = vlan_data
elif utils.diff(vlan_path, vlan_data):
if self.ifcfg_requires_restart(vlan_path, vlan_data):
restart_vlans.append(vlan_name)
else:
apply_interfaces.append(
(vlan_name, vlan_path, vlan_data))
update_files[vlan_path] = vlan_data
else:
logger.info('No changes required for vlan interface: %s' %
vlan_name)
if utils.diff(vlan_route_path, route_data):
update_files[vlan_route_path] = route_data
if vlan_name not in restart_vlans:
apply_routes.append((vlan_name, route_data))
if utils.diff(vlan_route6_path, route6_data):
update_files[vlan_route6_path] = route6_data
if vlan_name not in restart_vlans:
apply_routes.append((vlan_name, route6_data))
if self.vpp_interface_data or self.vpp_bond_data:
vpp_path = self.root_dir + vpp_config_path()
vpp_config = utils.generate_vpp_config(vpp_path, vpp_interfaces,

View File

@ -1976,6 +1976,32 @@ class TestIfcfgNetConfigApply(base.TestCase):
self.assertIn('em1', self.ifup_interface_names)
self.assertIn('em2', self.ifup_interface_names)
def test_restart_vlans_on_bond_change(self):
self.ifup_interface_names = []
interface1 = objects.Interface('em1')
interface2 = objects.Interface('em2')
bond = objects.LinuxBond('bond0', members=[interface1, interface2])
vlan = objects.Vlan('bond0', 10)
self.provider.add_interface(interface1)
self.provider.add_interface(interface2)
self.provider.add_linux_bond(bond)
self.provider.add_vlan(vlan)
self.provider.apply()
self.assertIn('bond0', self.ifup_interface_names)
self.assertIn('em1', self.ifup_interface_names)
self.assertIn('em2', self.ifup_interface_names)
self.assertIn('vlan10', self.ifup_interface_names)
# Change the bond configuration
self.ifup_interface_names = []
bond.bonding_options = 'mode=1 miimon=100'
self.provider.add_linux_bond(bond)
self.provider.apply()
self.assertIn('bond0', self.ifup_interface_names)
self.assertIn('em1', self.ifup_interface_names)
self.assertIn('em2', self.ifup_interface_names)
self.assertIn('vlan10', self.ifup_interface_names)
def test_restart_interface_counts(self):
interface = objects.Interface('em1')
self.provider.add_interface(interface)