6
6
"encoding/json"
7
7
"fmt"
8
8
"io"
9
+ "io/fs"
9
10
"os"
10
11
"os/exec"
11
12
"path/filepath"
@@ -38,7 +39,7 @@ const HostKernelModulesPath = `host-collectors/system/kernel_modules.json`
38
39
// kernelModuleCollector defines the interface used to collect modules from the
39
40
// underlying host.
40
41
type kernelModuleCollector interface {
41
- collect () (map [string ]KernelModuleInfo , error )
42
+ collect (kernelRelease string ) (map [string ]KernelModuleInfo , error )
42
43
}
43
44
44
45
// CollectHostKernelModules is responsible for collecting kernel module status
@@ -79,14 +80,20 @@ func (c *CollectHostKernelModules) IsExcluded() (bool, error) {
79
80
// a module is loaded, it may have one or more instances. The size represents
80
81
// the amount of memory (in bytes) that the module is using.
81
82
func (c * CollectHostKernelModules ) Collect (progressChan chan <- interface {}) (map [string ][]byte , error ) {
82
- modules , err := c .loadable .collect ()
83
+ out , err := exec .Command ("uname" , "-r" ).Output ()
84
+ if err != nil {
85
+ return nil , errors .Wrap (err , "failed to determine kernel release" )
86
+ }
87
+ kernelRelease := strings .TrimSpace (string (out ))
88
+
89
+ modules , err := c .loadable .collect (kernelRelease )
83
90
if err != nil {
84
91
return nil , errors .Wrap (err , "failed to read loadable kernel modules" )
85
92
}
86
93
if modules == nil {
87
94
modules = map [string ]KernelModuleInfo {}
88
95
}
89
- loaded , err := c .loaded .collect ()
96
+ loaded , err := c .loaded .collect (kernelRelease )
90
97
if err != nil {
91
98
return nil , errors .Wrap (err , "failed to read loaded kernel modules" )
92
99
}
@@ -114,20 +121,17 @@ func (c *CollectHostKernelModules) Collect(progressChan chan<- interface{}) (map
114
121
type kernelModulesLoadable struct {}
115
122
116
123
// collect the list of modules that can be loaded by the kernel.
117
- func (l kernelModulesLoadable ) collect () (map [string ]KernelModuleInfo , error ) {
124
+ func (l kernelModulesLoadable ) collect (kernelRelease string ) (map [string ]KernelModuleInfo , error ) {
118
125
modules := make (map [string ]KernelModuleInfo )
119
126
120
- out , err := exec .Command ("uname" , "-r" ).Output ()
121
- if err != nil {
122
- return nil , errors .Wrap (err , "failed to determine kernel release" )
123
- }
124
- kernel := strings .TrimSpace (string (out ))
125
-
126
- kernelPath := "/lib/modules/" + kernel
127
-
127
+ kernelPath := filepath .Join ("/lib/modules" , kernelRelease )
128
128
if _ , err := os .Stat (kernelPath ); os .IsNotExist (err ) {
129
- klog .V (2 ).Infof ("modules are not loadable because kernel path %q does not exist, assuming we are in a container" , kernelPath )
130
- return modules , nil
129
+ kernelPath = filepath .Join ("/usr/lib/modules" , kernelRelease )
130
+ if _ , err := os .Stat (kernelPath ); os .IsNotExist (err ) {
131
+ kernelPath = filepath .Join ("/lib/modules" , kernelRelease )
132
+ klog .V (2 ).Infof ("kernel modules are not loadable because path %q does not exist, assuming we are in a container" , kernelPath )
133
+ return modules , nil
134
+ }
131
135
}
132
136
133
137
cmd := exec .Command ("/usr/bin/find" , kernelPath , "-type" , "f" , "-name" , "*.ko*" )
@@ -155,16 +159,18 @@ func (l kernelModulesLoadable) collect() (map[string]KernelModuleInfo, error) {
155
159
156
160
// kernelModulesLoaded retrieves the list of modules that the kernel is aware of. The
157
161
// modules will either be in loaded, loading or unloading state.
158
- type kernelModulesLoaded struct {}
162
+ type kernelModulesLoaded struct {
163
+ fs fs.FS
164
+ }
159
165
160
166
// collect the list of modules that the kernel is aware of.
161
- func (l kernelModulesLoaded ) collect () (map [string ]KernelModuleInfo , error ) {
167
+ func (l kernelModulesLoaded ) collect (kernelRelease string ) (map [string ]KernelModuleInfo , error ) {
162
168
modules , err := l .collectProc ()
163
169
if err != nil {
164
170
return nil , fmt .Errorf ("proc: %w" , err )
165
171
}
166
172
167
- builtin , err := l .collectBuiltin ()
173
+ builtin , err := l .collectBuiltin (kernelRelease )
168
174
if err != nil {
169
175
return nil , fmt .Errorf ("builtin: %w" , err )
170
176
}
@@ -181,7 +187,7 @@ func (l kernelModulesLoaded) collect() (map[string]KernelModuleInfo, error) {
181
187
func (l kernelModulesLoaded ) collectProc () (map [string ]KernelModuleInfo , error ) {
182
188
modules := make (map [string ]KernelModuleInfo )
183
189
184
- file , err := os . Open ("/ proc/modules" )
190
+ file , err := l . fs . Open ("proc/modules" )
185
191
if err != nil {
186
192
return nil , err
187
193
}
@@ -221,14 +227,18 @@ func (l kernelModulesLoaded) collectProc() (map[string]KernelModuleInfo, error)
221
227
return modules , nil
222
228
}
223
229
224
- func (l kernelModulesLoaded ) collectBuiltin () (map [string ]KernelModuleInfo , error ) {
225
- out , err := exec .Command ("uname" , "-r" ).Output ()
226
- if err != nil {
227
- return nil , errors .Wrap (err , "failed to determine kernel release" )
230
+ func (l kernelModulesLoaded ) collectBuiltin (kernelRelease string ) (map [string ]KernelModuleInfo , error ) {
231
+ builtinPath := filepath .Join ("lib/modules" , kernelRelease , "modules.builtin" )
232
+ if _ , err := fs .Stat (l .fs , builtinPath ); os .IsNotExist (err ) {
233
+ builtinPath = filepath .Join ("usr/lib/modules" , kernelRelease , "modules.builtin" )
234
+ if _ , err := fs .Stat (l .fs , builtinPath ); os .IsNotExist (err ) {
235
+ builtinPath = filepath .Join ("lib/modules" , kernelRelease , "modules.builtin" )
236
+ klog .V (2 ).Infof ("kernel builtin modules path %q does not exist, assuming we are in a container" , builtinPath )
237
+ return nil , nil
238
+ }
228
239
}
229
- kernel := strings .TrimSpace (string (out ))
230
240
231
- file , err := os . Open (fmt . Sprintf ( "/usr/lib/modules/%s/modules.builtin" , kernel ) )
241
+ file , err := l . fs . Open (builtinPath )
232
242
if err != nil {
233
243
if os .IsNotExist (err ) {
234
244
return nil , nil
0 commit comments