66 "encoding/json"
77 "fmt"
88 "io"
9+ "io/fs"
910 "os"
1011 "os/exec"
1112 "path/filepath"
@@ -38,7 +39,7 @@ const HostKernelModulesPath = `host-collectors/system/kernel_modules.json`
3839// kernelModuleCollector defines the interface used to collect modules from the
3940// underlying host.
4041type kernelModuleCollector interface {
41- collect () (map [string ]KernelModuleInfo , error )
42+ collect (kernelRelease string ) (map [string ]KernelModuleInfo , error )
4243}
4344
4445// CollectHostKernelModules is responsible for collecting kernel module status
@@ -79,14 +80,20 @@ func (c *CollectHostKernelModules) IsExcluded() (bool, error) {
7980// a module is loaded, it may have one or more instances. The size represents
8081// the amount of memory (in bytes) that the module is using.
8182func (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 )
8390 if err != nil {
8491 return nil , errors .Wrap (err , "failed to read loadable kernel modules" )
8592 }
8693 if modules == nil {
8794 modules = map [string ]KernelModuleInfo {}
8895 }
89- loaded , err := c .loaded .collect ()
96+ loaded , err := c .loaded .collect (kernelRelease )
9097 if err != nil {
9198 return nil , errors .Wrap (err , "failed to read loaded kernel modules" )
9299 }
@@ -114,20 +121,17 @@ func (c *CollectHostKernelModules) Collect(progressChan chan<- interface{}) (map
114121type kernelModulesLoadable struct {}
115122
116123// 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 ) {
118125 modules := make (map [string ]KernelModuleInfo )
119126
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 )
128128 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+ }
131135 }
132136
133137 cmd := exec .Command ("/usr/bin/find" , kernelPath , "-type" , "f" , "-name" , "*.ko*" )
@@ -155,16 +159,18 @@ func (l kernelModulesLoadable) collect() (map[string]KernelModuleInfo, error) {
155159
156160// kernelModulesLoaded retrieves the list of modules that the kernel is aware of. The
157161// modules will either be in loaded, loading or unloading state.
158- type kernelModulesLoaded struct {}
162+ type kernelModulesLoaded struct {
163+ fs fs.FS
164+ }
159165
160166// 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 ) {
162168 modules , err := l .collectProc ()
163169 if err != nil {
164170 return nil , fmt .Errorf ("proc: %w" , err )
165171 }
166172
167- builtin , err := l .collectBuiltin ()
173+ builtin , err := l .collectBuiltin (kernelRelease )
168174 if err != nil {
169175 return nil , fmt .Errorf ("builtin: %w" , err )
170176 }
@@ -181,7 +187,7 @@ func (l kernelModulesLoaded) collect() (map[string]KernelModuleInfo, error) {
181187func (l kernelModulesLoaded ) collectProc () (map [string ]KernelModuleInfo , error ) {
182188 modules := make (map [string ]KernelModuleInfo )
183189
184- file , err := os . Open ("/ proc/modules" )
190+ file , err := l . fs . Open ("proc/modules" )
185191 if err != nil {
186192 return nil , err
187193 }
@@ -221,14 +227,18 @@ func (l kernelModulesLoaded) collectProc() (map[string]KernelModuleInfo, error)
221227 return modules , nil
222228}
223229
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+ }
228239 }
229- kernel := strings .TrimSpace (string (out ))
230240
231- file , err := os . Open (fmt . Sprintf ( "/usr/lib/modules/%s/modules.builtin" , kernel ) )
241+ file , err := l . fs . Open (builtinPath )
232242 if err != nil {
233243 if os .IsNotExist (err ) {
234244 return nil , nil
0 commit comments