• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

k8snetworkplumbingwg / sriov-network-operator / 19227470377

10 Nov 2025 09:48AM UTC coverage: 62.151% (-0.2%) from 62.366%
19227470377

Pull #902

github

web-flow
Merge f9637c189 into 3d1a472a6
Pull Request #902: Create platform and orchestrator packages

319 of 659 new or added lines in 25 files covered. (48.41%)

41 existing lines in 9 files now uncovered.

8772 of 14114 relevant lines covered (62.15%)

0.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.0
/pkg/host/internal/udev/udev.go
1
package udev
2

3
import (
4
        "fmt"
5
        "os"
6
        "path"
7
        "path/filepath"
8
        "strconv"
9
        "strings"
10

11
        "sigs.k8s.io/controller-runtime/pkg/log"
12

13
        sriovnetworkv1 "github.com/k8snetworkplumbingwg/sriov-network-operator/api/v1"
14
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"
15
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/host/types"
16
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils"
17
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/vars"
18
)
19

20
type udev struct {
21
        utilsHelper utils.CmdInterface
22
}
23

24
func New(utilsHelper utils.CmdInterface) types.UdevInterface {
1✔
25
        return &udev{utilsHelper: utilsHelper}
1✔
26
}
1✔
27

NEW
28
func (u *udev) PrepareNMUdevRule() error {
×
29
        log.Log.V(2).Info("PrepareNMUdevRule()")
×
30
        filePath := filepath.Join(vars.FilesystemRoot, consts.HostUdevRulesFolder, "10-nm-unmanaged.rules")
×
31

×
32
        // remove the old unmanaged rules file
×
33
        if _, err := os.Stat(filePath); err == nil {
×
34
                err = os.Remove(filePath)
×
35
                if err != nil {
×
36
                        log.Log.Error(err, "failed to remove the network manager global unmanaged rule",
×
37
                                "path", filePath)
×
38
                }
×
39
        }
40

41
        // create the pf finder script for udev rules
42
        stdout, stderr, err := u.utilsHelper.RunCommand("/bin/bash", filepath.Join(vars.FilesystemRoot, consts.UdevDisableNM))
×
43
        if err != nil {
×
44
                log.Log.Error(err, "PrepareNMUdevRule(): failed to prepare nmUdevRule", "stderr", stderr)
×
45
                return err
×
46
        }
×
47
        log.Log.V(2).Info("PrepareNMUdevRule()", "stdout", stdout)
×
48

×
49
        //save the device list to use for udev rules
×
NEW
50
        vars.SupportedVfIds = sriovnetworkv1.GetSupportedVfIds()
×
51
        return nil
×
52
}
53

54
// PrepareVFRepUdevRule creates a script which helps to configure representor name for the VF
55
func (u *udev) PrepareVFRepUdevRule() error {
1✔
56
        log.Log.V(2).Info("PrepareVFRepUdevRule()")
1✔
57
        targetPath := filepath.Join(vars.FilesystemRoot, consts.HostUdevFolder, filepath.Base(consts.UdevRepName))
1✔
58
        data, err := os.ReadFile(filepath.Join(vars.FilesystemRoot, consts.UdevRepName))
1✔
59
        if err != nil {
1✔
60
                log.Log.Error(err, "PrepareVFRepUdevRule(): failed to read source for representor name UDEV script")
×
61
                return err
×
62
        }
×
63
        if err := os.WriteFile(targetPath, data, 0755); err != nil {
2✔
64
                log.Log.Error(err, "PrepareVFRepUdevRule(): failed to write representor name UDEV script")
1✔
65
                return err
1✔
66
        }
1✔
67
        if err := os.Chmod(targetPath, 0755); err != nil {
1✔
68
                log.Log.Error(err, "PrepareVFRepUdevRule(): failed to set permissions on representor name UDEV script")
×
69
                return err
×
70
        }
×
71
        return nil
1✔
72
}
73

74
// AddDisableNMUdevRule adds udev rule that disables NetworkManager for VFs on the concrete PF:
75
func (u *udev) AddDisableNMUdevRule(pfPciAddress string) error {
1✔
76
        log.Log.V(2).Info("AddDisableNMUdevRule()", "device", pfPciAddress)
1✔
77
        udevRuleContent := fmt.Sprintf(consts.NMUdevRule, strings.Join(vars.SupportedVfIds, "|"), pfPciAddress)
1✔
78
        return u.addUdevRule(pfPciAddress, "10-nm-disable", udevRuleContent)
1✔
79
}
1✔
80

81
// RemoveDisableNMUdevRule removes udev rule that disables NetworkManager for VFs on the concrete PF
82
func (u *udev) RemoveDisableNMUdevRule(pfPciAddress string) error {
1✔
83
        log.Log.V(2).Info("RemoveDisableNMUdevRule()", "device", pfPciAddress)
1✔
84
        return u.removeUdevRule(pfPciAddress, "10-nm-disable")
1✔
85
}
1✔
86

87
// AddPersistPFNameUdevRule add udev rule that preserves PF name after switching to switchdev mode
88
func (u *udev) AddPersistPFNameUdevRule(pfPciAddress, pfName string) error {
1✔
89
        log.Log.V(2).Info("AddPersistPFNameUdevRule()", "device", pfPciAddress)
1✔
90
        udevRuleContent := fmt.Sprintf(consts.PFNameUdevRule, pfPciAddress, pfName)
1✔
91
        return u.addUdevRule(pfPciAddress, "10-pf-name", udevRuleContent)
1✔
92
}
1✔
93

