Skip to content

Commit

Permalink
Add additional methods to host/kernel.go
Browse files Browse the repository at this point in the history
New methods are:
* BindDriverByBusAndDevice - binds device to the provided driver
* UnbindDriverByBusAndDevice
unbind device identified by bus and device ID from the driver

Both methods allows to work with devices not
only on PCI bus.

+refactor driver-related methods
+add unit-tests for changed methods

Signed-off-by: Yury Kulazhenkov <[email protected]>
  • Loading branch information
ykulazhenkov committed Jan 10, 2024
1 parent 5752f32 commit 292811f
Show file tree
Hide file tree
Showing 4 changed files with 425 additions and 54 deletions.
9 changes: 6 additions & 3 deletions pkg/consts/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,16 @@ const (
CheckpointFileName = "sno-initial-node-state.json"
Unknown = "Unknown"

SysBusPciDevices = "/sys/bus/pci/devices"
SysBusPciDrivers = "/sys/bus/pci/drivers"
SysBusPciDriversProbe = "/sys/bus/pci/drivers_probe"
SysBus = "/sys/bus"
SysBusPciDevices = SysBus + "/pci/devices"
SysBusPciDrivers = SysBus + "/pci/drivers"
SysBusPciDriversProbe = SysBus + "/pci/drivers_probe"
SysClassNet = "/sys/class/net"
ProcKernelCmdLine = "/proc/cmdline"
NetClass = 0x02
NumVfsFile = "sriov_numvfs"
BusPci = "pci"
BusVdpa = "vdpa"

UdevFolder = "/etc/udev"
UdevRulesFolder = UdevFolder + "/rules.d"
Expand Down
28 changes: 28 additions & 0 deletions pkg/helper/mock/mock_helper.go

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

241 changes: 241 additions & 0 deletions pkg/host/host_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
package host

import (
"os"
"path/filepath"
"testing"

"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"

Check failure on line 8 in pkg/host/host_test.go

View workflow job for this annotation

GitHub Actions / Golangci-lint

File is not `goimports`-ed with -local github.com/k8snetworkplumbingwg/sriov-network-operator (goimports)
"github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
"github.com/k8snetworkplumbingwg/sriov-network-operator/test/util/fakefilesystem"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"go.uber.org/zap/zapcore"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
)

const (
testUnknownDev = "unknown-dev"
testUnknownDriver = "unknown-driver"
testDev = "0000:d8:00.0"
testDevPath = "/sys/bus/pci/devices/" + testDev
testDevDriverPath = testDevPath + "/driver"
testDevDriverOverridePath = testDevPath + "/driver_override"
testDriversRelPath = "../../../../bus/pci/drivers/"
testDevDriverSymlink = testDriversRelPath + testDriver
testDevDriver2Symlink = testDriversRelPath + testDriver2
testDriver = "test-driver"
testDriverPath = "/sys/bus/pci/drivers/" + testDriver
testDriverBindPath = testDriverPath + "/bind"
testDriverUnbindPath = testDriverPath + "/unbind"
testDriver2 = "vfio-pci" // dpdk
testDriver2Path = "/sys/bus/pci/drivers/" + testDriver2
testDriver2BindPath = testDriver2Path + "/bind"
testDriver2UnbindPath = testDriver2Path + "/unbind"
testPciDeviceProbePath = "/sys/bus/pci/drivers_probe"
)

func TestHostManager(t *testing.T) {
log.SetLogger(zap.New(
zap.WriteTo(GinkgoWriter),
zap.Level(zapcore.Level(-2)),
zap.UseDevMode(true)))
RegisterFailHandler(Fail)
RunSpecs(t, "Config Daemon Suite")
}

func testFileContent(path, expectedContent string) {
d, err := os.ReadFile(filepath.Join(vars.FilesystemRoot, path))
ExpectWithOffset(1, err).NotTo(HaveOccurred())
ExpectWithOffset(1, string(d)).To(Equal(expectedContent))
}

var _ = Describe("Kernel", func() {
Context("Drivers", func() {
var (
cleanFakeFs func()
k KernelInterface
)
configureFS := func(f *fakefilesystem.FS) {
var err error
vars.FilesystemRoot, cleanFakeFs, err = f.Use()
Expect(err).ToNot(HaveOccurred())
}
BeforeEach(func() {
cleanFakeFs = nil
k = newKernelInterface(nil)
})
AfterEach(func() {
if cleanFakeFs != nil {
cleanFakeFs()
}
})
Context("Unbind, UnbindDriverByBusAndDevice", func() {
It("unknown device", func() {
Expect(k.UnbindDriverByBusAndDevice(consts.BusPci, testUnknownDev)).NotTo(HaveOccurred())
})
It("known device, no driver", func() {
configureFS(&fakefilesystem.FS{Dirs: []string{testDevPath}})
Expect(k.Unbind(testDev)).NotTo(HaveOccurred())
})
It("has driver, succeed", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
Files: map[string][]byte{testDriverUnbindPath: {}},
})
Expect(k.Unbind(testDev)).NotTo(HaveOccurred())
// check that echo to unbind path was done
testFileContent(testDriverUnbindPath, testDev)
})
It("has driver, failed to unbind", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
})
Expect(k.Unbind(testDev)).To(HaveOccurred())
})
})
Context("HasDriver", func() {
It("unknown device", func() {
has, driver := k.HasDriver(testUnknownDev)
Expect(has).To(BeFalse())
Expect(driver).To(BeEmpty())
})
It("known device, no driver", func() {
configureFS(&fakefilesystem.FS{Dirs: []string{testDevPath}})
has, driver := k.HasDriver(testDev)
Expect(has).To(BeFalse())
Expect(driver).To(BeEmpty())
})
It("has driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
})
has, driver := k.HasDriver(testDev)
Expect(has).To(BeTrue())
Expect(driver).To(Equal(testDriver))
})
})
Context("BindDriverByBusAndDevice", func() {
It("unknown device", func() {
Expect(k.BindDriverByBusAndDevice(consts.BusPci, testUnknownDev, testDriver)).To(HaveOccurred())
})
It("bind to unknown driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath},
})
Expect(k.BindDriverByBusAndDevice(consts.BusPci, testDev, testUnknownDriver)).To(HaveOccurred())
})
It("already has required driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
Files: map[string][]byte{testDriverBindPath: {}, testDriverUnbindPath: {}},
})
Expect(k.BindDriverByBusAndDevice(consts.BusPci, testDev, testDriver)).NotTo(HaveOccurred())
// check that echo to bind/unbind path was not executed
testFileContent(testDriverBindPath, "")
testFileContent(testDriverUnbindPath, "")
})
It("no driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath},
Files: map[string][]byte{testDriverBindPath: {}, testDriverUnbindPath: {}},
})
Expect(k.BindDriverByBusAndDevice(consts.BusPci, testDev, testDriver)).NotTo(HaveOccurred())
// check that echo to bind/unbind path was not executed
testFileContent(testDriverBindPath, testDev)
testFileContent(testDriverUnbindPath, "")
})
It("wrong driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath, testDriver2Path},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
Files: map[string][]byte{testDriverUnbindPath: {}, testDriver2BindPath: {}},
})
Expect(k.BindDriverByBusAndDevice(consts.BusPci, testDev, testDriver2)).NotTo(HaveOccurred())
// should unbind from driver1
testFileContent(testDriverUnbindPath, testDev)
// should bind to driver2
testFileContent(testDriver2BindPath, testDev)
})
})
Context("BindDefaultDriver", func() {
It("unknown device", func() {
Expect(k.BindDefaultDriver(testUnknownDev)).To(HaveOccurred())
})
It("no driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath},
Files: map[string][]byte{testPciDeviceProbePath: {}, testDevDriverOverridePath: {}},
})
Expect(k.BindDefaultDriver(testDev)).NotTo(HaveOccurred())
// should probe driver for dev
testFileContent(testPciDeviceProbePath, testDev)
})
It("already bind to default driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
})
Expect(k.BindDefaultDriver(testDev)).NotTo(HaveOccurred())
})
It("bind to dpdk driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriver2Path},
Symlinks: map[string]string{testDevDriverPath: testDevDriver2Symlink},
Files: map[string][]byte{testPciDeviceProbePath: {}, testDriver2UnbindPath: {}},
})
Expect(k.BindDefaultDriver(testDev)).NotTo(HaveOccurred())
// should unbind from dpdk driver
testFileContent(testDriver2UnbindPath, testDev)
// should probe driver for dev
testFileContent(testPciDeviceProbePath, testDev)
})
})
Context("BindDpdkDriver", func() {
It("unknown device", func() {
Expect(k.BindDpdkDriver(testUnknownDev, testDriver2)).To(HaveOccurred())
})
It("no driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriver2Path},
Files: map[string][]byte{testDevDriverOverridePath: {}},
})
Expect(k.BindDpdkDriver(testDev, testDriver2)).NotTo(HaveOccurred())
// should reset driver override
testFileContent(testDevDriverOverridePath, "")
})
It("already bind to required driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriver2Symlink},
})
Expect(k.BindDpdkDriver(testDev, testDriver2)).NotTo(HaveOccurred())
})
It("bind to wrong driver", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath, testDriver2Path},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
Files: map[string][]byte{testDriverUnbindPath: {}, testDriver2BindPath: {}, testDevDriverOverridePath: {}},
})
Expect(k.BindDpdkDriver(testDev, testDriver2)).NotTo(HaveOccurred())
// should unbind from driver1
testFileContent(testDriverUnbindPath, testDev)
// should bind to driver2
testFileContent(testDriver2BindPath, testDev)
})
It("fail to bind", func() {
configureFS(&fakefilesystem.FS{
Dirs: []string{testDevPath, testDriverPath},
Symlinks: map[string]string{testDevDriverPath: testDevDriverSymlink},
Files: map[string][]byte{testDriverUnbindPath: {}, testDevDriverOverridePath: {}},
})
Expect(k.BindDpdkDriver(testDev, testDriver2)).To(HaveOccurred())
})
})
})
})
Loading

0 comments on commit 292811f

Please sign in to comment.