Skip to content

Commit

Permalink
Remove old switchdev implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Yury Kulazhenkov <[email protected]>
  • Loading branch information
ykulazhenkov committed Feb 27, 2024
1 parent 3037cee commit 168086e
Show file tree
Hide file tree
Showing 9 changed files with 27 additions and 250 deletions.
25 changes: 0 additions & 25 deletions bindata/scripts/load-udev.sh

This file was deleted.

91 changes: 4 additions & 87 deletions pkg/daemon/daemon.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package daemon

import (
"bytes"
"context"
"encoding/json"
"fmt"
"math/rand"
"os"
"os/exec"
"path"
"strconv"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -108,11 +103,10 @@ type Daemon struct {
}

const (
udevScriptsPath = "/bindata/scripts/load-udev.sh"
annoKey = "sriovnetwork.openshift.io/state"
annoIdle = "Idle"
annoDraining = "Draining"
annoMcpPaused = "Draining_MCP_Paused"
annoKey = "sriovnetwork.openshift.io/state"
annoIdle = "Idle"
annoDraining = "Draining"
annoMcpPaused = "Draining_MCP_Paused"
)

// writer implements io.Writer interface as a pass-through for log.Log.
Expand Down Expand Up @@ -207,9 +201,6 @@ func (dn *Daemon) Run(stopCh <-chan struct{}, exitCh <-chan error) error {
if err := dn.HostHelpers.PrepareVFRepUdevRule(); err != nil {
log.Log.Error(err, "failed to prepare udev files to rename VF representors for requested VFs")
}
if err := dn.tryCreateSwitchdevUdevRule(); err != nil {
log.Log.Error(err, "failed to create udev files for switchdev")
}

var timeout int64 = 5
var metadataKey = "metadata.name"
Expand Down Expand Up @@ -282,11 +273,6 @@ func (dn *Daemon) Run(stopCh <-chan struct{}, exitCh <-chan error) error {
}
}
return err
case <-time.After(30 * time.Second):
log.Log.V(2).Info("Run(): period refresh")
if err := dn.tryCreateSwitchdevUdevRule(); err != nil {
log.Log.V(2).Error(err, "Could not create udev rule")
}
}
}
}
Expand Down Expand Up @@ -1067,75 +1053,6 @@ func (dn *Daemon) drainNode() error {
return nil
}

// TODO: move this to host interface
func (dn *Daemon) tryCreateSwitchdevUdevRule() error {
log.Log.V(2).Info("tryCreateSwitchdevUdevRule()")
nodeState, nodeStateErr := dn.client.SriovnetworkV1().SriovNetworkNodeStates(vars.Namespace).Get(
context.Background(),
vars.NodeName,
metav1.GetOptions{},
)
if nodeStateErr != nil {
log.Log.Error(nodeStateErr, "could not fetch node state, skip updating switchdev udev rules", "name", vars.NodeName)
return nil
}

var newContent string
filePath := path.Join(vars.FilesystemRoot, "/host/etc/udev/rules.d/20-switchdev.rules")

for _, ifaceStatus := range nodeState.Status.Interfaces {
if ifaceStatus.EswitchMode == sriovnetworkv1.ESwithModeSwitchDev {
switchID, err := dn.HostHelpers.GetPhysSwitchID(ifaceStatus.Name)
if err != nil {
return err
}
portName, err := dn.HostHelpers.GetPhysPortName(ifaceStatus.Name)
if err != nil {
return err
}
newContent = newContent + fmt.Sprintf("SUBSYSTEM==\"net\", ACTION==\"add|move\", ATTRS{phys_switch_id}==\"%s\", ATTR{phys_port_name}==\"pf%svf*\", IMPORT{program}=\"/etc/udev/switchdev-vf-link-name.sh $attr{phys_port_name}\", NAME=\"%s_$env{NUMBER}\"\n", switchID, strings.TrimPrefix(portName, "p"), ifaceStatus.Name)
}
}

oldContent, err := os.ReadFile(filePath)
// if oldContent = newContent, don't do anything
if err == nil && newContent == string(oldContent) {
return nil
}

log.Log.V(2).Info("Old udev content and new content differ. Writing new content to file.",
"old-content", strings.TrimSuffix(string(oldContent), "\n"),
"new-content", strings.TrimSuffix(newContent, "\n"),
"path", filePath)

// if the file does not exist or if oldContent != newContent
// write to file and create it if it doesn't exist
err = os.WriteFile(filePath, []byte(newContent), 0664)
if err != nil {
log.Log.Error(err, "tryCreateSwitchdevUdevRule(): fail to write file")
return err
}

var stdout, stderr bytes.Buffer
cmd := exec.Command("/bin/bash", path.Join(vars.FilesystemRoot, udevScriptsPath))
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
return err
}
log.Log.V(2).Info("tryCreateSwitchdevUdevRule(): stdout", "output", cmd.Stdout)