94
// RemovePersistPFNameUdevRule removes udev rule that preserves PF name after switching to switchdev mode
95
func (u *udev) RemovePersistPFNameUdevRule(pfPciAddress string) error {
1✔
96
        log.Log.V(2).Info("RemovePersistPFNameUdevRule()", "device", pfPciAddress)
1✔
97
        return u.removeUdevRule(pfPciAddress, "10-pf-name")
1✔
98
}
1✔
99

100
// AddVfRepresentorUdevRule adds udev rule that renames VF representors on the concrete PF
101
func (u *udev) AddVfRepresentorUdevRule(pfPciAddress, pfName, pfSwitchID, pfSwitchPort string) error {
1✔
102
        log.Log.V(2).Info("AddVfRepresentorUdevRule()",
1✔
103
                "device", pfPciAddress, "name", pfName, "switch", pfSwitchID, "port", pfSwitchPort)
1✔
104
        udevRuleContent := fmt.Sprintf(consts.SwitchdevUdevRule, pfSwitchID, strings.TrimPrefix(pfSwitchPort, "p"), pfName)
1✔
105
        return u.addUdevRule(pfPciAddress, "20-switchdev", udevRuleContent)
1✔
106
}
1✔
107

108
// RemoveVfRepresentorUdevRule removes udev rule that renames VF representors on the concrete PF
109
func (u *udev) RemoveVfRepresentorUdevRule(pfPciAddress string) error {
1✔
110
        log.Log.V(2).Info("RemoveVfRepresentorUdevRule()", "device", pfPciAddress)
1✔
111
        return u.removeUdevRule(pfPciAddress, "20-switchdev")
1✔
112
}
1✔
113

114
// LoadUdevRules triggers udev rules for network subsystem
115
func (u *udev) LoadUdevRules() error {
1✔
116
        log.Log.V(2).Info("LoadUdevRules()")
1✔
117
        udevAdmTool := "udevadm"
1✔
118
        _, stderr, err := u.utilsHelper.RunCommand(udevAdmTool, "control", "--reload-rules")
1✔
119
        if err != nil {
2✔
120
                log.Log.Error(err, "LoadUdevRules(): failed to reload rules", "error", stderr)
1✔
121
                return err
1✔
122
        }
1✔
123
        _, stderr, err = u.utilsHelper.RunCommand(udevAdmTool, "trigger", "--action", "add", "--attr-match", "subsystem=net")
1✔
124
        if err != nil {
2✔
125
                log.Log.Error(err, "LoadUdevRules(): failed to trigger rules", "error", stderr)
1✔
126
                return err
1✔
127
        }
1✔
128
        return nil
1✔
129
}
130

131
// WaitUdevEventsProcessed calls `udevadm settleā€œ with provided timeout
132
// The command watches the udev event queue, and exits if all current events are handled.
133
func (u *udev) WaitUdevEventsProcessed(timeout int) error {
1✔
134
        log.Log.V(2).Info("WaitUdevEventsProcessed()")
1✔
135
        _, stderr, err := u.utilsHelper.RunCommand("udevadm", "settle", "-t", strconv.Itoa(timeout))
1✔
136
        if err != nil {
2✔
137
                log.Log.Error(err, "WaitUdevEventsProcessed(): failed to wait for udev rules to process", "error", stderr, "timeout", timeout)
1✔
138
                return err
1✔
139
        }
1✔
140
        return nil
1✔
141
}
142

143
func (u *udev) addUdevRule(pfPciAddress, ruleName, ruleContent string) error {
1✔
144
        log.Log.V(2).Info("addUdevRule()", "device", pfPciAddress, "rule", ruleName)
1✔
145
        rulePath := u.getRuleFolderPath()
1✔
146
        err := os.MkdirAll(rulePath, os.ModePerm)
1✔
147
        if err != nil && !os.IsExist(err) {
1✔
148
                log.Log.Error(err, "ensureUdevRulePathExist(): failed to create dir", "path", rulePath)
×
149
                return err
×
150
        }
×
151
        filePath := u.getRulePathForPF(ruleName, pfPciAddress)
1✔
152
        if err := os.WriteFile(filePath, []byte(ruleContent), 0666); err != nil {
1✔
153
                log.Log.Error(err, "addUdevRule(): fail to write file", "path", filePath)
×
154
                return err
×
155
        }
×
156
        return nil
1✔
157
}
158

159
func (u *udev) removeUdevRule(pfPciAddress, ruleName string) error {
1✔
160
        log.Log.V(2).Info("removeUdevRule()", "device", pfPciAddress, "rule", ruleName)
1✔
161
        rulePath := u.getRulePathForPF(ruleName, pfPciAddress)
1✔
162
        err := os.Remove(rulePath)
1✔
163
        if err != nil && !os.IsNotExist(err) {
1✔
164
                log.Log.Error(err, "removeUdevRule(): fail to remove rule file", "path", rulePath)
×
165
                return err
×
166
        }
×
167
        return nil
1✔
168
}
169

170
func (u *udev) getRuleFolderPath() string {
1✔
171
        return filepath.Join(vars.FilesystemRoot, consts.UdevRulesFolder)
1✔
172
}
1✔
173

174
func (u *udev) getRulePathForPF(ruleName, pfPciAddress string) string {
1✔
175
        return path.Join(u.getRuleFolderPath(), fmt.Sprintf("%s-%s.rules", ruleName, pfPciAddress))
1✔
176
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc