Blame SOURCES/BZ_1931290-SRIOV-Remove-VF-interface-when-total-vfs-decrease.patch

520691
From c55d39e8485a26490afc36d71fd9d20528ab6fd2 Mon Sep 17 00:00:00 2001
520691
From: Gris Ge <fge@redhat.com>
520691
Date: Thu, 18 Feb 2021 18:01:17 +0800
520691
Subject: [PATCH 1/5] SRIOV: Remove VF interface when total-vfs decrease
520691
520691
When `Ethernet.SRIOV.TOTAL_VFS` decrease, we should mark removed VF
520691
interface as absent.
520691
520691
Both integration and unit test cases have been include.
520691
The integration test has been tested on real SRIOV hardware.
520691
520691
Signed-off-by: Gris Ge <fge@redhat.com>
520691
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
520691
---
520691
 libnmstate/ifaces/base_iface.py |  5 +++++
520691
 libnmstate/ifaces/ethernet.py   | 20 ++++++++++++++++++
520691
 libnmstate/ifaces/ifaces.py     | 24 +++++++++++++++++++++
520691
 tests/integration/sriov_test.py | 37 +++++++++++++++++++++++++++++++++
520691
 4 files changed, 86 insertions(+)
520691
520691
diff --git a/libnmstate/ifaces/base_iface.py b/libnmstate/ifaces/base_iface.py
520691
index 564d583a..b4ade867 100644
520691
--- a/libnmstate/ifaces/base_iface.py
520691
+++ b/libnmstate/ifaces/base_iface.py
520691
@@ -177,6 +177,11 @@ class BaseIface:
520691
     def mark_as_desired(self):
520691
         self._is_desired = True
520691
 
520691
+    def mark_as_absent_by_desire(self):
520691
+        self.mark_as_desired()
520691
+        self._info[Interface.STATE] = InterfaceState.ABSENT
520691
+        self._origin_info[Interface.STATE] = InterfaceState.ABSENT
520691
+
520691
     def to_dict(self):
520691
         return deepcopy(self._info)
520691
 
520691
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
520691
index 644fe6dd..3e1bdc5d 100644
520691
--- a/libnmstate/ifaces/ethernet.py
520691
+++ b/libnmstate/ifaces/ethernet.py
520691
@@ -74,6 +74,26 @@ class EthernetIface(BaseIface):
520691
             for i in range(0, self.sriov_total_vfs)
520691
         ]
520691
 
520691
+    def remove_vfs_entry_when_total_vfs_decreased(self):
520691
+        vfs_count = len(
520691
+            self._info[Ethernet.CONFIG_SUBTREE]
520691
+            .get(Ethernet.SRIOV_SUBTREE, {})
520691
+            .get(Ethernet.SRIOV.VFS_SUBTREE, [])
520691
+        )
520691
+        if vfs_count > self.sriov_total_vfs:
520691
+            [
520691
+                self._info[Ethernet.CONFIG_SUBTREE][Ethernet.SRIOV_SUBTREE][
520691
+                    Ethernet.SRIOV.VFS_SUBTREE
520691
+                ].pop()
520691
+                for _ in range(self.sriov_total_vfs, vfs_count)
520691
+            ]
520691
+
520691
+    def get_delete_vf_interface_names(self, old_sriov_total_vfs):
520691
+        return [
520691
+            f"{self.name}v{i}"
520691
+            for i in range(self.sriov_total_vfs, old_sriov_total_vfs)
520691
+        ]
520691
+
520691
 
520691
 def _capitalize_sriov_vf_mac(state):
520691
     vfs = (
520691
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
520691
index ee75125d..67ab91c4 100644
520691
--- a/libnmstate/ifaces/ifaces.py
520691
+++ b/libnmstate/ifaces/ifaces.py
520691
@@ -99,6 +99,7 @@ class Ifaces:
520691
             self._create_virtual_slaves()
520691
             self._create_sriov_vfs_when_changed()
520691
             self._validate_unknown_slaves()
520691
+            self._mark_vf_interface_as_absent_when_sriov_vf_decrease()
520691
             self._validate_unknown_parent()
520691
             self._gen_metadata()
520691
             for iface in self._ifaces.values():
520691
@@ -147,6 +148,29 @@ class Ifaces:
520691
         for new_iface in new_ifaces:
520691
             self._ifaces[new_iface.name] = new_iface
520691
 
520691
+    def _mark_vf_interface_as_absent_when_sriov_vf_decrease(self):
520691
+        """
520691
+        When SRIOV TOTAL_VFS decreased, we should mark certain VF interfaces
520691
+        as absent and also remove the entry in `Ethernet.SRIOV.VFS_SUBTREE`.
520691
+        """
520691
+        for iface_name, iface in self._ifaces.items():
520691
+            if iface.type != InterfaceType.ETHERNET or not iface.is_up:
520691
+                continue
520691
+            if iface_name not in self.current_ifaces:
520691
+                continue
520691
+            cur_iface = self.current_ifaces[iface_name]
520691
+            if (
520691
+                cur_iface.sriov_total_vfs != 0
520691
+                and iface.sriov_total_vfs < cur_iface.sriov_total_vfs
520691
+            ):
520691
+                iface.remove_vfs_entry_when_total_vfs_decreased()
520691
+                for vf_name in iface.get_delete_vf_interface_names(
520691
+                    cur_iface.sriov_total_vfs
520691
+                ):
520691
+                    vf_iface = self._ifaces.get(vf_name)
520691
+                    if vf_iface:
520691
+                        vf_iface.mark_as_absent_by_desire()
520691
+
520691
     def _pre_edit_validation_and_cleanup(self):
520691
         self._validate_over_booked_slaves()
520691
         self._validate_vlan_mtu()
520691
-- 
520691
2.29.2
520691