From e1d0599a61ca55e0267a4816d50b0adb7a3d8066 Mon Sep 17 00:00:00 2001 From: Moshe Levi Date: Thu, 29 Jun 2017 12:26:07 +0300 Subject: [PATCH] unplug_vf_passthrough: don't try to delete representor netdev The representor is bound to the SR-IOV VF therefore it can't be removed. Adding a flag in the delete_ovs_vif_port that allows to skip deleting the netdev interface. Closes-Bug: #1700726 Change-Id: I918c10eae5531872091661600875d76d44b68dad --- vif_plug_ovs/linux_net.py | 5 +++-- vif_plug_ovs/ovs.py | 6 +++++- vif_plug_ovs/tests/unit/test_linux_net.py | 24 +++++++++++++++++++++++ vif_plug_ovs/tests/unit/test_plugin.py | 3 ++- 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py index daef00b2..3055b334 100644 --- a/vif_plug_ovs/linux_net.py +++ b/vif_plug_ovs/linux_net.py @@ -88,10 +88,11 @@ def update_ovs_vif_port(dev, mtu=None, interface_type=None, timeout=None): @privsep.vif_plug.entrypoint -def delete_ovs_vif_port(bridge, dev, timeout=None): +def delete_ovs_vif_port(bridge, dev, timeout=None, delete_netdev=True): _ovs_vsctl(['--', '--if-exists', 'del-port', bridge, dev], timeout=timeout) - _delete_net_dev(dev) + if delete_netdev: + _delete_net_dev(dev) def device_exists(device): diff --git a/vif_plug_ovs/ovs.py b/vif_plug_ovs/ovs.py index 62e52611..6ec73335 100644 --- a/vif_plug_ovs/ovs.py +++ b/vif_plug_ovs/ovs.py @@ -224,7 +224,11 @@ class OvsPlugin(plugin.PluginBase): pf_interface=True) vf_num = linux_net.get_vf_num_by_pci_address(pci_slot) representor = linux_net.get_representor_port(pf_ifname, vf_num) - linux_net.delete_ovs_vif_port(vif.network.bridge, representor) + # The representor interface can't be deleted because it bind the + # SR-IOV VF, therefore we just need to remove it from the ovs bridge + # and set the status to down + linux_net.delete_ovs_vif_port( + vif.network.bridge, representor, delete_netdev=False) linux_net.set_interface_state(representor, 'down') def unplug(self, vif, instance_info): diff --git a/vif_plug_ovs/tests/unit/test_linux_net.py b/vif_plug_ovs/tests/unit/test_linux_net.py index f5ba75de..cfdacac8 100644 --- a/vif_plug_ovs/tests/unit/test_linux_net.py +++ b/vif_plug_ovs/tests/unit/test_linux_net.py @@ -274,6 +274,30 @@ class LinuxNetTest(testtools.TestCase): 'mtu_request=%s' % mtu] mock_vsctl.assert_called_with(args, timeout=timeout) + @mock.patch.object(linux_net, '_delete_net_dev') + @mock.patch.object(linux_net, '_ovs_vsctl') + def test_delete_ovs_vif_port_delete_netdev( + self, mock_vsctl, mock_delete_net_dev): + bridge = 'fake-bridge' + dev = 'fake-dev' + timeout = 120 + linux_net.delete_ovs_vif_port(bridge, dev, timeout=timeout) + args = ['--', '--if-exists', 'del-port', bridge, dev] + mock_vsctl.assert_called_with(args, timeout=timeout) + mock_delete_net_dev.assert_called() + + @mock.patch.object(linux_net, '_delete_net_dev') + @mock.patch.object(linux_net, '_ovs_vsctl') + def test_delete_ovs_vif_port(self, mock_vsctl, mock_delete_net_dev): + bridge = 'fake-bridge' + dev = 'fake-dev' + timeout = 120 + linux_net.delete_ovs_vif_port( + bridge, dev, timeout=timeout, delete_netdev=False) + args = ['--', '--if-exists', 'del-port', bridge, dev] + mock_vsctl.assert_called_with(args, timeout=timeout) + mock_delete_net_dev.assert_not_called() + @mock.patch.object(linux_net, '_ovs_vsctl') def test_ovs_supports_mtu_requests(self, mock_vsctl): args = ['--columns=mtu_request', 'list', 'interface'] diff --git a/vif_plug_ovs/tests/unit/test_plugin.py b/vif_plug_ovs/tests/unit/test_plugin.py index eb0a0c44..f87a8e02 100644 --- a/vif_plug_ovs/tests/unit/test_plugin.py +++ b/vif_plug_ovs/tests/unit/test_plugin.py @@ -383,7 +383,8 @@ class PluginTest(testtools.TestCase): 'get_vf_num_by_pci_address': [mock.call('0002:24:12.3')], 'get_representor_port': [mock.call('eth0', '2')], 'set_interface_state': [mock.call('eth0_2', 'down')], - 'delete_ovs_vif_port': [mock.call('br0', 'eth0_2')] + 'delete_ovs_vif_port': [mock.call('br0', 'eth0_2', + delete_netdev=False)] } get_ifname_by_pci_address.return_value = 'eth0'