From a43609607abe30b973f1cb78cb1754f1a9a91514 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Mon, 22 Feb 2021 13:33:06 +0100 Subject: [PATCH 4/5] SR-IOV: fail on verification if `total_vfs` does not match vfs len Signed-off-by: Fernando Fernandez Mancera --- libnmstate/ifaces/ethernet.py | 11 +++++++++++ libnmstate/ifaces/ifaces.py | 17 +++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py index 1c3ca266..4903bde7 100644 --- a/libnmstate/ifaces/ethernet.py +++ b/libnmstate/ifaces/ethernet.py @@ -52,6 +52,14 @@ class EthernetIface(BaseIface): _capitalize_sriov_vf_mac(state) return state + @property + def sriov_vfs(self): + return ( + self.raw.get(Ethernet.CONFIG_SUBTREE, {}) + .get(Ethernet.SRIOV_SUBTREE, {}) + .get(Ethernet.SRIOV.VFS_SUBTREE, {}) + ) + @property def sriov_total_vfs(self): return ( @@ -109,6 +117,9 @@ class EthernetIface(BaseIface): for i in range(self.sriov_total_vfs, old_sriov_total_vfs) ] + def check_total_vfs_matches_vf_list(self, total_vfs): + return total_vfs == len(self.sriov_vfs) + def _capitalize_sriov_vf_mac(state): vfs = ( diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py index b212ebb5..1d30d0c6 100644 --- a/libnmstate/ifaces/ifaces.py +++ b/libnmstate/ifaces/ifaces.py @@ -146,6 +146,11 @@ class Ifaces: new_iface.mark_as_desired() new_iface.mark_as_new_sr_iov_vf() new_ifaces.append(new_iface) + else: + # When the VFs are being modified, all VFs link are + # being removed from kernel and created again. Nmstate + # must verify they have been created. + self._ifaces[new_iface.name].mark_as_desired() for new_iface in new_ifaces: self._ifaces[new_iface.name] = new_iface @@ -403,6 +408,18 @@ class Ifaces: cur_iface.state_for_verify(), ) ) + elif ( + iface.type == InterfaceType.ETHERNET and iface.is_sriov + ): + if not cur_iface.check_total_vfs_matches_vf_list( + iface.sriov_total_vfs + ): + raise NmstateVerificationError( + "The NIC exceeded the waiting time for " + "verification and it is failing because " + "the `total_vfs` does not match the VF " + "list length." + ) def gen_dns_metadata(self, dns_state, route_state): iface_metadata = dns_state.gen_metadata(self, route_state) -- 2.29.2