|
4 | 4 | "bufio"
|
5 | 5 | "bytes"
|
6 | 6 | "encoding/json"
|
| 7 | + "fmt" |
| 8 | + "io" |
7 | 9 | "os"
|
8 | 10 | "os/exec"
|
9 | 11 | "path/filepath"
|
@@ -157,6 +159,26 @@ type kernelModulesLoaded struct{}
|
157 | 159 |
|
158 | 160 | // collect the list of modules that the kernel is aware of.
|
159 | 161 | func (l kernelModulesLoaded) collect() (map[string]KernelModuleInfo, error) {
|
| 162 | + modules, err := l.collectProc() |
| 163 | + if err != nil { |
| 164 | + return nil, fmt.Errorf("proc: %w", err) |
| 165 | + } |
| 166 | + |
| 167 | + builtin, err := l.collectBuiltin() |
| 168 | + if err != nil { |
| 169 | + return nil, fmt.Errorf("builtin: %w", err) |
| 170 | + } |
| 171 | + |
| 172 | + for name, module := range builtin { |
| 173 | + if _, ok := modules[name]; !ok { |
| 174 | + modules[name] = module |
| 175 | + } |
| 176 | + } |
| 177 | + |
| 178 | + return modules, nil |
| 179 | +} |
| 180 | + |
| 181 | +func (l kernelModulesLoaded) collectProc() (map[string]KernelModuleInfo, error) { |
160 | 182 | modules := make(map[string]KernelModuleInfo)
|
161 | 183 |
|
162 | 184 | file, err := os.Open("/proc/modules")
|
@@ -199,6 +221,45 @@ func (l kernelModulesLoaded) collect() (map[string]KernelModuleInfo, error) {
|
199 | 221 | return modules, nil
|
200 | 222 | }
|
201 | 223 |
|
| 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") |
| 228 | + } |
| 229 | + kernel := strings.TrimSpace(string(out)) |
| 230 | + |
| 231 | + file, err := os.Open(fmt.Sprintf("/usr/lib/modules/%s/modules.builtin", kernel)) |
| 232 | + if err != nil { |
| 233 | + return nil, err |
| 234 | + } |
| 235 | + defer file.Close() |
| 236 | + |
| 237 | + return l.parseBuiltin(file) |
| 238 | +} |
| 239 | + |
| 240 | +func (l kernelModulesLoaded) parseBuiltin(r io.Reader) (map[string]KernelModuleInfo, error) { |
| 241 | + modules := make(map[string]KernelModuleInfo) |
| 242 | + |
| 243 | + scanner := bufio.NewScanner(r) |
| 244 | + for scanner.Scan() { |
| 245 | + _, file := filepath.Split(scanner.Text()) |
| 246 | + name := strings.TrimSuffix(file, filepath.Ext(file)) |
| 247 | + |
| 248 | + if name == "" { |
| 249 | + continue |
| 250 | + } |
| 251 | + |
| 252 | + modules[name] = KernelModuleInfo{ |
| 253 | + Status: KernelModuleLoaded, |
| 254 | + } |
| 255 | + } |
| 256 | + if err := scanner.Err(); err != nil { |
| 257 | + return nil, err |
| 258 | + } |
| 259 | + |
| 260 | + return modules, nil |
| 261 | +} |
| 262 | + |
202 | 263 | func (c *CollectHostKernelModules) RemoteCollect(progressChan chan<- interface{}) (map[string][]byte, error) {
|
203 | 264 | return nil, ErrRemoteCollectorNotImplemented
|
204 | 265 | }
|
0 commit comments