|
|
2bf224 |
From d410b928c8f2a22d42d1974b62ab5b3164861184 Mon Sep 17 00:00:00 2001
|
|
|
2bf224 |
From: Gris Ge <fge@redhat.com>
|
|
|
2bf224 |
Date: Thu, 23 Feb 2023 13:06:01 +0800
|
|
|
2bf224 |
Subject: [PATCH] nm: Fix error on SR-IOV
|
|
|
2bf224 |
|
|
|
2bf224 |
When SR-IOV VF naming scheme is like `ens1f0v0`, nmstate will delete
|
|
|
2bf224 |
the VF NM connection when applying this state:
|
|
|
2bf224 |
|
|
|
2bf224 |
```yml
|
|
|
2bf224 |
---
|
|
|
2bf224 |
interfaces:
|
|
|
2bf224 |
- name: ens1f0
|
|
|
2bf224 |
type: ethernet
|
|
|
2bf224 |
state: up
|
|
|
2bf224 |
ethernet:
|
|
|
2bf224 |
sr-iov:
|
|
|
2bf224 |
total-vfs: 1
|
|
|
2bf224 |
- name: ens1f0v0
|
|
|
2bf224 |
type: ethernet
|
|
|
2bf224 |
state: up
|
|
|
2bf224 |
ipv4:
|
|
|
2bf224 |
enabled: false
|
|
|
2bf224 |
ipv6:
|
|
|
2bf224 |
enabled: false
|
|
|
2bf224 |
```
|
|
|
2bf224 |
|
|
|
2bf224 |
This is because `delete_other_profiles()` is checking
|
|
|
2bf224 |
`self._nm_profile()` from active NM profile instead of newly created
|
|
|
2bf224 |
one. The fix is using newly created profile `self._nm_simple_conn`.
|
|
|
2bf224 |
|
|
|
2bf224 |
We also have race problem when activating PF along with VF, PF
|
|
|
2bf224 |
activation might delete VF NIC which cause VF activation failed. To
|
|
|
2bf224 |
workaround that, we activate PF first via `NmProfile.ACTION_SRIOV_PF`
|
|
|
2bf224 |
and wait on it before start VF activation.
|
|
|
2bf224 |
|
|
|
2bf224 |
Also problem found during SR-IOV investigations is we do extra
|
|
|
2bf224 |
un-required modification to `NM.SettingOvsExternalIDs` even it is not
|
|
|
2bf224 |
mentioned in desired. We skip overriding `NM.SettingOvsExternalIDs` when
|
|
|
2bf224 |
not desired.
|
|
|
2bf224 |
|
|
|
2bf224 |
Existing test case can cover the use cases.
|
|
|
2bf224 |
|
|
|
2bf224 |
Signed-off-by: Gris Ge <fge@redhat.com>
|
|
|
2bf224 |
---
|
|
|
2bf224 |
libnmstate/ifaces/ifaces.py | 18 +++++++++++++++++-
|
|
|
2bf224 |
libnmstate/netapplier.py | 20 +++++++++++---------
|
|
|
2bf224 |
libnmstate/nm/connection.py | 2 +-
|
|
|
2bf224 |
libnmstate/nm/profile.py | 12 ++++++++++--
|
|
|
2bf224 |
4 files changed, 39 insertions(+), 13 deletions(-)
|
|
|
2bf224 |
|
|
|
2bf224 |
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
|
|
|
2bf224 |
index 828ff578..470dc0e6 100644
|
|
|
2bf224 |
--- a/libnmstate/ifaces/ifaces.py
|
|
|
2bf224 |
+++ b/libnmstate/ifaces/ifaces.py
|
|
|
2bf224 |
@@ -157,6 +157,23 @@ class Ifaces:
|
|
|
2bf224 |
def has_vf_count_change_and_missing_eth(self):
|
|
|
2bf224 |
return self._has_vf_count_change() and self._has_missing_veth()
|
|
|
2bf224 |
|
|
|
2bf224 |
+ def has_sriov_iface(self):
|
|
|
2bf224 |
+ for iface in self.all_kernel_ifaces.values():
|
|
|
2bf224 |
+ if (iface.is_desired or iface.is_changed) and iface.is_up:
|
|
|
2bf224 |
+ cur_iface = self._cur_kernel_ifaces.get(iface.name)
|
|
|
2bf224 |
+ if (
|
|
|
2bf224 |
+ cur_iface
|
|
|
2bf224 |
+ and cur_iface.raw.get(Ethernet.CONFIG_SUBTREE, {}).get(
|
|
|
2bf224 |
+ Ethernet.SRIOV_SUBTREE, {}
|
|
|
2bf224 |
+ )
|
|
|
2bf224 |
+ ) or iface.original_desire_dict.get(
|
|
|
2bf224 |
+ Ethernet.CONFIG_SUBTREE, {}
|
|
|
2bf224 |
+ ).get(
|
|
|
2bf224 |
+ Ethernet.SRIOV_SUBTREE, {}
|
|
|
2bf224 |
+ ):
|
|
|
2bf224 |
+ return True
|
|
|
2bf224 |
+ return False
|
|
|
2bf224 |
+
|
|
|
2bf224 |
def _has_vf_count_change(self):
|
|
|
2bf224 |
for iface in self.all_kernel_ifaces.values():
|
|
|
2bf224 |
cur_iface = self._cur_kernel_ifaces.get(iface.name)
|
|
|
2bf224 |
@@ -664,7 +681,6 @@ class Ifaces:
|
|
|
2bf224 |
return None
|
|
|
2bf224 |
|
|
|
2bf224 |
def get_cur_iface(self, iface_name, iface_type):
|
|
|
2bf224 |
-
|
|
|
2bf224 |
iface = self._cur_kernel_ifaces.get(iface_name)
|
|
|
2bf224 |
if iface and iface_type in (None, InterfaceType.UNKNOWN, iface.type):
|
|
|
2bf224 |
return iface
|
|
|
2bf224 |
diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py
|
|
|
2bf224 |
index ae909126..50a70a9c 100644
|
|
|
2bf224 |
--- a/libnmstate/netapplier.py
|
|
|
2bf224 |
+++ b/libnmstate/netapplier.py
|
|
|
2bf224 |
@@ -104,7 +104,7 @@ def apply(
|
|
|
2bf224 |
pf_net_state,
|
|
|
2bf224 |
verify_change,
|
|
|
2bf224 |
save_to_disk,
|
|
|
2bf224 |
- has_sriov_pf=True,
|
|
|
2bf224 |
+ VERIFY_RETRY_COUNT_SRIOV,
|
|
|
2bf224 |
)
|
|
|
2bf224 |
# Refresh the current state
|
|
|
2bf224 |
current_state = show_with_plugins(
|
|
|
2bf224 |
@@ -120,8 +120,16 @@ def apply(
|
|
|
2bf224 |
current_state,
|
|
|
2bf224 |
save_to_disk,
|
|
|
2bf224 |
)
|
|
|
2bf224 |
+
|
|
|
2bf224 |
+ if net_state.ifaces.has_sriov_iface():
|
|
|
2bf224 |
+ # If SR-IOV is present, the verification timeout is being increased
|
|
|
2bf224 |
+ # to avoid timeouts due to slow drivers like i40e.
|
|
|
2bf224 |
+ verify_retry = VERIFY_RETRY_COUNT_SRIOV
|
|
|
2bf224 |
+ else:
|
|
|
2bf224 |
+ verify_retry = VERIFY_RETRY_COUNT
|
|
|
2bf224 |
+
|
|
|
2bf224 |
_apply_ifaces_state(
|
|
|
2bf224 |
- plugins, net_state, verify_change, save_to_disk, has_sriov_pf=False
|
|
|
2bf224 |
+ plugins, net_state, verify_change, save_to_disk, verify_retry
|
|
|
2bf224 |
)
|
|
|
2bf224 |
if commit:
|
|
|
2bf224 |
destroy_checkpoints(plugins, checkpoints)
|
|
|
2bf224 |
@@ -154,7 +162,7 @@ def rollback(*, checkpoint=None):
|
|
|
2bf224 |
|
|
|
2bf224 |
|
|
|
2bf224 |
def _apply_ifaces_state(
|
|
|
2bf224 |
- plugins, net_state, verify_change, save_to_disk, has_sriov_pf=False
|
|
|
2bf224 |
+ plugins, net_state, verify_change, save_to_disk, verify_retry
|
|
|
2bf224 |
):
|
|
|
2bf224 |
for plugin in plugins:
|
|
|
2bf224 |
# Do not allow plugin to modify the net_state for future verification
|
|
|
2bf224 |
@@ -163,12 +171,6 @@ def _apply_ifaces_state(
|
|
|
2bf224 |
|
|
|
2bf224 |
verified = False
|
|
|
2bf224 |
if verify_change:
|
|
|
2bf224 |
- if has_sriov_pf:
|
|
|
2bf224 |
- # If SR-IOV is present, the verification timeout is being increased
|
|
|
2bf224 |
- # to avoid timeouts due to slow drivers like i40e.
|
|
|
2bf224 |
- verify_retry = VERIFY_RETRY_COUNT_SRIOV
|
|
|
2bf224 |
- else:
|
|
|
2bf224 |
- verify_retry = VERIFY_RETRY_COUNT
|
|
|
2bf224 |
for _ in range(verify_retry):
|
|
|
2bf224 |
try:
|
|
|
2bf224 |
_verify_change(plugins, net_state)
|
|
|
2bf224 |
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
|
|
|
2bf224 |
index 1fbb380b..6448e372 100644
|
|
|
2bf224 |
--- a/libnmstate/nm/connection.py
|
|
|
2bf224 |
+++ b/libnmstate/nm/connection.py
|
|
|
2bf224 |
@@ -240,7 +240,7 @@ def create_new_nm_simple_conn(iface, nm_profile):
|
|
|
2bf224 |
InterfaceType.OVS_PORT,
|
|
|
2bf224 |
)
|
|
|
2bf224 |
or iface.type == InterfaceType.OVS_BRIDGE
|
|
|
2bf224 |
- ):
|
|
|
2bf224 |
+ ) and OvsDB.OVS_DB_SUBTREE in iface.original_desire_dict:
|
|
|
2bf224 |
nm_setting = create_ovsdb_external_ids_setting(
|
|
|
2bf224 |
iface_info.get(OvsDB.OVS_DB_SUBTREE, {})
|
|
|
2bf224 |
)
|
|
|
2bf224 |
diff --git a/libnmstate/nm/profile.py b/libnmstate/nm/profile.py
|
|
|
2bf224 |
index 53eaebed..ad1ad19f 100644
|
|
|
2bf224 |
--- a/libnmstate/nm/profile.py
|
|
|
2bf224 |
+++ b/libnmstate/nm/profile.py
|
|
|
2bf224 |
@@ -56,6 +56,7 @@ ROUTE_REMOVED = "_route_removed"
|
|
|
2bf224 |
class NmProfile:
|
|
|
2bf224 |
# For unmanged iface and desired to down
|
|
|
2bf224 |
ACTION_ACTIVATE_FIRST = "activate_first"
|
|
|
2bf224 |
+ ACTION_SRIOV_PF = "activate_sriov_pf"
|
|
|
2bf224 |
ACTION_DEACTIVATE = "deactivate"
|
|
|
2bf224 |
ACTION_DEACTIVATE_FIRST = "deactivate_first"
|
|
|
2bf224 |
ACTION_DELETE_DEVICE = "delete_device"
|
|
|
2bf224 |
@@ -77,6 +78,7 @@ class NmProfile:
|
|
|
2bf224 |
ACTION_ACTIVATE_FIRST,
|
|
|
2bf224 |
ACTION_DEACTIVATE_FIRST,
|
|
|
2bf224 |
ACTION_TOP_CONTROLLER,
|
|
|
2bf224 |
+ ACTION_SRIOV_PF,
|
|
|
2bf224 |
ACTION_NEW_IFACES,
|
|
|
2bf224 |
ACTION_OTHER_CONTROLLER,
|
|
|
2bf224 |
ACTION_NEW_OVS_PORT,
|
|
|
2bf224 |
@@ -181,6 +183,11 @@ class NmProfile:
|
|
|
2bf224 |
else:
|
|
|
2bf224 |
self._add_action(NmProfile.ACTION_NEW_IFACES)
|
|
|
2bf224 |
else:
|
|
|
2bf224 |
+ if (
|
|
|
2bf224 |
+ self._nm_dev.props.capabilities
|
|
|
2bf224 |
+ & NM.DeviceCapabilities.SRIOV
|
|
|
2bf224 |
+ ):
|
|
|
2bf224 |
+ self._add_action(NmProfile.ACTION_SRIOV_PF)
|
|
|
2bf224 |
if self._iface.type == InterfaceType.OVS_PORT:
|
|
|
2bf224 |
self._add_action(NmProfile.ACTION_MODIFIED_OVS_PORT)
|
|
|
2bf224 |
if self._iface.type == InterfaceType.OVS_INTERFACE:
|
|
|
2bf224 |
@@ -462,6 +469,7 @@ class NmProfile:
|
|
|
2bf224 |
|
|
|
2bf224 |
def do_action(self, action):
|
|
|
2bf224 |
if action in (
|
|
|
2bf224 |
+ NmProfile.ACTION_SRIOV_PF,
|
|
|
2bf224 |
NmProfile.ACTION_MODIFIED,
|
|
|
2bf224 |
NmProfile.ACTION_MODIFIED_OVS_PORT,
|
|
|
2bf224 |
NmProfile.ACTION_MODIFIED_OVS_IFACE,
|
|
|
2bf224 |
@@ -559,8 +567,8 @@ class NmProfile:
|
|
|
2bf224 |
or nm_profile.get_connection_type() == self._nm_iface_type
|
|
|
2bf224 |
)
|
|
|
2bf224 |
and (
|
|
|
2bf224 |
- self._nm_profile is None
|
|
|
2bf224 |
- or nm_profile.get_uuid() != self._nm_profile.get_uuid()
|
|
|
2bf224 |
+ self._nm_simple_conn is None
|
|
|
2bf224 |
+ or nm_profile.get_uuid() != self._nm_simple_conn.get_uuid()
|
|
|
2bf224 |
)
|
|
|
2bf224 |
):
|
|
|
2bf224 |
ProfileDelete(
|
|
|
2bf224 |
--
|
|
|
2bf224 |
2.39.2
|
|
|
2bf224 |
|