i, err := strconv.Atoi(strings.TrimSpace(stdout.String()))
if err == nil {
if i == 0 {
log.Log.V(2).Info("tryCreateSwitchdevUdevRule(): switchdev udev rules loaded")
} else {
log.Log.V(2).Info("tryCreateSwitchdevUdevRule(): switchdev udev rules not loaded")
}
}
return nil
}

func (dn *Daemon) prepareNMUdevRule() error {
// we need to remove the Red Hat Virtio network device from the udev rule configuration
// if we don't remove it when running the config-daemon on a virtual node it will disconnect the node after a reboot
Expand Down
23 changes: 4 additions & 19 deletions pkg/helper/mock/mock_helper.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 5 additions & 11 deletions pkg/host/internal/sriov/sriov.go
Original file line number Diff line number Diff line change
Expand Up @@ -581,13 +581,13 @@ func (s *sriov) configSriovDevice(iface *sriovnetworkv1.Interface, skipVFConfigu
}

func (s *sriov) ConfigSriovInterfaces(storeManager store.ManagerInterface,
interfaces []sriovnetworkv1.Interface, ifaceStatuses []sriovnetworkv1.InterfaceExt, pfsToConfig map[string]bool, skipVFConfiguration bool) error {
interfaces []sriovnetworkv1.Interface, ifaceStatuses []sriovnetworkv1.InterfaceExt, skipVFConfiguration bool) error {
if s.kernelHelper.IsKernelLockdownMode() && mlx.HasMellanoxInterfacesInSpec(ifaceStatuses, interfaces) {
log.Log.Error(nil, "cannot use mellanox devices when in kernel lockdown mode")
return fmt.Errorf("cannot use mellanox devices when in kernel lockdown mode")
}

toBeConfigured, toBeResetted, err := s.getConfigureAndReset(storeManager, interfaces, ifaceStatuses, pfsToConfig)
toBeConfigured, toBeResetted, err := s.getConfigureAndReset(storeManager, interfaces, ifaceStatuses)
if err != nil {
log.Log.Error(err, "cannot get a list of interfaces to configure")
return fmt.Errorf("cannot get a list of interfaces to configure")
Expand Down Expand Up @@ -615,19 +615,15 @@ func (s *sriov) ConfigSriovInterfaces(storeManager store.ManagerInterface,
return nil
}

func (s *sriov) getConfigureAndReset(storeManager store.ManagerInterface, interfaces []sriovnetworkv1.Interface, ifaceStatuses []sriovnetworkv1.InterfaceExt, pfsToConfig map[string]bool) ([]interfaceToConfigure, []sriovnetworkv1.InterfaceExt, error) {
func (s *sriov) getConfigureAndReset(storeManager store.ManagerInterface, interfaces []sriovnetworkv1.Interface,
ifaceStatuses []sriovnetworkv1.InterfaceExt) ([]interfaceToConfigure, []sriovnetworkv1.InterfaceExt, error) {
toBeConfigured := []interfaceToConfigure{}
toBeResetted := []sriovnetworkv1.InterfaceExt{}
for _, ifaceStatus := range ifaceStatuses {
configured := false
for _, iface := range interfaces {
if iface.PciAddress == ifaceStatus.PciAddress {
configured = true

if skip := pfsToConfig[iface.PciAddress]; skip {
break
}

skip, err := skipSriovConfig(&iface, &ifaceStatus, storeManager)
if err != nil {
log.Log.Error(err, "getConfigureAndReset(): failed to check interface")
Expand All @@ -643,9 +639,7 @@ func (s *sriov) getConfigureAndReset(storeManager store.ManagerInterface, interf
}

if !configured && ifaceStatus.NumVfs > 0 {
if skip := pfsToConfig[ifaceStatus.PciAddress]; !skip {
toBeResetted = append(toBeResetted, ifaceStatus)
}
toBeResetted = append(toBeResetted, ifaceStatus)
}
}
return toBeConfigured, toBeResetted, nil
Expand Down
18 changes: 8 additions & 10 deletions pkg/host/internal/sriov/sriov_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ var _ = Describe("SRIOV", func() {
}},
}},
[]sriovnetworkv1.InterfaceExt{{PciAddress: "0000:d8:00.0"}, {PciAddress: "0000:d8:00.1"}},
map[string]bool{"0000:d8:00.1": true}, false)).NotTo(HaveOccurred())
false)).NotTo(HaveOccurred())
helpers.GinkgoAssertFileContentsEquals("/sys/bus/pci/devices/0000:d8:00.0/sriov_numvfs", "2")
})
It("should configure IB", func() {
Expand Down Expand Up @@ -215,7 +215,7 @@ var _ = Describe("SRIOV", func() {
}},
}},
[]sriovnetworkv1.InterfaceExt{{PciAddress: "0000:d8:00.0"}},
map[string]bool{}, false)).NotTo(HaveOccurred())
false)).NotTo(HaveOccurred())
helpers.GinkgoAssertFileContentsEquals("/sys/bus/pci/devices/0000:d8:00.0/sriov_numvfs", "1")
})

