Blob Blame History Raw
From afb3f2dfeb5364e8a9a0bde4ad9062f1585a8795 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Mon, 22 Feb 2021 12:03:11 +0100
Subject: [PATCH 3/5] SR-IOV: increase the verification timeout if SR-IOV is
 present

Certain drivers like i40e take a long time to modify the VFs in the
kernel. Nmstate is timing out on verification because of that. In order
to fix this, nmstate is incresing the verification time if SR-IOV is
present on the desired state.

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
 libnmstate/ifaces/ethernet.py |  5 +++++
 libnmstate/ifaces/ifaces.py   |  4 ++++
 libnmstate/netapplier.py      | 18 +++++++++++++++++-
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
index f1ece5f5..1c3ca266 100644
--- a/libnmstate/ifaces/ethernet.py
+++ b/libnmstate/ifaces/ethernet.py
@@ -67,6 +67,11 @@ class EthernetIface(BaseIface):
     def mark_as_new_sr_iov_vf(self):
         self.raw[IS_NEW_SR_IOV_VF] = True
 
+    def is_sriov(self):
+        return self.raw.get(Ethernet.CONFIG_SUBTREE, {}).get(
+            Ethernet.SRIOV_SUBTREE, {}
+        )
+
     def create_sriov_vf_ifaces(self):
         return [
             EthernetIface(
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index a7af9712..b212ebb5 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -325,6 +325,10 @@ class Ifaces:
     def current_ifaces(self):
         return self._cur_ifaces
 
+    @property
+    def all_ifaces(self):
+        return self._ifaces
+
     @property
     def state_to_edit(self):
         return [
diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py
index 24df4d56..6aa1ac07 100644
--- a/libnmstate/netapplier.py
+++ b/libnmstate/netapplier.py
@@ -23,6 +23,7 @@ import time
 
 from libnmstate import validator
 from libnmstate.error import NmstateVerificationError
+from libnmstate.schema import InterfaceType
 
 from .nmstate import create_checkpoints
 from .nmstate import destroy_checkpoints
@@ -35,6 +36,7 @@ from .net_state import NetState
 MAINLOOP_TIMEOUT = 35
 VERIFY_RETRY_INTERNAL = 1
 VERIFY_RETRY_TIMEOUT = 5
+VERIFY_RETRY_TIMEOUT_INCREASE = 4
 
 
 def apply(
@@ -104,7 +106,13 @@ def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
         plugin.apply_changes(net_state, save_to_disk)
     verified = False
     if verify_change:
-        for _ in range(VERIFY_RETRY_TIMEOUT):
+        if _net_state_contains_sriov_interface(net_state):
+            # If SR-IOV is present, the verification timeout is being increased
+            # to avoid timeouts due to slow drivers like i40e.
+            verify_retry = VERIFY_RETRY_TIMEOUT * VERIFY_RETRY_TIMEOUT_INCREASE
+        else:
+            verify_retry = VERIFY_RETRY_TIMEOUT
+        for _ in range(verify_retry):
             try:
                 _verify_change(plugins, net_state)
                 verified = True
@@ -115,6 +123,14 @@ def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
             _verify_change(plugins, net_state)
 
 
+def _net_state_contains_sriov_interface(net_state):
+    for iface in net_state.ifaces.all_ifaces.values():
+        if iface.type == InterfaceType.ETHERNET and iface.is_sriov:
+            return True
+
+    return False
+
+
 def _verify_change(plugins, net_state):
     current_state = show_with_plugins(plugins)
     net_state.verify(current_state)
-- 
2.29.2