Skip to content

Commit 3bafc14

Browse files
committed
Use strings.Cut() to parse modalias strings
Signed-off-by: Christopher Desiniotis <[email protected]>
1 parent d491626 commit 3bafc14

File tree

3 files changed

+147
-155
lines changed

3 files changed

+147
-155
lines changed

internal/nvpci/modalias.go

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,24 @@ import (
2525
"golang.org/x/sys/unix"
2626
)
2727

28+
const (
29+
vfioPciAliasPrefix string = "alias vfio_pci:"
30+
)
31+
2832
// modAlias is a decomposed version of string like this
2933
//
3034
// vNNNNNNNNdNNNNNNNNsvNNNNNNNNsdNNNNNNNNbcNNscNNiNN
3135
//
3236
// The "NNNN" are always of the length in the example
3337
// unless replaced with a wildcard ("*")
3438
type modAlias struct {
35-
vendor string // v
36-
device string // d
37-
subvendor string // sv
38-
subdevice string // sd
39-
baseClass string // bc
40-
subClass string // sc
41-
interface_ string // i
39+
vendor string // v
40+
device string // d
41+
subvendor string // sv
42+
subdevice string // sd
43+
baseClass string // bc
44+
subClass string // sc
45+
programmingInterface string // i
4246
}
4347

4448
// vfioAlias represents an entry from the modules.alias file for a vfio driver
@@ -66,63 +70,50 @@ func parseModAliasString(input string) (*modAlias, error) {
6670
}
6771

6872
ma := &modAlias{}
69-
remaining := input[1:] // skip 'v'
73+
var before, after string
74+
var found bool
75+
after = input[1:] // cut leading 'v'
7076

71-
vendor, remaining, err := extractField(remaining, "d")
72-
if err != nil {
73-
return nil, fmt.Errorf("failed to parse vendor: %w", err)
77+
before, after, found = strings.Cut(after, "d")
78+
if !found {
79+
return nil, fmt.Errorf("failed to find delimiter 'd' in %q", input)
7480
}
75-
ma.vendor = vendor
81+
ma.vendor = before
7682

77-
device, remaining, err := extractField(remaining, "sv")
78-
if err != nil {
79-
return nil, fmt.Errorf("failed to parse device: %w", err)
83+
before, after, found = strings.Cut(after, "sv")
84+
if !found {
85+
return nil, fmt.Errorf("failed to find delimiter 'sv' in %q", input)
8086
}
81-
ma.device = device
87+
ma.device = before
8288

83-
subvendor, remaining, err := extractField(remaining, "sd")
84-
if err != nil {
85-
return nil, fmt.Errorf("failed to parse subvendor: %w", err)
89+
before, after, found = strings.Cut(after, "sd")
90+
if !found {
91+
return nil, fmt.Errorf("failed to find delimiter 'sd' in %q", input)
8692
}
87-
ma.subvendor = subvendor
93+
ma.subvendor = before
8894

89-
subdevice, remaining, err := extractField(remaining, "bc")
90-
if err != nil {
91-
return nil, fmt.Errorf("failed to parse subdevice: %w", err)
95+
before, after, found = strings.Cut(after, "bc")
96+
if !found {
97+
return nil, fmt.Errorf("failed to find delimiter 'bc' in %q", input)
9298
}
93-
ma.subdevice = subdevice
99+
ma.subdevice = before
94100

95-
baseClass, remaining, err := extractField(remaining, "sc")
96-
if err != nil {
97-
return nil, fmt.Errorf("failed to parse base class: %w", err)
101+
before, after, found = strings.Cut(after, "sc")
102+
if !found {
103+
return nil, fmt.Errorf("failed to find delimiter 'sc' in input %q", input)
98104
}
99-
ma.baseClass = baseClass
105+
ma.baseClass = before
100106

101-
subClass, remaining, err := extractField(remaining, "i")
102-
if err != nil {
103-
return nil, fmt.Errorf("failed to parse subclass: %w", err)
107+
before, after, found = strings.Cut(after, "i")
108+
if !found {
109+
return nil, fmt.Errorf("failed to find delimiter 'i' in %q", input)
104110
}
105-
ma.subClass = subClass
106-
107-
ma.interface_ = remaining
111+
ma.subClass = before
112+
ma.programmingInterface = after
108113

109114
return ma, nil
110115
}
111116

112-
// extractField extracts the value before the next delimiter from the input string.
113-
// Returns the extracted value, the remaining string (without the delimiter), and any error.
114-
func extractField(input, delimiter string) (string, string, error) {
115-
idx := strings.Index(input, delimiter)
116-
if idx == -1 {
117-
return "", "", fmt.Errorf("failed to find index of the first instance of %q in string %q", delimiter, input)
118-
}
119-
120-
value := input[:idx]
121-
remaining := input[idx+len(delimiter):]
122-
123-
return value, remaining, nil
124-
}
125-
126117
func getKernelVersion() (string, error) {
127118
var uname unix.Utsname
128119
if err := unix.Uname(&uname); err != nil {
@@ -154,7 +145,7 @@ func getVFIOAliases(input string) []vfioAlias {
154145
for _, line := range lines {
155146
line = strings.TrimSpace(line)
156147

157-
if !strings.HasPrefix(line, "alias vfio_pci:") {
148+
if !strings.HasPrefix(line, vfioPciAliasPrefix) {
158149
continue
159150
}
160151

0 commit comments

Comments
 (0)