Merge ~fnordahl/ubuntu/+source/python-os-vif:bug/1892132-ussuri into ~ubuntu-openstack-dev/ubuntu/+source/python-os-vif:stable/ussuri

Proposed by Frode Nordahl
Status: Merged
Merged at revision: 0119aebdc0949b9f3a74f78f1c275d1f51ee59c7
Proposed branch: ~fnordahl/ubuntu/+source/python-os-vif:bug/1892132-ussuri
Merge into: ~ubuntu-openstack-dev/ubuntu/+source/python-os-vif:stable/ussuri
Diff against target: 696 lines (+670/-0)
4 files modified
debian/changelog (+9/-0)
debian/patches/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch (+168/-0)
debian/patches/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch (+491/-0)
debian/patches/series (+2/-0)
Reviewer Review Type Date Requested Status
Corey Bryant Pending
Chris MacNaughton Pending
Ubuntu OpenStack uploaders Pending
Review via email: mp+405805@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index e2673a2..b62c1c2 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
1python-os-vif (2.0.0-0ubuntu1.2) UNRELEASED; urgency=medium
2
3 * Add support for switchdev NICs that link representor ports to parent PCI
4 device. (LP: #1892132)
5 - d/p/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
6 - d/p/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch
7
8 -- Frode Nordahl <frode.nordahl@canonical.com> Fri, 16 Jul 2021 09:43:06 +0000
9
1python-os-vif (2.0.0-0ubuntu1.1) UNRELEASED; urgency=medium10python-os-vif (2.0.0-0ubuntu1.1) UNRELEASED; urgency=medium
211
3 [ Corey Bryant ]12 [ Corey Bryant ]
diff --git a/debian/patches/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch b/debian/patches/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch
4new file mode 10064413new file mode 100644
index 0000000..bb82b13
--- /dev/null
+++ b/debian/patches/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch
@@ -0,0 +1,168 @@
1From ssh://review.opendev.org:29418/openstack/os-vif
2 * branch refs/changes/67/765967/5 -> FETCH_HEAD
3From 1226d46cc8bde9531821c68465a05292528142f0 Mon Sep 17 00:00:00 2001
4From: Mamduh Alassi <mamduhala@mellanox.com>
5Date: Wed, 12 Aug 2020 16:24:47 +0300
6Subject: [PATCH] Fix - os-vif fails to get the correct UpLink Representor
7
8Till kernel 5.7 PF and VF representors are exposed as virtual device.
9They are not linked to its parent PCI device like how uplink
10representor is linked.
11
12Starting from kernel 5.8 due to new change [1] the PF and VF representors are
13linked to their parent PCI device, and so "get_ifname_by_pci_address" fails
14to get the correct UpLink Representor.
15
16This patch modifys the behviour of "get_ifname_by_pci_address" to
17check the physical port name of the netdev in
18vf_pci_addr_path/physfn/net to match the formart for the uplink "p\d+".
19
20[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=123f0f53dd64b67e34142485fe866a8a581f12f1
21
22Closes-Bug: #1892132
23Change-Id: I49f6ae3f0e6bfbf555c8284bfd70371ce90da0c7
24(cherry picked from commit a28aafa796378b8a36ccb51d2c0010a44f622d14)
25---
26 .../notes/bug-1892132-812e6d5ce0588ebb.yaml | 10 +++++
27 vif_plug_ovs/linux_net.py | 28 +++++++++---
28 vif_plug_ovs/tests/unit/test_linux_net.py | 44 +++++++++++++++++--
29 3 files changed, 74 insertions(+), 8 deletions(-)
30 create mode 100644 releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
31
32diff --git a/releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml b/releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
33new file mode 100644
34index 0000000..f7604dd
35--- /dev/null
36+++ b/releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
37@@ -0,0 +1,10 @@
38+---
39+fixes:
40+ - |
41+ Linux kernel 5.8 changed the sysfs interface that is used to
42+ discover the interfaces used for OVS offloads for certain NIC
43+ models. This results in network plugging failure, as described
44+ in `bug #1892132`_. This release fixes the plugging issue by
45+ properly handling the new sysfs structure.
46+
47+ .. _bug #1892132: https://bugs.launchpad.net/os-vif/+bug/1892132
48diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py
49index 3e77585..f7b120c 100644
50--- a/vif_plug_ovs/linux_net.py
51+++ b/vif_plug_ovs/linux_net.py
52@@ -45,6 +45,8 @@ VF_RE = re.compile(r"vf(\d+)", re.IGNORECASE)
53 PF_RE = re.compile(r"pf(\d+)", re.IGNORECASE)
54 # bus_info (bdf) contains <bus>:<dev>.<func>
55 PF_FUNC_RE = re.compile(r"\.(\d+)", 0)
56+# phys_port_name contains p##
57+UPLINK_PORT_RE = re.compile(r"p(\d+)", re.IGNORECASE)
58
59 _SRIOV_TOTALVFS = "sriov_totalvfs"
60 NIC_NAME_LEN = 14
61@@ -327,12 +329,28 @@ def get_ifname_by_pci_address(pci_addr, pf_interface=False, switchdev=False):
62 itself based on the argument of pf_interface.
63 """
64 dev_path = _get_sysfs_netdev_path(pci_addr, pf_interface)
65- # make the if statement later more readable
66- ignore_switchdev = not switchdev
67 try:
68- for netdev in os.listdir(dev_path):
69- if ignore_switchdev or _is_switchdev(netdev):
70- return netdev
71+ devices = os.listdir(dev_path)
72+
73+ # Return the first netdev in case of switchdev=False
74+ if not switchdev:
75+ return devices[0]
76+ elif pf_interface:
77+ fallback_netdev = None
78+ for netdev in devices:
79+ # Return the uplink representor in case of switchdev=True
80+ if _is_switchdev(netdev):
81+ fallback_netdev = netdev if fallback_netdev is None \
82+ else fallback_netdev
83+ phys_port_name = _get_phys_port_name(netdev)
84+ if phys_port_name is not None and \
85+ UPLINK_PORT_RE.search(phys_port_name):
86+ return netdev
87+
88+ # Fallback to first switchdev netdev in case of switchdev=True
89+ if fallback_netdev is not None:
90+ return fallback_netdev
91+
92 except Exception:
93 raise exception.PciDeviceNotFoundById(id=pci_addr)
94 raise exception.PciDeviceNotFoundById(id=pci_addr)
95diff --git a/vif_plug_ovs/tests/unit/test_linux_net.py b/vif_plug_ovs/tests/unit/test_linux_net.py
96index a5404ea..e19ce94 100644
97--- a/vif_plug_ovs/tests/unit/test_linux_net.py
98+++ b/vif_plug_ovs/tests/unit/test_linux_net.py
99@@ -260,26 +260,64 @@ class LinuxNetTest(testtools.TestCase):
100
101 @mock.patch.object(os, 'listdir')
102 @mock.patch.object(linux_net, '_get_phys_switch_id')
103+ @mock.patch.object(linux_net, "_get_phys_port_name")
104 def test_physical_function_interface_name(
105- self, mock__get_phys_switch_id, mock_listdir):
106+ self, mock__get_phys_port_name, mock__get_phys_switch_id,
107+ mock_listdir):
108 mock_listdir.return_value = ['foo', 'bar']
109 mock__get_phys_switch_id.side_effect = (
110 ['', 'valid_switch'])
111+ mock__get_phys_port_name.side_effect = (["p1"])
112 ifname = linux_net.get_ifname_by_pci_address(
113 '0000:00:00.1', pf_interface=True, switchdev=False)
114 self.assertEqual(ifname, 'foo')
115
116 @mock.patch.object(os, 'listdir')
117- @mock.patch.object(linux_net, '_get_phys_switch_id')
118+ @mock.patch.object(linux_net, "_get_phys_switch_id")
119+ @mock.patch.object(linux_net, "_get_phys_port_name")
120 def test_physical_function_interface_name_with_switchdev(
121- self, mock__get_phys_switch_id, mock_listdir):
122+ self, mock__get_phys_port_name, mock__get_phys_switch_id,
123+ mock_listdir):
124 mock_listdir.return_value = ['foo', 'bar']
125 mock__get_phys_switch_id.side_effect = (
126 ['', 'valid_switch'])
127+ mock__get_phys_port_name.side_effect = (["p1s0"])
128 ifname = linux_net.get_ifname_by_pci_address(
129 '0000:00:00.1', pf_interface=True, switchdev=True)
130 self.assertEqual(ifname, 'bar')
131
132+ @mock.patch.object(os, 'listdir')
133+ @mock.patch.object(linux_net, "_get_phys_switch_id")
134+ @mock.patch.object(linux_net, "_get_phys_port_name")
135+ def test_physical_function_interface_name_with_representors(
136+ self, mock__get_phys_port_name, mock__get_phys_switch_id,
137+ mock_listdir):
138+ # Get the PF that matches the phys_port_name regex
139+ mock_listdir.return_value = ['enp2s0f0_0', 'enp2s0f0_1', 'enp2s0f0']
140+ mock__get_phys_switch_id.side_effect = (
141+ ['valid_switch', 'valid_switch', 'valid_switch'])
142+ mock__get_phys_port_name.side_effect = (["pf0vf0", "pf0vf1", "p0"])
143+ ifname = linux_net.get_ifname_by_pci_address(
144+ '0000:00:00.1', pf_interface=True, switchdev=True)
145+ self.assertEqual(ifname, 'enp2s0f0')
146+
147+ @mock.patch.object(os, 'listdir')
148+ @mock.patch.object(linux_net, "_get_phys_switch_id")
149+ @mock.patch.object(linux_net, "_get_phys_port_name")
150+ def test_physical_function_interface_name_with_fallback_To_first_netdev(
151+ self, mock__get_phys_port_name, mock__get_phys_switch_id,
152+ mock_listdir):
153+ # Try with switchdev mode to get PF but fail because there is no match
154+ # for the phys_port_name then fallback to first interface found
155+ mock_listdir.return_value = ['enp2s0f0_0', 'enp2s0f0_1', 'enp2s0f0']
156+ mock__get_phys_switch_id.side_effect = (['valid_switch',
157+ 'valid_switch',
158+ 'valid_switch'])
159+ mock__get_phys_port_name.side_effect = (["pf0vf0", "pf0vf1", "pf0vf2"])
160+ ifname = linux_net.get_ifname_by_pci_address(
161+ '0000:00:00.1', pf_interface=True, switchdev=True)
162+ self.assertEqual(ifname, 'enp2s0f0_0')
163+
164 @mock.patch.object(os, 'listdir')
165 def test_get_ifname_by_pci_address_exception(self, mock_listdir):
166 mock_listdir.side_effect = OSError('No such file or directory')
167--
1682.31.1
diff --git a/debian/patches/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch b/debian/patches/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
0new file mode 100644169new file mode 100644
index 0000000..e895a24
--- /dev/null
+++ b/debian/patches/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
@@ -0,0 +1,491 @@
1From ssh://review.opendev.org:29418/openstack/os-vif
2 * branch refs/changes/19/765419/6 -> FETCH_HEAD
3From 3e1d898b752c327165aeca1fec0919d858a87ec4 Mon Sep 17 00:00:00 2001
4From: Mamduh <mamduhala@nvidia.com>
5Date: Tue, 18 Aug 2020 12:40:10 +0300
6Subject: [PATCH] Refactor code of linux_net to more cleaner and increase
7 performace
8
9The patch adds new functions '_get_phys_port_name' for reading physical
10port name of the SR-IOV port and '_get_phys_switch_id' for reading
11physical port switch ID of the SR-IOV port, in addition to refactoring
12'get_representor_port' to use the new functions and decrease calls for
13"_get_pf_func" and netdevs associated with the PF will now be processed
14in the loop, however it will not be matching 'phys_port_name' which
15ensures the correct behaviour.
16
17In addition to updating the unit test for linux_net and remove not
18needed mocks
19
20Conflicts:
21 vif_plug_ovs/linux_net.py
22 vif_plug_ovs/tests/unit/test_linux_net.py
23
24Related-Bug: #1892132
25Change-Id: I3fdbea4f48cb79ebfd03a4da21e2232ccafb7a76
26(cherry picked from commit 167bb030f1143f37ce189673d831bd572f64d4ad)
27---
28 vif_plug_ovs/linux_net.py | 77 ++++---
29 vif_plug_ovs/tests/unit/test_linux_net.py | 250 ++++++++--------------
30 2 files changed, 139 insertions(+), 188 deletions(-)
31
32diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py
33index 20baab3..3e77585 100644
34--- a/vif_plug_ovs/linux_net.py
35+++ b/vif_plug_ovs/linux_net.py
36@@ -239,46 +239,35 @@ def get_representor_port(pf_ifname, vf_num):
37 VF number in the phys_port_name. That interface is the representor for
38 the requested VF.
39 """
40- pf_path = "/sys/class/net/%s" % pf_ifname
41- pf_sw_id_file = os.path.join(pf_path, "phys_switch_id")
42
43 pf_sw_id = None
44 try:
45- with open(pf_sw_id_file, 'r') as fd:
46- pf_sw_id = fd.readline().rstrip()
47+ pf_sw_id = _get_phys_switch_id(pf_ifname)
48 except (OSError, IOError):
49 raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
50
51- pf_subsystem_file = os.path.join(pf_path, "subsystem")
52+ pf_subsystem_file = "/sys/class/net/%s/subsystem" % pf_ifname
53 try:
54 devices = os.listdir(pf_subsystem_file)
55 except (OSError, IOError):
56 raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
57
58- for device in devices:
59- address_str, pf = get_function_by_ifname(device)
60- if pf:
61- continue
62+ ifname_pf_func = _get_pf_func(pf_ifname)
63+ if ifname_pf_func is None:
64+ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
65
66- device_path = "/sys/class/net/%s" % device
67- device_sw_id_file = os.path.join(device_path, "phys_switch_id")
68+ for device in devices:
69 try:
70- with open(device_sw_id_file, 'r') as fd:
71- device_sw_id = fd.readline().rstrip()
72+ device_sw_id = _get_phys_switch_id(device)
73+ if not device_sw_id or device_sw_id != pf_sw_id:
74+ continue
75 except (OSError, IOError):
76 continue
77
78- if device_sw_id != pf_sw_id:
79- continue
80- device_port_name_file = (
81- os.path.join(device_path, 'phys_port_name'))
82-
83- if not os.path.isfile(device_port_name_file):
84- continue
85-
86 try:
87- with open(device_port_name_file, 'r') as fd:
88- phys_port_name = fd.readline().rstrip()
89+ phys_port_name = _get_phys_port_name(device)
90+ if phys_port_name is None:
91+ continue
92 except (OSError, IOError):
93 continue
94
95@@ -287,12 +276,8 @@ def get_representor_port(pf_ifname, vf_num):
96 # the PCI func number of pf_ifname.
97 rep_parent_pf_func = _parse_pf_number(phys_port_name)
98 if rep_parent_pf_func is not None:
99- ifname_pf_func = _get_pf_func(pf_ifname)
100- if ifname_pf_func is None:
101- continue
102- if int(rep_parent_pf_func) != int(ifname_pf_func):
103- continue
104-
105+ if int(rep_parent_pf_func) != int(ifname_pf_func):
106+ continue
107 representor_num = _parse_vf_number(phys_port_name)
108 # Note: representor_num can be 0, referring to VF0
109 if representor_num is None:
110@@ -321,9 +306,7 @@ def _get_sysfs_netdev_path(pci_addr, pf_interface):
111 def _is_switchdev(netdev):
112 """Returns True if a netdev has a readable phys_switch_id"""
113 try:
114- sw_id_file = "/sys/class/net/%s/phys_switch_id" % netdev
115- with open(sw_id_file, 'r') as fd:
116- phys_switch_id = fd.readline().rstrip()
117+ phys_switch_id = _get_phys_switch_id(netdev)
118 if phys_switch_id != "" and phys_switch_id is not None:
119 return True
120 except (OSError, IOError):
121@@ -389,3 +372,33 @@ def get_pf_pci_from_vf(vf_pci):
122 """
123 physfn_path = os.readlink("/sys/bus/pci/devices/%s/physfn" % vf_pci)
124 return os.path.basename(physfn_path)
125+
126+
127+def _get_phys_port_name(ifname):
128+ """Get the interface name and return its phys_port_name
129+
130+ :param ifname: The interface name
131+ :return: The phys_port_name of the given ifname
132+ """
133+ phys_port_name_path = "/sys/class/net/%s/phys_port_name" % ifname
134+
135+ if not os.path.isfile(phys_port_name_path):
136+ return None
137+
138+ with open(phys_port_name_path, 'r') as fd:
139+ return fd.readline().strip()
140+
141+
142+def _get_phys_switch_id(ifname):
143+ """Get the interface name and return its phys_switch_id
144+
145+ :param ifname: The interface name
146+ :return: The phys_switch_id of the given ifname
147+ """
148+ phys_port_name_path = "/sys/class/net/%s/phys_switch_id" % ifname
149+
150+ if not os.path.isfile(phys_port_name_path):
151+ return None
152+
153+ with open(phys_port_name_path, 'r') as fd:
154+ return fd.readline().strip()
155diff --git a/vif_plug_ovs/tests/unit/test_linux_net.py b/vif_plug_ovs/tests/unit/test_linux_net.py
156index 4eaa1f7..a5404ea 100644
157--- a/vif_plug_ovs/tests/unit/test_linux_net.py
158+++ b/vif_plug_ovs/tests/unit/test_linux_net.py
159@@ -132,47 +132,22 @@ class LinuxNetTest(testtools.TestCase):
160 linux_net.add_bridge_port("br0", "vnet1")
161 mock_set.assert_called_once_with("vnet1", master="br0")
162
163- @mock.patch('six.moves.builtins.open')
164- @mock.patch.object(os.path, 'isfile')
165- def test_is_switchdev_ioerror(self, mock_isfile, mock_open):
166- mock_isfile.side_effect = [True]
167- mock_open.return_value.__enter__ = lambda s: s
168- readline_mock = mock_open.return_value.readline
169- readline_mock.side_effect = (
170- [IOError()])
171+ @mock.patch.object(linux_net, '_get_phys_switch_id')
172+ def test_is_switchdev_ioerror(self, mock__get_phys_switch_id):
173+ mock__get_phys_switch_id.side_effect = ([IOError()])
174 test_switchdev = linux_net._is_switchdev('pf_ifname')
175 self.assertEqual(test_switchdev, False)
176
177- @mock.patch('six.moves.builtins.open')
178- @mock.patch.object(os.path, 'isfile')
179- def test_is_switchdev_empty(self, mock_isfile, mock_open):
180- mock_isfile.side_effect = [True]
181- mock_open.return_value.__enter__ = lambda s: s
182- readline_mock = mock_open.return_value.readline
183- readline_mock.side_effect = (
184- [''])
185- open_calls = (
186- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
187- mock.call().readline(),
188- mock.call().__exit__(None, None, None)])
189+ @mock.patch.object(linux_net, '_get_phys_switch_id')
190+ def test_is_switchdev_empty(self, mock__get_phys_switch_id):
191+ mock__get_phys_switch_id.return_value = ''
192 test_switchdev = linux_net._is_switchdev('pf_ifname')
193- mock_open.assert_has_calls(open_calls)
194 self.assertEqual(test_switchdev, False)
195
196- @mock.patch('six.moves.builtins.open')
197- @mock.patch.object(os.path, 'isfile')
198- def test_is_switchdev_positive(self, mock_isfile, mock_open):
199- mock_isfile.side_effect = [True]
200- mock_open.return_value.__enter__ = lambda s: s
201- readline_mock = mock_open.return_value.readline
202- readline_mock.side_effect = (
203- ['pf_sw_id'])
204- open_calls = (
205- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
206- mock.call().readline(),
207- mock.call().__exit__(None, None, None)])
208+ @mock.patch.object(linux_net, '_get_phys_switch_id')
209+ def test_is_switchdev_positive(self, mock__get_phys_switch_id):
210+ mock__get_phys_switch_id.return_value = 'pf_sw_id'
211 test_switchdev = linux_net._is_switchdev('pf_ifname')
212- mock_open.assert_has_calls(open_calls)
213 self.assertEqual(test_switchdev, True)
214
215 def test_parse_vf_number(self):
216@@ -191,184 +166,115 @@ class LinuxNetTest(testtools.TestCase):
217 self.assertEqual(linux_net._parse_pf_number("pf31"), "31")
218 self.assertIsNone(linux_net._parse_pf_number("g4rbl3d"))
219
220- @mock.patch('six.moves.builtins.open')
221- @mock.patch.object(os.path, 'isfile')
222 @mock.patch.object(os, 'listdir')
223- @mock.patch.object(linux_net, "get_function_by_ifname")
224- def test_get_representor_port(self, mock_get_function_by_ifname,
225- mock_listdir, mock_isfile, mock_open):
226+ @mock.patch.object(linux_net, "_get_pf_func")
227+ @mock.patch.object(linux_net, "_get_phys_port_name")
228+ @mock.patch.object(linux_net, '_get_phys_switch_id')
229+ def test_get_representor_port(self, mock__get_phys_switch_id,
230+ mock__get_phys_port_name,
231+ mock__get_pf_func,
232+ mock_listdir):
233 mock_listdir.return_value = [
234 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
235 ]
236- mock_isfile.side_effect = [True, True]
237- mock_open.return_value.__enter__ = lambda s: s
238- readline_mock = mock_open.return_value.readline
239- readline_mock.side_effect = (
240- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', 'pf0vf2'])
241- # PCI IDs mocked:
242- # PF0: 0000:0a:00.0
243- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
244- mock_get_function_by_ifname.side_effect = (
245- [("0000:0a:00.0", True),
246- ("0000:0a:02.1", False),
247- ("0000:0a:02.2", False), ("0000:0a:00.0", True)])
248- open_calls = (
249- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
250- mock.call().readline(),
251- mock.call().__exit__(None, None, None),
252- mock.call('/sys/class/net/rep_vf_1/phys_switch_id', 'r'),
253- mock.call().readline(),
254- mock.call().__exit__(None, None, None),
255- mock.call('/sys/class/net/rep_vf_1/phys_port_name', 'r'),
256- mock.call().readline(),
257- mock.call().__exit__(None, None, None),
258- mock.call('/sys/class/net/rep_vf_2/phys_switch_id', 'r'),
259- mock.call().readline(),
260- mock.call().__exit__(None, None, None),
261- mock.call('/sys/class/net/rep_vf_2/phys_port_name', 'r'),
262- mock.call().readline(),
263- mock.call().__exit__(None, None, None)])
264+ mock__get_phys_switch_id.return_value = 'pf_sw_id'
265+ mock__get_pf_func.return_value = "0"
266+ mock__get_phys_port_name.side_effect = (['1', "pf0vf1", "pf0vf2"])
267 ifname = linux_net.get_representor_port('pf_ifname', '2')
268- mock_open.assert_has_calls(open_calls)
269 self.assertEqual('rep_vf_2', ifname)
270
271- @mock.patch('six.moves.builtins.open')
272- @mock.patch.object(os.path, 'isfile')
273 @mock.patch.object(os, 'listdir')
274- @mock.patch.object(linux_net, "get_function_by_ifname")
275+ @mock.patch.object(linux_net, "_get_pf_func")
276+ @mock.patch.object(linux_net, "_get_phys_port_name")
277+ @mock.patch.object(linux_net, "_get_phys_switch_id")
278 def test_get_representor_port_2_pfs(
279- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
280- mock_open):
281+ self, mock__get_phys_switch_id, mock__get_phys_port_name,
282+ mock__get_pf_func, mock_listdir):
283 mock_listdir.return_value = [
284 'pf_ifname1', 'pf_ifname2', 'rep_pf1_vf_1', 'rep_pf1_vf_2',
285 'rep_pf2_vf_1', 'rep_pf2_vf_2',
286 ]
287- mock_isfile.side_effect = [True, True, True, True]
288- mock_open.return_value.__enter__ = lambda s: s
289- readline_mock = mock_open.return_value.readline
290- readline_mock.side_effect = (
291- ['pf_sw_id',
292- 'pf_sw_id', 'VF1@PF1', 'pf_sw_id', 'vf2@pf1',
293- 'pf_sw_id', 'pf2vf1', 'pf_sw_id', 'pf2vf2'])
294- # PCI IDs mocked:
295- # PF1: 0000:0a:00.1 PF2: 0000:0a:00.2
296- # PF1VF1: 0000:0a:02.1 PF1VF2: 0000:0a:02.2
297- # PF2VF1: 0000:0a:04.1 PF2VF2: 0000:0a:04.2
298- mock_get_function_by_ifname.side_effect = (
299- [("0000:0a:00.1", True), ("0000:0a:00.2", True),
300- ("0000:0a:02.1", False), ("0000:0a:00.2", True),
301- ("0000:0a:02.2", False), ("0000:0a:00.2", True),
302- ("0000:0a:04.1", False), ("0000:0a:00.2", True),
303- ("0000:0a:04.2", False), ("0000:0a:00.2", True)])
304+ mock__get_phys_switch_id.return_value = 'pf_sw_id'
305+ mock__get_pf_func.return_value = "2"
306+ mock__get_phys_port_name.side_effect = (
307+ ["p1", "p2", "VF1@PF1", "pf2vf1", "vf2@pf1", "pf2vf2"])
308 ifname = linux_net.get_representor_port('pf_ifname2', '2')
309 self.assertEqual('rep_pf2_vf_2', ifname)
310
311- @mock.patch('six.moves.builtins.open')
312- @mock.patch.object(os.path, 'isfile')
313 @mock.patch.object(os, 'listdir')
314- @mock.patch.object(linux_net, "get_function_by_ifname")
315+ @mock.patch.object(linux_net, "_get_pf_func")
316+ @mock.patch.object(linux_net, "_get_phys_switch_id")
317+ @mock.patch.object(linux_net, "_get_phys_port_name")
318 def test_get_representor_port_not_found(
319- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
320- mock_open):
321+ self, mock__get_phys_port_name, mock__get_phys_switch_id,
322+ mock__get_pf_func, mock_listdir):
323 mock_listdir.return_value = [
324 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
325 ]
326- mock_isfile.side_effect = [True, True]
327- mock_open.return_value.__enter__ = lambda s: s
328- readline_mock = mock_open.return_value.readline
329- readline_mock.side_effect = (
330- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', '2'])
331- # PCI IDs mocked:
332- # PF0: 0000:0a:00.0
333- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
334- mock_get_function_by_ifname.side_effect = (
335- [("0000:0a:00.0", True),
336- ("0000:0a:02.1", False),
337- ("0000:0a:02.2", False)])
338+ mock__get_phys_switch_id.return_value = 'pf_sw_id'
339+ mock__get_pf_func.return_value = "0"
340+ mock__get_phys_port_name.side_effect = (
341+ ["p0", "1", "2"])
342 self.assertRaises(
343 exception.RepresentorNotFound,
344 linux_net.get_representor_port,
345 'pf_ifname', '3'),
346
347- @mock.patch('six.moves.builtins.open')
348- @mock.patch.object(os.path, 'isfile')
349 @mock.patch.object(os, 'listdir')
350- @mock.patch.object(linux_net, "get_function_by_ifname")
351+ @mock.patch.object(linux_net, "_get_pf_func")
352+ @mock.patch.object(linux_net, "_get_phys_port_name")
353+ @mock.patch.object(linux_net, "_get_phys_switch_id")
354 def test_get_representor_port_exception_io_error(
355- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
356- mock_open):
357+ self, mock__get_phys_switch_id, mock__get_phys_port_name,
358+ mock__get_pf_func, mock_listdir):
359 mock_listdir.return_value = [
360 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
361 ]
362- mock_isfile.side_effect = [True, True]
363- mock_open.return_value.__enter__ = lambda s: s
364- readline_mock = mock_open.return_value.readline
365- readline_mock.side_effect = (
366+ mock__get_phys_switch_id.side_effect = (
367 ['pf_sw_id', 'pf_sw_id', IOError(), 'pf_sw_id', '2'])
368- # PCI IDs mocked:
369- # PF0: 0000:0a:00.0
370- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
371- mock_get_function_by_ifname.side_effect = (
372- [("0000:0a:00.0", True),
373- ("0000:0a:02.1", False),
374- ("0000:0a:02.2", False), ("0000:0a:00.0", True)])
375+ mock__get_pf_func.return_value = "0"
376+ mock__get_phys_port_name.side_effect = (
377+ ["p0", "pf0vf0", "pf0vf1"])
378 self.assertRaises(
379 exception.RepresentorNotFound,
380 linux_net.get_representor_port,
381 'pf_ifname', '3')
382
383- @mock.patch('six.moves.builtins.open')
384- @mock.patch.object(os.path, 'isfile')
385 @mock.patch.object(os, 'listdir')
386- @mock.patch.object(linux_net, "get_function_by_ifname")
387+ @mock.patch.object(linux_net, "_get_pf_func")
388+ @mock.patch.object(linux_net, "_get_phys_port_name")
389+ @mock.patch.object(linux_net, "_get_phys_switch_id")
390 def test_get_representor_port_exception_value_error(
391- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
392- mock_open):
393+ self, mock__get_phys_switch_id, mock__get_phys_port_name,
394+ mock__get_pf_func, mock_listdir):
395 mock_listdir.return_value = [
396 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
397 ]
398- mock_isfile.side_effect = [True, True]
399- mock_open.return_value.__enter__ = lambda s: s
400- readline_mock = mock_open.return_value.readline
401- readline_mock.side_effect = (
402- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', 'a'])
403- # PCI IDs mocked:
404- # PF0: 0000:0a:00.0
405- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
406- mock_get_function_by_ifname.side_effect = (
407- [("0000:0a:00.0", True),
408- ("0000:0a:02.1", False),
409- ("0000:0a:02.2", False)])
410+ mock__get_phys_switch_id.return_value = 'pf_sw_id'
411+ mock__get_phys_port_name.side_effect = (['p0', '1', 'a'])
412+ mock__get_pf_func.return_value = "0"
413 self.assertRaises(
414 exception.RepresentorNotFound,
415 linux_net.get_representor_port,
416 'pf_ifname', '3')
417
418- @mock.patch('six.moves.builtins.open')
419- @mock.patch.object(os.path, 'isfile')
420 @mock.patch.object(os, 'listdir')
421- def test_physical_function_inferface_name(
422- self, mock_listdir, mock_isfile, mock_open):
423+ @mock.patch.object(linux_net, '_get_phys_switch_id')
424+ def test_physical_function_interface_name(
425+ self, mock__get_phys_switch_id, mock_listdir):
426 mock_listdir.return_value = ['foo', 'bar']
427- mock_isfile.side_effect = [True, True]
428- mock_open.return_value.__enter__ = lambda s: s
429- readline_mock = mock_open.return_value.readline
430- readline_mock.side_effect = (
431+ mock__get_phys_switch_id.side_effect = (
432 ['', 'valid_switch'])
433 ifname = linux_net.get_ifname_by_pci_address(
434 '0000:00:00.1', pf_interface=True, switchdev=False)
435 self.assertEqual(ifname, 'foo')
436
437- @mock.patch('six.moves.builtins.open')
438- @mock.patch.object(os.path, 'isfile')
439 @mock.patch.object(os, 'listdir')
440- def test_physical_function_inferface_name_with_switchdev(
441- self, mock_listdir, mock_isfile, mock_open):
442+ @mock.patch.object(linux_net, '_get_phys_switch_id')
443+ def test_physical_function_interface_name_with_switchdev(
444+ self, mock__get_phys_switch_id, mock_listdir):
445 mock_listdir.return_value = ['foo', 'bar']
446- mock_isfile.side_effect = [True, True]
447- mock_open.return_value.__enter__ = lambda s: s
448- readline_mock = mock_open.return_value.readline
449- readline_mock.side_effect = (
450+ mock__get_phys_switch_id.side_effect = (
451 ['', 'valid_switch'])
452 ifname = linux_net.get_ifname_by_pci_address(
453 '0000:00:00.1', pf_interface=True, switchdev=True)
454@@ -419,3 +325,35 @@ class LinuxNetTest(testtools.TestCase):
455 linux_net.get_vf_num_by_pci_address,
456 '0000:00:00.1'
457 )
458+
459+ @mock.patch('builtins.open')
460+ @mock.patch.object(os.path, 'isfile')
461+ def test__get_phys_port_name(self, mock_isfile, mock_open):
462+ mock_open.return_value.__enter__ = lambda s: s
463+ readline_mock = mock_open.return_value.readline
464+ readline_mock.return_value = 'pf0vf0'
465+ mock_isfile.return_value = True
466+ phys_port_name = linux_net._get_phys_port_name("vf_ifname")
467+ self.assertEqual(phys_port_name, 'pf0vf0')
468+
469+ @mock.patch.object(os.path, 'isfile')
470+ def test__get_phys_port_name_not_found(self, mock_isfile):
471+ mock_isfile.return_value = False
472+ phys_port_name = linux_net._get_phys_port_name("vf_ifname")
473+ self.assertIsNone(phys_port_name)
474+
475+ @mock.patch('builtins.open')
476+ @mock.patch.object(os.path, 'isfile')
477+ def test__get_phys_switch_id(self, mock_isfile, mock_open):
478+ mock_open.return_value.__enter__ = lambda s: s
479+ readline_mock = mock_open.return_value.readline
480+ readline_mock.return_value = '66e40000039b0398'
481+ mock_isfile.return_value = True
482+ phys_port_name = linux_net._get_phys_switch_id("ifname")
483+ self.assertEqual(phys_port_name, '66e40000039b0398')
484+
485+ @mock.patch.object(os.path, 'isfile')
486+ def test__get_phys_switch_id_not_found(self, mock_isfile):
487+ mock_isfile.return_value = False
488+ phys_port_name = linux_net._get_phys_switch_id("ifname")
489+ self.assertIsNone(phys_port_name)
490--
4912.31.1
diff --git a/debian/patches/series b/debian/patches/series
0new file mode 100644492new file mode 100644
index 0000000..2467eb6
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,2 @@
1Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
2Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch

Subscribers

People subscribed via source and target branches