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

Proposed by Frode Nordahl
Status: Merged
Merge reported by: Corey Bryant
Merged at revision: 98b7c9312ffcbcec06d6880669be746f0e04633d
Proposed branch: ~fnordahl/ubuntu/+source/python-os-vif:bug/1892132-victoria
Merge into: ~ubuntu-openstack-dev/ubuntu/+source/python-os-vif:stable/victoria
Diff against target: 687 lines (+661/-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 (+482/-0)
debian/patches/series (+2/-0)
Reviewer Review Type Date Requested Status
Corey Bryant Approve
Review via email: mp+408212@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Corey Bryant (corey.bryant) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index 7ff1394..7f75459 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,12 @@
6+python-os-vif (2.2.0-0ubuntu2.2) UNRELEASED; urgency=medium
7+
8+ * Add support for switchdev NICs that link representor ports to parent PCI
9+ device. (LP: #1892132)
10+ - d/p/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
11+ - d/p/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch
12+
13+ -- Frode Nordahl <frode.nordahl@canonical.com> Fri, 16 Jul 2021 09:43:06 +0000
14+
15 python-os-vif (2.2.0-0ubuntu2.1) UNRELEASED; urgency=medium
16
17 * d/gbp.conf: Create stable/victoria branch.
18diff --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
19new file mode 100644
20index 0000000..31c4fdb
21--- /dev/null
22+++ b/debian/patches/Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch
23@@ -0,0 +1,168 @@
24+From ssh://review.opendev.org:29418/openstack/os-vif
25+ * branch refs/changes/55/759255/1 -> FETCH_HEAD
26+From a28aafa796378b8a36ccb51d2c0010a44f622d14 Mon Sep 17 00:00:00 2001
27+From: Mamduh Alassi <mamduhala@mellanox.com>
28+Date: Wed, 12 Aug 2020 16:24:47 +0300
29+Subject: [PATCH] Fix - os-vif fails to get the correct UpLink Representor
30+
31+Till kernel 5.7 PF and VF representors are exposed as virtual device.
32+They are not linked to its parent PCI device like how uplink
33+representor is linked.
34+
35+Starting from kernel 5.8 due to new change [1] the PF and VF representors are
36+linked to their parent PCI device, and so "get_ifname_by_pci_address" fails
37+to get the correct UpLink Representor.
38+
39+This patch modifys the behviour of "get_ifname_by_pci_address" to
40+check the physical port name of the netdev in
41+vf_pci_addr_path/physfn/net to match the formart for the uplink "p\d+".
42+
43+[1] https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=123f0f53dd64b67e34142485fe866a8a581f12f1
44+
45+Closes-Bug: #1892132
46+Change-Id: I49f6ae3f0e6bfbf555c8284bfd70371ce90da0c7
47+(cherry picked from commit b37de19c58c877f5174d76d0a4ba5ab519f464e8)
48+---
49+ .../notes/bug-1892132-812e6d5ce0588ebb.yaml | 10 +++++
50+ vif_plug_ovs/linux_net.py | 28 +++++++++---
51+ vif_plug_ovs/tests/unit/test_linux_net.py | 44 +++++++++++++++++--
52+ 3 files changed, 74 insertions(+), 8 deletions(-)
53+ create mode 100644 releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
54+
55+diff --git a/releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml b/releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
56+new file mode 100644
57+index 0000000..f7604dd
58+--- /dev/null
59++++ b/releasenotes/notes/bug-1892132-812e6d5ce0588ebb.yaml
60+@@ -0,0 +1,10 @@
61++---
62++fixes:
63++ - |
64++ Linux kernel 5.8 changed the sysfs interface that is used to
65++ discover the interfaces used for OVS offloads for certain NIC
66++ models. This results in network plugging failure, as described
67++ in `bug #1892132`_. This release fixes the plugging issue by
68++ properly handling the new sysfs structure.
69++
70++ .. _bug #1892132: https://bugs.launchpad.net/os-vif/+bug/1892132
71+diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py
72+index 448b08c..7c5e1a2 100644
73+--- a/vif_plug_ovs/linux_net.py
74++++ b/vif_plug_ovs/linux_net.py
75+@@ -45,6 +45,8 @@ VF_RE = re.compile(r"vf(\d+)", re.IGNORECASE)
76+ PF_RE = re.compile(r"pf(\d+)", re.IGNORECASE)
77+ # bus_info (bdf) contains <bus>:<dev>.<func>
78+ PF_FUNC_RE = re.compile(r"\.(\d+)", 0)
79++# phys_port_name contains p##
80++UPLINK_PORT_RE = re.compile(r"p(\d+)", re.IGNORECASE)
81+
82+ _SRIOV_TOTALVFS = "sriov_totalvfs"
83+ NIC_NAME_LEN = 14
84+@@ -328,12 +330,28 @@ def get_ifname_by_pci_address(pci_addr, pf_interface=False, switchdev=False):
85+ itself based on the argument of pf_interface.
86+ """
87+ dev_path = _get_sysfs_netdev_path(pci_addr, pf_interface)
88+- # make the if statement later more readable
89+- ignore_switchdev = not switchdev
90+ try:
91+- for netdev in os.listdir(dev_path):
92+- if ignore_switchdev or _is_switchdev(netdev):
93+- return netdev
94++ devices = os.listdir(dev_path)
95++
96++ # Return the first netdev in case of switchdev=False
97++ if not switchdev:
98++ return devices[0]
99++ elif pf_interface:
100++ fallback_netdev = None
101++ for netdev in devices:
102++ # Return the uplink representor in case of switchdev=True
103++ if _is_switchdev(netdev):
104++ fallback_netdev = netdev if fallback_netdev is None \
105++ else fallback_netdev
106++ phys_port_name = _get_phys_port_name(netdev)
107++ if phys_port_name is not None and \
108++ UPLINK_PORT_RE.search(phys_port_name):
109++ return netdev
110++
111++ # Fallback to first switchdev netdev in case of switchdev=True
112++ if fallback_netdev is not None:
113++ return fallback_netdev
114++
115+ except Exception:
116+ raise exception.PciDeviceNotFoundById(id=pci_addr)
117+ raise exception.PciDeviceNotFoundById(id=pci_addr)
118+diff --git a/vif_plug_ovs/tests/unit/test_linux_net.py b/vif_plug_ovs/tests/unit/test_linux_net.py
119+index 63ee393..029087a 100644
120+--- a/vif_plug_ovs/tests/unit/test_linux_net.py
121++++ b/vif_plug_ovs/tests/unit/test_linux_net.py
122+@@ -261,26 +261,64 @@ class LinuxNetTest(testtools.TestCase):
123+
124+ @mock.patch.object(os, 'listdir')
125+ @mock.patch.object(linux_net, '_get_phys_switch_id')
126++ @mock.patch.object(linux_net, "_get_phys_port_name")
127+ def test_physical_function_interface_name(
128+- self, mock__get_phys_switch_id, mock_listdir):
129++ self, mock__get_phys_port_name, mock__get_phys_switch_id,
130++ mock_listdir):
131+ mock_listdir.return_value = ['foo', 'bar']
132+ mock__get_phys_switch_id.side_effect = (
133+ ['', 'valid_switch'])
134++ mock__get_phys_port_name.side_effect = (["p1"])
135+ ifname = linux_net.get_ifname_by_pci_address(
136+ '0000:00:00.1', pf_interface=True, switchdev=False)
137+ self.assertEqual(ifname, 'foo')
138+
139+ @mock.patch.object(os, 'listdir')
140+- @mock.patch.object(linux_net, '_get_phys_switch_id')
141++ @mock.patch.object(linux_net, "_get_phys_switch_id")
142++ @mock.patch.object(linux_net, "_get_phys_port_name")
143+ def test_physical_function_interface_name_with_switchdev(
144+- self, mock__get_phys_switch_id, mock_listdir):
145++ self, mock__get_phys_port_name, mock__get_phys_switch_id,
146++ mock_listdir):
147+ mock_listdir.return_value = ['foo', 'bar']
148+ mock__get_phys_switch_id.side_effect = (
149+ ['', 'valid_switch'])
150++ mock__get_phys_port_name.side_effect = (["p1s0"])
151+ ifname = linux_net.get_ifname_by_pci_address(
152+ '0000:00:00.1', pf_interface=True, switchdev=True)
153+ self.assertEqual(ifname, 'bar')
154+
155++ @mock.patch.object(os, 'listdir')
156++ @mock.patch.object(linux_net, "_get_phys_switch_id")
157++ @mock.patch.object(linux_net, "_get_phys_port_name")
158++ def test_physical_function_interface_name_with_representors(
159++ self, mock__get_phys_port_name, mock__get_phys_switch_id,
160++ mock_listdir):
161++ # Get the PF that matches the phys_port_name regex
162++ mock_listdir.return_value = ['enp2s0f0_0', 'enp2s0f0_1', 'enp2s0f0']
163++ mock__get_phys_switch_id.side_effect = (
164++ ['valid_switch', 'valid_switch', 'valid_switch'])
165++ mock__get_phys_port_name.side_effect = (["pf0vf0", "pf0vf1", "p0"])
166++ ifname = linux_net.get_ifname_by_pci_address(
167++ '0000:00:00.1', pf_interface=True, switchdev=True)
168++ self.assertEqual(ifname, 'enp2s0f0')
169++
170++ @mock.patch.object(os, 'listdir')
171++ @mock.patch.object(linux_net, "_get_phys_switch_id")
172++ @mock.patch.object(linux_net, "_get_phys_port_name")
173++ def test_physical_function_interface_name_with_fallback_To_first_netdev(
174++ self, mock__get_phys_port_name, mock__get_phys_switch_id,
175++ mock_listdir):
176++ # Try with switchdev mode to get PF but fail because there is no match
177++ # for the phys_port_name then fallback to first interface found
178++ mock_listdir.return_value = ['enp2s0f0_0', 'enp2s0f0_1', 'enp2s0f0']
179++ mock__get_phys_switch_id.side_effect = (['valid_switch',
180++ 'valid_switch',
181++ 'valid_switch'])
182++ mock__get_phys_port_name.side_effect = (["pf0vf0", "pf0vf1", "pf0vf2"])
183++ ifname = linux_net.get_ifname_by_pci_address(
184++ '0000:00:00.1', pf_interface=True, switchdev=True)
185++ self.assertEqual(ifname, 'enp2s0f0_0')
186++
187+ @mock.patch.object(os, 'listdir')
188+ def test_get_ifname_by_pci_address_exception(self, mock_listdir):
189+ mock_listdir.side_effect = OSError('No such file or directory')
190+--
191+2.31.1
192diff --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
193new file mode 100644
194index 0000000..46cc4d8
195--- /dev/null
196+++ b/debian/patches/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
197@@ -0,0 +1,482 @@
198+From https://review.opendev.org/openstack/os-vif
199+ * branch refs/changes/06/756406/1 -> FETCH_HEAD
200+From 167bb030f1143f37ce189673d831bd572f64d4ad Mon Sep 17 00:00:00 2001
201+From: Mamduh <mamduhala@nvidia.com>
202+Date: Tue, 18 Aug 2020 12:40:10 +0300
203+Subject: [PATCH] Refactor code of linux_net to more cleaner and increase
204+ performace
205+
206+The patch adds new functions '_get_phys_port_name' for reading physical
207+port name of the SR-IOV port and '_get_phys_switch_id' for reading
208+physical port switch ID of the SR-IOV port, in addition to refactoring
209+'get_representor_port' to use the new functions and decrease calls for
210+"_get_pf_func" and netdevs associated with the PF will now be processed
211+in the loop, however it will not be matching 'phys_port_name' which
212+ensures the correct behaviour.
213+
214+In addition to updating the unit test for linux_net and remove not
215+needed mocks
216+
217+Related-Bug: #1892132
218+Change-Id: I3fdbea4f48cb79ebfd03a4da21e2232ccafb7a76
219+(cherry picked from commit 76f7565b99e637d74878955a0033f35e9eb0e13f)
220+---
221+ vif_plug_ovs/linux_net.py | 72 ++++---
222+ vif_plug_ovs/tests/unit/test_linux_net.py | 250 ++++++++--------------
223+ 2 files changed, 137 insertions(+), 185 deletions(-)
224+
225+diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py
226+index 0d677a6..448b08c 100644
227+--- a/vif_plug_ovs/linux_net.py
228++++ b/vif_plug_ovs/linux_net.py
229+@@ -239,46 +239,35 @@ def get_representor_port(pf_ifname, vf_num):
230+ VF number in the phys_port_name. That interface is the representor for
231+ the requested VF.
232+ """
233+- pf_path = "/sys/class/net/%s" % pf_ifname
234+- pf_sw_id_file = os.path.join(pf_path, "phys_switch_id")
235+
236+ pf_sw_id = None
237+ try:
238+- with open(pf_sw_id_file, 'r') as fd:
239+- pf_sw_id = fd.readline().rstrip()
240++ pf_sw_id = _get_phys_switch_id(pf_ifname)
241+ except (OSError, IOError):
242+ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
243+
244+- pf_subsystem_file = os.path.join(pf_path, "subsystem")
245++ pf_subsystem_file = "/sys/class/net/%s/subsystem" % pf_ifname
246+ try:
247+ devices = os.listdir(pf_subsystem_file)
248+ except (OSError, IOError):
249+ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
250+
251+- for device in devices:
252+- address_str, pf = get_function_by_ifname(device)
253+- if pf:
254+- continue
255++ ifname_pf_func = _get_pf_func(pf_ifname)
256++ if ifname_pf_func is None:
257++ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
258+
259+- device_path = "/sys/class/net/%s" % device
260+- device_sw_id_file = os.path.join(device_path, "phys_switch_id")
261++ for device in devices:
262+ try:
263+- with open(device_sw_id_file, 'r') as fd:
264+- device_sw_id = fd.readline().rstrip()
265++ device_sw_id = _get_phys_switch_id(device)
266++ if not device_sw_id or device_sw_id != pf_sw_id:
267++ continue
268+ except (OSError, IOError):
269+ continue
270+
271+- if device_sw_id != pf_sw_id:
272+- continue
273+- device_port_name_file = (
274+- os.path.join(device_path, 'phys_port_name'))
275+-
276+- if not os.path.isfile(device_port_name_file):
277+- continue
278+-
279+ try:
280+- with open(device_port_name_file, 'r') as fd:
281+- phys_port_name = fd.readline().rstrip()
282++ phys_port_name = _get_phys_port_name(device)
283++ if phys_port_name is None:
284++ continue
285+ except (OSError, IOError):
286+ continue
287+
288+@@ -287,9 +276,6 @@ def get_representor_port(pf_ifname, vf_num):
289+ # the PCI func number of pf_ifname.
290+ rep_parent_pf_func = _parse_pf_number(phys_port_name)
291+ if rep_parent_pf_func is not None:
292+- ifname_pf_func = _get_pf_func(pf_ifname)
293+- if ifname_pf_func is None:
294+- continue
295+ if int(rep_parent_pf_func) != int(ifname_pf_func):
296+ continue
297+
298+@@ -321,9 +307,7 @@ def _get_sysfs_netdev_path(pci_addr, pf_interface):
299+ def _is_switchdev(netdev):
300+ """Returns True if a netdev has a readable phys_switch_id"""
301+ try:
302+- sw_id_file = "/sys/class/net/%s/phys_switch_id" % netdev
303+- with open(sw_id_file, 'r') as fd:
304+- phys_switch_id = fd.readline().rstrip()
305++ phys_switch_id = _get_phys_switch_id(netdev)
306+ if phys_switch_id != "" and phys_switch_id is not None:
307+ return True
308+ except (OSError, IOError):
309+@@ -389,3 +373,33 @@ def get_pf_pci_from_vf(vf_pci):
310+ """
311+ physfn_path = os.readlink("/sys/bus/pci/devices/%s/physfn" % vf_pci)
312+ return os.path.basename(physfn_path)
313++
314++
315++def _get_phys_port_name(ifname):
316++ """Get the interface name and return its phys_port_name
317++
318++ :param ifname: The interface name
319++ :return: The phys_port_name of the given ifname
320++ """
321++ phys_port_name_path = "/sys/class/net/%s/phys_port_name" % ifname
322++
323++ if not os.path.isfile(phys_port_name_path):
324++ return None
325++
326++ with open(phys_port_name_path, 'r') as fd:
327++ return fd.readline().strip()
328++
329++
330++def _get_phys_switch_id(ifname):
331++ """Get the interface name and return its phys_switch_id
332++
333++ :param ifname: The interface name
334++ :return: The phys_switch_id of the given ifname
335++ """
336++ phys_port_name_path = "/sys/class/net/%s/phys_switch_id" % ifname
337++
338++ if not os.path.isfile(phys_port_name_path):
339++ return None
340++
341++ with open(phys_port_name_path, 'r') as fd:
342++ return fd.readline().strip()
343+diff --git a/vif_plug_ovs/tests/unit/test_linux_net.py b/vif_plug_ovs/tests/unit/test_linux_net.py
344+index 659b1a2..63ee393 100644
345+--- a/vif_plug_ovs/tests/unit/test_linux_net.py
346++++ b/vif_plug_ovs/tests/unit/test_linux_net.py
347+@@ -133,47 +133,22 @@ class LinuxNetTest(testtools.TestCase):
348+ linux_net.add_bridge_port("br0", "vnet1")
349+ mock_set.assert_called_once_with("vnet1", master="br0")
350+
351+- @mock.patch('builtins.open')
352+- @mock.patch.object(os.path, 'isfile')
353+- def test_is_switchdev_ioerror(self, mock_isfile, mock_open):
354+- mock_isfile.side_effect = [True]
355+- mock_open.return_value.__enter__ = lambda s: s
356+- readline_mock = mock_open.return_value.readline
357+- readline_mock.side_effect = (
358+- [IOError()])
359++ @mock.patch.object(linux_net, '_get_phys_switch_id')
360++ def test_is_switchdev_ioerror(self, mock__get_phys_switch_id):
361++ mock__get_phys_switch_id.side_effect = ([IOError()])
362+ test_switchdev = linux_net._is_switchdev('pf_ifname')
363+ self.assertEqual(test_switchdev, False)
364+
365+- @mock.patch('builtins.open')
366+- @mock.patch.object(os.path, 'isfile')
367+- def test_is_switchdev_empty(self, mock_isfile, mock_open):
368+- mock_isfile.side_effect = [True]
369+- mock_open.return_value.__enter__ = lambda s: s
370+- readline_mock = mock_open.return_value.readline
371+- readline_mock.side_effect = (
372+- [''])
373+- open_calls = (
374+- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
375+- mock.call().readline(),
376+- mock.call().__exit__(None, None, None)])
377++ @mock.patch.object(linux_net, '_get_phys_switch_id')
378++ def test_is_switchdev_empty(self, mock__get_phys_switch_id):
379++ mock__get_phys_switch_id.return_value = ''
380+ test_switchdev = linux_net._is_switchdev('pf_ifname')
381+- mock_open.assert_has_calls(open_calls)
382+ self.assertEqual(test_switchdev, False)
383+
384+- @mock.patch('builtins.open')
385+- @mock.patch.object(os.path, 'isfile')
386+- def test_is_switchdev_positive(self, mock_isfile, mock_open):
387+- mock_isfile.side_effect = [True]
388+- mock_open.return_value.__enter__ = lambda s: s
389+- readline_mock = mock_open.return_value.readline
390+- readline_mock.side_effect = (
391+- ['pf_sw_id'])
392+- open_calls = (
393+- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
394+- mock.call().readline(),
395+- mock.call().__exit__(None, None, None)])
396++ @mock.patch.object(linux_net, '_get_phys_switch_id')
397++ def test_is_switchdev_positive(self, mock__get_phys_switch_id):
398++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
399+ test_switchdev = linux_net._is_switchdev('pf_ifname')
400+- mock_open.assert_has_calls(open_calls)
401+ self.assertEqual(test_switchdev, True)
402+
403+ def test_parse_vf_number(self):
404+@@ -192,184 +167,115 @@ class LinuxNetTest(testtools.TestCase):
405+ self.assertEqual(linux_net._parse_pf_number("pf31"), "31")
406+ self.assertIsNone(linux_net._parse_pf_number("g4rbl3d"))
407+
408+- @mock.patch('builtins.open')
409+- @mock.patch.object(os.path, 'isfile')
410+ @mock.patch.object(os, 'listdir')
411+- @mock.patch.object(linux_net, "get_function_by_ifname")
412+- def test_get_representor_port(self, mock_get_function_by_ifname,
413+- mock_listdir, mock_isfile, mock_open):
414++ @mock.patch.object(linux_net, "_get_pf_func")
415++ @mock.patch.object(linux_net, "_get_phys_port_name")
416++ @mock.patch.object(linux_net, '_get_phys_switch_id')
417++ def test_get_representor_port(self, mock__get_phys_switch_id,
418++ mock__get_phys_port_name,
419++ mock__get_pf_func,
420++ mock_listdir):
421+ mock_listdir.return_value = [
422+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
423+ ]
424+- mock_isfile.side_effect = [True, True]
425+- mock_open.return_value.__enter__ = lambda s: s
426+- readline_mock = mock_open.return_value.readline
427+- readline_mock.side_effect = (
428+- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', 'pf0vf2'])
429+- # PCI IDs mocked:
430+- # PF0: 0000:0a:00.0
431+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
432+- mock_get_function_by_ifname.side_effect = (
433+- [("0000:0a:00.0", True),
434+- ("0000:0a:02.1", False),
435+- ("0000:0a:02.2", False), ("0000:0a:00.0", True)])
436+- open_calls = (
437+- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
438+- mock.call().readline(),
439+- mock.call().__exit__(None, None, None),
440+- mock.call('/sys/class/net/rep_vf_1/phys_switch_id', 'r'),
441+- mock.call().readline(),
442+- mock.call().__exit__(None, None, None),
443+- mock.call('/sys/class/net/rep_vf_1/phys_port_name', 'r'),
444+- mock.call().readline(),
445+- mock.call().__exit__(None, None, None),
446+- mock.call('/sys/class/net/rep_vf_2/phys_switch_id', 'r'),
447+- mock.call().readline(),
448+- mock.call().__exit__(None, None, None),
449+- mock.call('/sys/class/net/rep_vf_2/phys_port_name', 'r'),
450+- mock.call().readline(),
451+- mock.call().__exit__(None, None, None)])
452++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
453++ mock__get_pf_func.return_value = "0"
454++ mock__get_phys_port_name.side_effect = (['1', "pf0vf1", "pf0vf2"])
455+ ifname = linux_net.get_representor_port('pf_ifname', '2')
456+- mock_open.assert_has_calls(open_calls)
457+ self.assertEqual('rep_vf_2', ifname)
458+
459+- @mock.patch('builtins.open')
460+- @mock.patch.object(os.path, 'isfile')
461+ @mock.patch.object(os, 'listdir')
462+- @mock.patch.object(linux_net, "get_function_by_ifname")
463++ @mock.patch.object(linux_net, "_get_pf_func")
464++ @mock.patch.object(linux_net, "_get_phys_port_name")
465++ @mock.patch.object(linux_net, "_get_phys_switch_id")
466+ def test_get_representor_port_2_pfs(
467+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
468+- mock_open):
469++ self, mock__get_phys_switch_id, mock__get_phys_port_name,
470++ mock__get_pf_func, mock_listdir):
471+ mock_listdir.return_value = [
472+ 'pf_ifname1', 'pf_ifname2', 'rep_pf1_vf_1', 'rep_pf1_vf_2',
473+ 'rep_pf2_vf_1', 'rep_pf2_vf_2',
474+ ]
475+- mock_isfile.side_effect = [True, True, True, True]
476+- mock_open.return_value.__enter__ = lambda s: s
477+- readline_mock = mock_open.return_value.readline
478+- readline_mock.side_effect = (
479+- ['pf_sw_id',
480+- 'pf_sw_id', 'VF1@PF1', 'pf_sw_id', 'vf2@pf1',
481+- 'pf_sw_id', 'pf2vf1', 'pf_sw_id', 'pf2vf2'])
482+- # PCI IDs mocked:
483+- # PF1: 0000:0a:00.1 PF2: 0000:0a:00.2
484+- # PF1VF1: 0000:0a:02.1 PF1VF2: 0000:0a:02.2
485+- # PF2VF1: 0000:0a:04.1 PF2VF2: 0000:0a:04.2
486+- mock_get_function_by_ifname.side_effect = (
487+- [("0000:0a:00.1", True), ("0000:0a:00.2", True),
488+- ("0000:0a:02.1", False), ("0000:0a:00.2", True),
489+- ("0000:0a:02.2", False), ("0000:0a:00.2", True),
490+- ("0000:0a:04.1", False), ("0000:0a:00.2", True),
491+- ("0000:0a:04.2", False), ("0000:0a:00.2", True)])
492++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
493++ mock__get_pf_func.return_value = "2"
494++ mock__get_phys_port_name.side_effect = (
495++ ["p1", "p2", "VF1@PF1", "pf2vf1", "vf2@pf1", "pf2vf2"])
496+ ifname = linux_net.get_representor_port('pf_ifname2', '2')
497+ self.assertEqual('rep_pf2_vf_2', ifname)
498+
499+- @mock.patch('builtins.open')
500+- @mock.patch.object(os.path, 'isfile')
501+ @mock.patch.object(os, 'listdir')
502+- @mock.patch.object(linux_net, "get_function_by_ifname")
503++ @mock.patch.object(linux_net, "_get_pf_func")
504++ @mock.patch.object(linux_net, "_get_phys_switch_id")
505++ @mock.patch.object(linux_net, "_get_phys_port_name")
506+ def test_get_representor_port_not_found(
507+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
508+- mock_open):
509++ self, mock__get_phys_port_name, mock__get_phys_switch_id,
510++ mock__get_pf_func, mock_listdir):
511+ mock_listdir.return_value = [
512+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
513+ ]
514+- mock_isfile.side_effect = [True, True]
515+- mock_open.return_value.__enter__ = lambda s: s
516+- readline_mock = mock_open.return_value.readline
517+- readline_mock.side_effect = (
518+- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', '2'])
519+- # PCI IDs mocked:
520+- # PF0: 0000:0a:00.0
521+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
522+- mock_get_function_by_ifname.side_effect = (
523+- [("0000:0a:00.0", True),
524+- ("0000:0a:02.1", False),
525+- ("0000:0a:02.2", False)])
526++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
527++ mock__get_pf_func.return_value = "0"
528++ mock__get_phys_port_name.side_effect = (
529++ ["p0", "1", "2"])
530+ self.assertRaises(
531+ exception.RepresentorNotFound,
532+ linux_net.get_representor_port,
533+ 'pf_ifname', '3'),
534+
535+- @mock.patch('builtins.open')
536+- @mock.patch.object(os.path, 'isfile')
537+ @mock.patch.object(os, 'listdir')
538+- @mock.patch.object(linux_net, "get_function_by_ifname")
539++ @mock.patch.object(linux_net, "_get_pf_func")
540++ @mock.patch.object(linux_net, "_get_phys_port_name")
541++ @mock.patch.object(linux_net, "_get_phys_switch_id")
542+ def test_get_representor_port_exception_io_error(
543+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
544+- mock_open):
545++ self, mock__get_phys_switch_id, mock__get_phys_port_name,
546++ mock__get_pf_func, mock_listdir):
547+ mock_listdir.return_value = [
548+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
549+ ]
550+- mock_isfile.side_effect = [True, True]
551+- mock_open.return_value.__enter__ = lambda s: s
552+- readline_mock = mock_open.return_value.readline
553+- readline_mock.side_effect = (
554++ mock__get_phys_switch_id.side_effect = (
555+ ['pf_sw_id', 'pf_sw_id', IOError(), 'pf_sw_id', '2'])
556+- # PCI IDs mocked:
557+- # PF0: 0000:0a:00.0
558+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
559+- mock_get_function_by_ifname.side_effect = (
560+- [("0000:0a:00.0", True),
561+- ("0000:0a:02.1", False),
562+- ("0000:0a:02.2", False), ("0000:0a:00.0", True)])
563++ mock__get_pf_func.return_value = "0"
564++ mock__get_phys_port_name.side_effect = (
565++ ["p0", "pf0vf0", "pf0vf1"])
566+ self.assertRaises(
567+ exception.RepresentorNotFound,
568+ linux_net.get_representor_port,
569+ 'pf_ifname', '3')
570+
571+- @mock.patch('builtins.open')
572+- @mock.patch.object(os.path, 'isfile')
573+ @mock.patch.object(os, 'listdir')
574+- @mock.patch.object(linux_net, "get_function_by_ifname")
575++ @mock.patch.object(linux_net, "_get_pf_func")
576++ @mock.patch.object(linux_net, "_get_phys_port_name")
577++ @mock.patch.object(linux_net, "_get_phys_switch_id")
578+ def test_get_representor_port_exception_value_error(
579+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
580+- mock_open):
581++ self, mock__get_phys_switch_id, mock__get_phys_port_name,
582++ mock__get_pf_func, mock_listdir):
583+ mock_listdir.return_value = [
584+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
585+ ]
586+- mock_isfile.side_effect = [True, True]
587+- mock_open.return_value.__enter__ = lambda s: s
588+- readline_mock = mock_open.return_value.readline
589+- readline_mock.side_effect = (
590+- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', 'a'])
591+- # PCI IDs mocked:
592+- # PF0: 0000:0a:00.0
593+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
594+- mock_get_function_by_ifname.side_effect = (
595+- [("0000:0a:00.0", True),
596+- ("0000:0a:02.1", False),
597+- ("0000:0a:02.2", False)])
598++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
599++ mock__get_phys_port_name.side_effect = (['p0', '1', 'a'])
600++ mock__get_pf_func.return_value = "0"
601+ self.assertRaises(
602+ exception.RepresentorNotFound,
603+ linux_net.get_representor_port,
604+ 'pf_ifname', '3')
605+
606+- @mock.patch('builtins.open')
607+- @mock.patch.object(os.path, 'isfile')
608+ @mock.patch.object(os, 'listdir')
609+- def test_physical_function_inferface_name(
610+- self, mock_listdir, mock_isfile, mock_open):
611++ @mock.patch.object(linux_net, '_get_phys_switch_id')
612++ def test_physical_function_interface_name(
613++ self, mock__get_phys_switch_id, mock_listdir):
614+ mock_listdir.return_value = ['foo', 'bar']
615+- mock_isfile.side_effect = [True, True]
616+- mock_open.return_value.__enter__ = lambda s: s
617+- readline_mock = mock_open.return_value.readline
618+- readline_mock.side_effect = (
619++ mock__get_phys_switch_id.side_effect = (
620+ ['', 'valid_switch'])
621+ ifname = linux_net.get_ifname_by_pci_address(
622+ '0000:00:00.1', pf_interface=True, switchdev=False)
623+ self.assertEqual(ifname, 'foo')
624+
625+- @mock.patch('builtins.open')
626+- @mock.patch.object(os.path, 'isfile')
627+ @mock.patch.object(os, 'listdir')
628+- def test_physical_function_inferface_name_with_switchdev(
629+- self, mock_listdir, mock_isfile, mock_open):
630++ @mock.patch.object(linux_net, '_get_phys_switch_id')
631++ def test_physical_function_interface_name_with_switchdev(
632++ self, mock__get_phys_switch_id, mock_listdir):
633+ mock_listdir.return_value = ['foo', 'bar']
634+- mock_isfile.side_effect = [True, True]
635+- mock_open.return_value.__enter__ = lambda s: s
636+- readline_mock = mock_open.return_value.readline
637+- readline_mock.side_effect = (
638++ mock__get_phys_switch_id.side_effect = (
639+ ['', 'valid_switch'])
640+ ifname = linux_net.get_ifname_by_pci_address(
641+ '0000:00:00.1', pf_interface=True, switchdev=True)
642+@@ -420,3 +326,35 @@ class LinuxNetTest(testtools.TestCase):
643+ linux_net.get_vf_num_by_pci_address,
644+ '0000:00:00.1'
645+ )
646++
647++ @mock.patch('builtins.open')
648++ @mock.patch.object(os.path, 'isfile')
649++ def test__get_phys_port_name(self, mock_isfile, mock_open):
650++ mock_open.return_value.__enter__ = lambda s: s
651++ readline_mock = mock_open.return_value.readline
652++ readline_mock.return_value = 'pf0vf0'
653++ mock_isfile.return_value = True
654++ phys_port_name = linux_net._get_phys_port_name("vf_ifname")
655++ self.assertEqual(phys_port_name, 'pf0vf0')
656++
657++ @mock.patch.object(os.path, 'isfile')
658++ def test__get_phys_port_name_not_found(self, mock_isfile):
659++ mock_isfile.return_value = False
660++ phys_port_name = linux_net._get_phys_port_name("vf_ifname")
661++ self.assertIsNone(phys_port_name)
662++
663++ @mock.patch('builtins.open')
664++ @mock.patch.object(os.path, 'isfile')
665++ def test__get_phys_switch_id(self, mock_isfile, mock_open):
666++ mock_open.return_value.__enter__ = lambda s: s
667++ readline_mock = mock_open.return_value.readline
668++ readline_mock.return_value = '66e40000039b0398'
669++ mock_isfile.return_value = True
670++ phys_port_name = linux_net._get_phys_switch_id("ifname")
671++ self.assertEqual(phys_port_name, '66e40000039b0398')
672++
673++ @mock.patch.object(os.path, 'isfile')
674++ def test__get_phys_switch_id_not_found(self, mock_isfile):
675++ mock_isfile.return_value = False
676++ phys_port_name = linux_net._get_phys_switch_id("ifname")
677++ self.assertIsNone(phys_port_name)
678+--
679+2.31.1
680diff --git a/debian/patches/series b/debian/patches/series
681new file mode 100644
682index 0000000..2467eb6
683--- /dev/null
684+++ b/debian/patches/series
685@@ -0,0 +1,2 @@
686+Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
687+Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch

Subscribers

People subscribed via source and target branches