Expand Down Expand Up @@ -279,7 +279,7 @@ var _ = Describe("SRIOV", func() {
}},
}},
[]sriovnetworkv1.InterfaceExt{{PciAddress: "0000:d8:00.0"}},
map[string]bool{}, false)).NotTo(HaveOccurred())
false)).NotTo(HaveOccurred())
helpers.GinkgoAssertFileContentsEquals("/sys/bus/pci/devices/0000:d8:00.0/sriov_numvfs", "1")
})

Expand All @@ -302,7 +302,7 @@ var _ = Describe("SRIOV", func() {
}},
}},
[]sriovnetworkv1.InterfaceExt{{PciAddress: "0000:d8:00.0"}},
map[string]bool{}, false)).To(HaveOccurred())
false)).To(HaveOccurred())
})

It("externally managed - wrong MTU", func() {
Expand All @@ -328,7 +328,7 @@ var _ = Describe("SRIOV", func() {
}},
}},
[]sriovnetworkv1.InterfaceExt{{PciAddress: "0000:d8:00.0"}},
map[string]bool{}, false)).To(HaveOccurred())
false)).To(HaveOccurred())
})

It("reset device", func() {
Expand Down Expand Up @@ -359,8 +359,7 @@ var _ = Describe("SRIOV", func() {
LinkType: "ETH",
NumVfs: 2,
TotalVfs: 2,
}},
map[string]bool{}, false)).NotTo(HaveOccurred())
}}, false)).NotTo(HaveOccurred())
helpers.GinkgoAssertFileContentsEquals("/sys/bus/pci/devices/0000:d8:00.0/sriov_numvfs", "0")
})
It("reset device - skip external", func() {
Expand All @@ -379,8 +378,7 @@ var _ = Describe("SRIOV", func() {
PciAddress: "0000:d8:00.0",
NumVfs: 2,
TotalVfs: 2,
}},
map[string]bool{}, false)).NotTo(HaveOccurred())
}}, false)).NotTo(HaveOccurred())
})
It("should configure - skipVFConfiguration is true", func() {
helpers.GinkgoConfigureFakeFS(&fakefilesystem.FS{
Expand Down Expand Up @@ -424,7 +422,7 @@ var _ = Describe("SRIOV", func() {
}},
}},
[]sriovnetworkv1.InterfaceExt{{PciAddress: "0000:d8:00.0"}},
map[string]bool{}, true)).NotTo(HaveOccurred())
true)).NotTo(HaveOccurred())
helpers.GinkgoAssertFileContentsEquals("/sys/bus/pci/devices/0000:d8:00.0/sriov_numvfs", "2")
})
})
Expand Down
23 changes: 4 additions & 19 deletions pkg/host/mock/mock_host.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions pkg/host/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,12 @@ type SriovInterface interface {
// ConfigSriovInterfaces configure multiple SR-IOV devices with the desired configuration
// if skipVFConfiguration flag is set, the function will configure PF and create VFs on it, but will skip VFs configuration
ConfigSriovInterfaces(storeManager store.ManagerInterface, interfaces []sriovnetworkv1.Interface,
ifaceStatuses []sriovnetworkv1.InterfaceExt, pfsToConfig map[string]bool, skipVFConfiguration bool) error
ifaceStatuses []sriovnetworkv1.InterfaceExt, skipVFConfiguration bool) error
// ConfigSriovInterfaces configure virtual functions for virtual environments with the desired configuration
ConfigSriovDeviceVirtual(iface *sriovnetworkv1.Interface) error
}

type UdevInterface interface {
// WriteSwitchdevConfFile writes the needed switchdev configuration files for HW offload support
WriteSwitchdevConfFile(newState *sriovnetworkv1.SriovNetworkNodeState, pfsToSkip map[string]bool) (bool, error)
// PrepareNMUdevRule creates the needed udev rules to disable NetworkManager from
// our managed SR-IOV virtual functions
PrepareNMUdevRule(supportedVfIds []string) error
Expand Down
Loading

0 comments on commit 168086e

Please sign in to comment.