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
1diff --git a/debian/changelog b/debian/changelog
2index e2673a2..b62c1c2 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,12 @@
6+python-os-vif (2.0.0-0ubuntu1.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.0.0-0ubuntu1.1) UNRELEASED; urgency=medium
16
17 [ Corey Bryant ]
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..bb82b13
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/67/765967/5 -> FETCH_HEAD
26+From 1226d46cc8bde9531821c68465a05292528142f0 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 a28aafa796378b8a36ccb51d2c0010a44f622d14)
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 3e77585..f7b120c 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+@@ -327,12 +329,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 a5404ea..e19ce94 100644
120+--- a/vif_plug_ovs/tests/unit/test_linux_net.py
121++++ b/vif_plug_ovs/tests/unit/test_linux_net.py
122+@@ -260,26 +260,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..e895a24
195--- /dev/null
196+++ b/debian/patches/Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
197@@ -0,0 +1,491 @@
198+From ssh://review.opendev.org:29418/openstack/os-vif
199+ * branch refs/changes/19/765419/6 -> FETCH_HEAD
200+From 3e1d898b752c327165aeca1fec0919d858a87ec4 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+Conflicts:
218+ vif_plug_ovs/linux_net.py
219+ vif_plug_ovs/tests/unit/test_linux_net.py
220+
221+Related-Bug: #1892132
222+Change-Id: I3fdbea4f48cb79ebfd03a4da21e2232ccafb7a76
223+(cherry picked from commit 167bb030f1143f37ce189673d831bd572f64d4ad)
224+---
225+ vif_plug_ovs/linux_net.py | 77 ++++---
226+ vif_plug_ovs/tests/unit/test_linux_net.py | 250 ++++++++--------------
227+ 2 files changed, 139 insertions(+), 188 deletions(-)
228+
229+diff --git a/vif_plug_ovs/linux_net.py b/vif_plug_ovs/linux_net.py
230+index 20baab3..3e77585 100644
231+--- a/vif_plug_ovs/linux_net.py
232++++ b/vif_plug_ovs/linux_net.py
233+@@ -239,46 +239,35 @@ def get_representor_port(pf_ifname, vf_num):
234+ VF number in the phys_port_name. That interface is the representor for
235+ the requested VF.
236+ """
237+- pf_path = "/sys/class/net/%s" % pf_ifname
238+- pf_sw_id_file = os.path.join(pf_path, "phys_switch_id")
239+
240+ pf_sw_id = None
241+ try:
242+- with open(pf_sw_id_file, 'r') as fd:
243+- pf_sw_id = fd.readline().rstrip()
244++ pf_sw_id = _get_phys_switch_id(pf_ifname)
245+ except (OSError, IOError):
246+ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
247+
248+- pf_subsystem_file = os.path.join(pf_path, "subsystem")
249++ pf_subsystem_file = "/sys/class/net/%s/subsystem" % pf_ifname
250+ try:
251+ devices = os.listdir(pf_subsystem_file)
252+ except (OSError, IOError):
253+ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
254+
255+- for device in devices:
256+- address_str, pf = get_function_by_ifname(device)
257+- if pf:
258+- continue
259++ ifname_pf_func = _get_pf_func(pf_ifname)
260++ if ifname_pf_func is None:
261++ raise exception.RepresentorNotFound(ifname=pf_ifname, vf_num=vf_num)
262+
263+- device_path = "/sys/class/net/%s" % device
264+- device_sw_id_file = os.path.join(device_path, "phys_switch_id")
265++ for device in devices:
266+ try:
267+- with open(device_sw_id_file, 'r') as fd:
268+- device_sw_id = fd.readline().rstrip()
269++ device_sw_id = _get_phys_switch_id(device)
270++ if not device_sw_id or device_sw_id != pf_sw_id:
271++ continue
272+ except (OSError, IOError):
273+ continue
274+
275+- if device_sw_id != pf_sw_id:
276+- continue
277+- device_port_name_file = (
278+- os.path.join(device_path, 'phys_port_name'))
279+-
280+- if not os.path.isfile(device_port_name_file):
281+- continue
282+-
283+ try:
284+- with open(device_port_name_file, 'r') as fd:
285+- phys_port_name = fd.readline().rstrip()
286++ phys_port_name = _get_phys_port_name(device)
287++ if phys_port_name is None:
288++ continue
289+ except (OSError, IOError):
290+ continue
291+
292+@@ -287,12 +276,8 @@ def get_representor_port(pf_ifname, vf_num):
293+ # the PCI func number of pf_ifname.
294+ rep_parent_pf_func = _parse_pf_number(phys_port_name)
295+ if rep_parent_pf_func is not None:
296+- ifname_pf_func = _get_pf_func(pf_ifname)
297+- if ifname_pf_func is None:
298+- continue
299+- if int(rep_parent_pf_func) != int(ifname_pf_func):
300+- continue
301+-
302++ if int(rep_parent_pf_func) != int(ifname_pf_func):
303++ continue
304+ representor_num = _parse_vf_number(phys_port_name)
305+ # Note: representor_num can be 0, referring to VF0
306+ if representor_num is None:
307+@@ -321,9 +306,7 @@ def _get_sysfs_netdev_path(pci_addr, pf_interface):
308+ def _is_switchdev(netdev):
309+ """Returns True if a netdev has a readable phys_switch_id"""
310+ try:
311+- sw_id_file = "/sys/class/net/%s/phys_switch_id" % netdev
312+- with open(sw_id_file, 'r') as fd:
313+- phys_switch_id = fd.readline().rstrip()
314++ phys_switch_id = _get_phys_switch_id(netdev)
315+ if phys_switch_id != "" and phys_switch_id is not None:
316+ return True
317+ except (OSError, IOError):
318+@@ -389,3 +372,33 @@ def get_pf_pci_from_vf(vf_pci):
319+ """
320+ physfn_path = os.readlink("/sys/bus/pci/devices/%s/physfn" % vf_pci)
321+ return os.path.basename(physfn_path)
322++
323++
324++def _get_phys_port_name(ifname):
325++ """Get the interface name and return its phys_port_name
326++
327++ :param ifname: The interface name
328++ :return: The phys_port_name of the given ifname
329++ """
330++ phys_port_name_path = "/sys/class/net/%s/phys_port_name" % ifname
331++
332++ if not os.path.isfile(phys_port_name_path):
333++ return None
334++
335++ with open(phys_port_name_path, 'r') as fd:
336++ return fd.readline().strip()
337++
338++
339++def _get_phys_switch_id(ifname):
340++ """Get the interface name and return its phys_switch_id
341++
342++ :param ifname: The interface name
343++ :return: The phys_switch_id of the given ifname
344++ """
345++ phys_port_name_path = "/sys/class/net/%s/phys_switch_id" % ifname
346++
347++ if not os.path.isfile(phys_port_name_path):
348++ return None
349++
350++ with open(phys_port_name_path, 'r') as fd:
351++ return fd.readline().strip()
352+diff --git a/vif_plug_ovs/tests/unit/test_linux_net.py b/vif_plug_ovs/tests/unit/test_linux_net.py
353+index 4eaa1f7..a5404ea 100644
354+--- a/vif_plug_ovs/tests/unit/test_linux_net.py
355++++ b/vif_plug_ovs/tests/unit/test_linux_net.py
356+@@ -132,47 +132,22 @@ class LinuxNetTest(testtools.TestCase):
357+ linux_net.add_bridge_port("br0", "vnet1")
358+ mock_set.assert_called_once_with("vnet1", master="br0")
359+
360+- @mock.patch('six.moves.builtins.open')
361+- @mock.patch.object(os.path, 'isfile')
362+- def test_is_switchdev_ioerror(self, mock_isfile, mock_open):
363+- mock_isfile.side_effect = [True]
364+- mock_open.return_value.__enter__ = lambda s: s
365+- readline_mock = mock_open.return_value.readline
366+- readline_mock.side_effect = (
367+- [IOError()])
368++ @mock.patch.object(linux_net, '_get_phys_switch_id')
369++ def test_is_switchdev_ioerror(self, mock__get_phys_switch_id):
370++ mock__get_phys_switch_id.side_effect = ([IOError()])
371+ test_switchdev = linux_net._is_switchdev('pf_ifname')
372+ self.assertEqual(test_switchdev, False)
373+
374+- @mock.patch('six.moves.builtins.open')
375+- @mock.patch.object(os.path, 'isfile')
376+- def test_is_switchdev_empty(self, mock_isfile, mock_open):
377+- mock_isfile.side_effect = [True]
378+- mock_open.return_value.__enter__ = lambda s: s
379+- readline_mock = mock_open.return_value.readline
380+- readline_mock.side_effect = (
381+- [''])
382+- open_calls = (
383+- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
384+- mock.call().readline(),
385+- mock.call().__exit__(None, None, None)])
386++ @mock.patch.object(linux_net, '_get_phys_switch_id')
387++ def test_is_switchdev_empty(self, mock__get_phys_switch_id):
388++ mock__get_phys_switch_id.return_value = ''
389+ test_switchdev = linux_net._is_switchdev('pf_ifname')
390+- mock_open.assert_has_calls(open_calls)
391+ self.assertEqual(test_switchdev, False)
392+
393+- @mock.patch('six.moves.builtins.open')
394+- @mock.patch.object(os.path, 'isfile')
395+- def test_is_switchdev_positive(self, mock_isfile, mock_open):
396+- mock_isfile.side_effect = [True]
397+- mock_open.return_value.__enter__ = lambda s: s
398+- readline_mock = mock_open.return_value.readline
399+- readline_mock.side_effect = (
400+- ['pf_sw_id'])
401+- open_calls = (
402+- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
403+- mock.call().readline(),
404+- mock.call().__exit__(None, None, None)])
405++ @mock.patch.object(linux_net, '_get_phys_switch_id')
406++ def test_is_switchdev_positive(self, mock__get_phys_switch_id):
407++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
408+ test_switchdev = linux_net._is_switchdev('pf_ifname')
409+- mock_open.assert_has_calls(open_calls)
410+ self.assertEqual(test_switchdev, True)
411+
412+ def test_parse_vf_number(self):
413+@@ -191,184 +166,115 @@ class LinuxNetTest(testtools.TestCase):
414+ self.assertEqual(linux_net._parse_pf_number("pf31"), "31")
415+ self.assertIsNone(linux_net._parse_pf_number("g4rbl3d"))
416+
417+- @mock.patch('six.moves.builtins.open')
418+- @mock.patch.object(os.path, 'isfile')
419+ @mock.patch.object(os, 'listdir')
420+- @mock.patch.object(linux_net, "get_function_by_ifname")
421+- def test_get_representor_port(self, mock_get_function_by_ifname,
422+- mock_listdir, mock_isfile, mock_open):
423++ @mock.patch.object(linux_net, "_get_pf_func")
424++ @mock.patch.object(linux_net, "_get_phys_port_name")
425++ @mock.patch.object(linux_net, '_get_phys_switch_id')
426++ def test_get_representor_port(self, mock__get_phys_switch_id,
427++ mock__get_phys_port_name,
428++ mock__get_pf_func,
429++ mock_listdir):
430+ mock_listdir.return_value = [
431+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
432+ ]
433+- mock_isfile.side_effect = [True, True]
434+- mock_open.return_value.__enter__ = lambda s: s
435+- readline_mock = mock_open.return_value.readline
436+- readline_mock.side_effect = (
437+- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', 'pf0vf2'])
438+- # PCI IDs mocked:
439+- # PF0: 0000:0a:00.0
440+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
441+- mock_get_function_by_ifname.side_effect = (
442+- [("0000:0a:00.0", True),
443+- ("0000:0a:02.1", False),
444+- ("0000:0a:02.2", False), ("0000:0a:00.0", True)])
445+- open_calls = (
446+- [mock.call('/sys/class/net/pf_ifname/phys_switch_id', 'r'),
447+- mock.call().readline(),
448+- mock.call().__exit__(None, None, None),
449+- mock.call('/sys/class/net/rep_vf_1/phys_switch_id', 'r'),
450+- mock.call().readline(),
451+- mock.call().__exit__(None, None, None),
452+- mock.call('/sys/class/net/rep_vf_1/phys_port_name', 'r'),
453+- mock.call().readline(),
454+- mock.call().__exit__(None, None, None),
455+- mock.call('/sys/class/net/rep_vf_2/phys_switch_id', 'r'),
456+- mock.call().readline(),
457+- mock.call().__exit__(None, None, None),
458+- mock.call('/sys/class/net/rep_vf_2/phys_port_name', 'r'),
459+- mock.call().readline(),
460+- mock.call().__exit__(None, None, None)])
461++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
462++ mock__get_pf_func.return_value = "0"
463++ mock__get_phys_port_name.side_effect = (['1', "pf0vf1", "pf0vf2"])
464+ ifname = linux_net.get_representor_port('pf_ifname', '2')
465+- mock_open.assert_has_calls(open_calls)
466+ self.assertEqual('rep_vf_2', ifname)
467+
468+- @mock.patch('six.moves.builtins.open')
469+- @mock.patch.object(os.path, 'isfile')
470+ @mock.patch.object(os, 'listdir')
471+- @mock.patch.object(linux_net, "get_function_by_ifname")
472++ @mock.patch.object(linux_net, "_get_pf_func")
473++ @mock.patch.object(linux_net, "_get_phys_port_name")
474++ @mock.patch.object(linux_net, "_get_phys_switch_id")
475+ def test_get_representor_port_2_pfs(
476+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
477+- mock_open):
478++ self, mock__get_phys_switch_id, mock__get_phys_port_name,
479++ mock__get_pf_func, mock_listdir):
480+ mock_listdir.return_value = [
481+ 'pf_ifname1', 'pf_ifname2', 'rep_pf1_vf_1', 'rep_pf1_vf_2',
482+ 'rep_pf2_vf_1', 'rep_pf2_vf_2',
483+ ]
484+- mock_isfile.side_effect = [True, True, True, True]
485+- mock_open.return_value.__enter__ = lambda s: s
486+- readline_mock = mock_open.return_value.readline
487+- readline_mock.side_effect = (
488+- ['pf_sw_id',
489+- 'pf_sw_id', 'VF1@PF1', 'pf_sw_id', 'vf2@pf1',
490+- 'pf_sw_id', 'pf2vf1', 'pf_sw_id', 'pf2vf2'])
491+- # PCI IDs mocked:
492+- # PF1: 0000:0a:00.1 PF2: 0000:0a:00.2
493+- # PF1VF1: 0000:0a:02.1 PF1VF2: 0000:0a:02.2
494+- # PF2VF1: 0000:0a:04.1 PF2VF2: 0000:0a:04.2
495+- mock_get_function_by_ifname.side_effect = (
496+- [("0000:0a:00.1", True), ("0000:0a:00.2", True),
497+- ("0000:0a:02.1", False), ("0000:0a:00.2", True),
498+- ("0000:0a:02.2", False), ("0000:0a:00.2", True),
499+- ("0000:0a:04.1", False), ("0000:0a:00.2", True),
500+- ("0000:0a:04.2", False), ("0000:0a:00.2", True)])
501++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
502++ mock__get_pf_func.return_value = "2"
503++ mock__get_phys_port_name.side_effect = (
504++ ["p1", "p2", "VF1@PF1", "pf2vf1", "vf2@pf1", "pf2vf2"])
505+ ifname = linux_net.get_representor_port('pf_ifname2', '2')
506+ self.assertEqual('rep_pf2_vf_2', ifname)
507+
508+- @mock.patch('six.moves.builtins.open')
509+- @mock.patch.object(os.path, 'isfile')
510+ @mock.patch.object(os, 'listdir')
511+- @mock.patch.object(linux_net, "get_function_by_ifname")
512++ @mock.patch.object(linux_net, "_get_pf_func")
513++ @mock.patch.object(linux_net, "_get_phys_switch_id")
514++ @mock.patch.object(linux_net, "_get_phys_port_name")
515+ def test_get_representor_port_not_found(
516+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
517+- mock_open):
518++ self, mock__get_phys_port_name, mock__get_phys_switch_id,
519++ mock__get_pf_func, mock_listdir):
520+ mock_listdir.return_value = [
521+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
522+ ]
523+- mock_isfile.side_effect = [True, True]
524+- mock_open.return_value.__enter__ = lambda s: s
525+- readline_mock = mock_open.return_value.readline
526+- readline_mock.side_effect = (
527+- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', '2'])
528+- # PCI IDs mocked:
529+- # PF0: 0000:0a:00.0
530+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
531+- mock_get_function_by_ifname.side_effect = (
532+- [("0000:0a:00.0", True),
533+- ("0000:0a:02.1", False),
534+- ("0000:0a:02.2", False)])
535++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
536++ mock__get_pf_func.return_value = "0"
537++ mock__get_phys_port_name.side_effect = (
538++ ["p0", "1", "2"])
539+ self.assertRaises(
540+ exception.RepresentorNotFound,
541+ linux_net.get_representor_port,
542+ 'pf_ifname', '3'),
543+
544+- @mock.patch('six.moves.builtins.open')
545+- @mock.patch.object(os.path, 'isfile')
546+ @mock.patch.object(os, 'listdir')
547+- @mock.patch.object(linux_net, "get_function_by_ifname")
548++ @mock.patch.object(linux_net, "_get_pf_func")
549++ @mock.patch.object(linux_net, "_get_phys_port_name")
550++ @mock.patch.object(linux_net, "_get_phys_switch_id")
551+ def test_get_representor_port_exception_io_error(
552+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
553+- mock_open):
554++ self, mock__get_phys_switch_id, mock__get_phys_port_name,
555++ mock__get_pf_func, mock_listdir):
556+ mock_listdir.return_value = [
557+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
558+ ]
559+- mock_isfile.side_effect = [True, True]
560+- mock_open.return_value.__enter__ = lambda s: s
561+- readline_mock = mock_open.return_value.readline
562+- readline_mock.side_effect = (
563++ mock__get_phys_switch_id.side_effect = (
564+ ['pf_sw_id', 'pf_sw_id', IOError(), 'pf_sw_id', '2'])
565+- # PCI IDs mocked:
566+- # PF0: 0000:0a:00.0
567+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
568+- mock_get_function_by_ifname.side_effect = (
569+- [("0000:0a:00.0", True),
570+- ("0000:0a:02.1", False),
571+- ("0000:0a:02.2", False), ("0000:0a:00.0", True)])
572++ mock__get_pf_func.return_value = "0"
573++ mock__get_phys_port_name.side_effect = (
574++ ["p0", "pf0vf0", "pf0vf1"])
575+ self.assertRaises(
576+ exception.RepresentorNotFound,
577+ linux_net.get_representor_port,
578+ 'pf_ifname', '3')
579+
580+- @mock.patch('six.moves.builtins.open')
581+- @mock.patch.object(os.path, 'isfile')
582+ @mock.patch.object(os, 'listdir')
583+- @mock.patch.object(linux_net, "get_function_by_ifname")
584++ @mock.patch.object(linux_net, "_get_pf_func")
585++ @mock.patch.object(linux_net, "_get_phys_port_name")
586++ @mock.patch.object(linux_net, "_get_phys_switch_id")
587+ def test_get_representor_port_exception_value_error(
588+- self, mock_get_function_by_ifname, mock_listdir, mock_isfile,
589+- mock_open):
590++ self, mock__get_phys_switch_id, mock__get_phys_port_name,
591++ mock__get_pf_func, mock_listdir):
592+ mock_listdir.return_value = [
593+ 'pf_ifname', 'rep_vf_1', 'rep_vf_2'
594+ ]
595+- mock_isfile.side_effect = [True, True]
596+- mock_open.return_value.__enter__ = lambda s: s
597+- readline_mock = mock_open.return_value.readline
598+- readline_mock.side_effect = (
599+- ['pf_sw_id', 'pf_sw_id', '1', 'pf_sw_id', 'a'])
600+- # PCI IDs mocked:
601+- # PF0: 0000:0a:00.0
602+- # PF0VF1: 0000:0a:02.1 PF0VF2: 0000:0a:02.2
603+- mock_get_function_by_ifname.side_effect = (
604+- [("0000:0a:00.0", True),
605+- ("0000:0a:02.1", False),
606+- ("0000:0a:02.2", False)])
607++ mock__get_phys_switch_id.return_value = 'pf_sw_id'
608++ mock__get_phys_port_name.side_effect = (['p0', '1', 'a'])
609++ mock__get_pf_func.return_value = "0"
610+ self.assertRaises(
611+ exception.RepresentorNotFound,
612+ linux_net.get_representor_port,
613+ 'pf_ifname', '3')
614+
615+- @mock.patch('six.moves.builtins.open')
616+- @mock.patch.object(os.path, 'isfile')
617+ @mock.patch.object(os, 'listdir')
618+- def test_physical_function_inferface_name(
619+- self, mock_listdir, mock_isfile, mock_open):
620++ @mock.patch.object(linux_net, '_get_phys_switch_id')
621++ def test_physical_function_interface_name(
622++ self, mock__get_phys_switch_id, mock_listdir):
623+ mock_listdir.return_value = ['foo', 'bar']
624+- mock_isfile.side_effect = [True, True]
625+- mock_open.return_value.__enter__ = lambda s: s
626+- readline_mock = mock_open.return_value.readline
627+- readline_mock.side_effect = (
628++ mock__get_phys_switch_id.side_effect = (
629+ ['', 'valid_switch'])
630+ ifname = linux_net.get_ifname_by_pci_address(
631+ '0000:00:00.1', pf_interface=True, switchdev=False)
632+ self.assertEqual(ifname, 'foo')
633+
634+- @mock.patch('six.moves.builtins.open')
635+- @mock.patch.object(os.path, 'isfile')
636+ @mock.patch.object(os, 'listdir')
637+- def test_physical_function_inferface_name_with_switchdev(
638+- self, mock_listdir, mock_isfile, mock_open):
639++ @mock.patch.object(linux_net, '_get_phys_switch_id')
640++ def test_physical_function_interface_name_with_switchdev(
641++ self, mock__get_phys_switch_id, mock_listdir):
642+ mock_listdir.return_value = ['foo', 'bar']
643+- mock_isfile.side_effect = [True, True]
644+- mock_open.return_value.__enter__ = lambda s: s
645+- readline_mock = mock_open.return_value.readline
646+- readline_mock.side_effect = (
647++ mock__get_phys_switch_id.side_effect = (
648+ ['', 'valid_switch'])
649+ ifname = linux_net.get_ifname_by_pci_address(
650+ '0000:00:00.1', pf_interface=True, switchdev=True)
651+@@ -419,3 +325,35 @@ class LinuxNetTest(testtools.TestCase):
652+ linux_net.get_vf_num_by_pci_address,
653+ '0000:00:00.1'
654+ )
655++
656++ @mock.patch('builtins.open')
657++ @mock.patch.object(os.path, 'isfile')
658++ def test__get_phys_port_name(self, mock_isfile, mock_open):
659++ mock_open.return_value.__enter__ = lambda s: s
660++ readline_mock = mock_open.return_value.readline
661++ readline_mock.return_value = 'pf0vf0'
662++ mock_isfile.return_value = True
663++ phys_port_name = linux_net._get_phys_port_name("vf_ifname")
664++ self.assertEqual(phys_port_name, 'pf0vf0')
665++
666++ @mock.patch.object(os.path, 'isfile')
667++ def test__get_phys_port_name_not_found(self, mock_isfile):
668++ mock_isfile.return_value = False
669++ phys_port_name = linux_net._get_phys_port_name("vf_ifname")
670++ self.assertIsNone(phys_port_name)
671++
672++ @mock.patch('builtins.open')
673++ @mock.patch.object(os.path, 'isfile')
674++ def test__get_phys_switch_id(self, mock_isfile, mock_open):
675++ mock_open.return_value.__enter__ = lambda s: s
676++ readline_mock = mock_open.return_value.readline
677++ readline_mock.return_value = '66e40000039b0398'
678++ mock_isfile.return_value = True
679++ phys_port_name = linux_net._get_phys_switch_id("ifname")
680++ self.assertEqual(phys_port_name, '66e40000039b0398')
681++
682++ @mock.patch.object(os.path, 'isfile')
683++ def test__get_phys_switch_id_not_found(self, mock_isfile):
684++ mock_isfile.return_value = False
685++ phys_port_name = linux_net._get_phys_switch_id("ifname")
686++ self.assertIsNone(phys_port_name)
687+--
688+2.31.1
689diff --git a/debian/patches/series b/debian/patches/series
690new file mode 100644
691index 0000000..2467eb6
692--- /dev/null
693+++ b/debian/patches/series
694@@ -0,0 +1,2 @@
695+Refactor-code-of-linux_net-to-more-cleaner-and-increase-performace.patch
696+Fix-os-vif-fails-to-get-the-correct-UpLink-Representor.patch

Subscribers

People subscribed via source and target branches