mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-06 20:10:11 +02:00
75 lines
2.0 KiB
Go
75 lines
2.0 KiB
Go
package mod
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
)
|
|
|
|
// Probe is a expanded version of modprobe, in which it checks if the Kernel
|
|
// built-in features contain the given module name.
|
|
// It first tries to locate the modules directory in [getModulesPath].
|
|
// If it fails (like on WSL), it then only checks for the kernel feature
|
|
// in /proc/config.gz with [checkProcConfig].
|
|
// Otherwise, it first checks if the modules directory modules.builtin
|
|
// file contains the given module name in [checkModulesBuiltin].
|
|
// If the module is not found, it then runs the classic [modProbe] behavior,
|
|
// trying to load the module in the kernel.
|
|
// If this fails, it does one final try running [checkProcConfig].
|
|
func Probe(moduleName string) error {
|
|
modulesPath, err := getModulesPath()
|
|
if err != nil {
|
|
if errors.Is(err, ErrModulesDirectoryNotFound) {
|
|
err = checkProcConfig(moduleName)
|
|
if err != nil {
|
|
return fmt.Errorf("checking /proc/config.gz: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
return fmt.Errorf("getting modules path: %w", err)
|
|
}
|
|
|
|
err = checkModulesBuiltin(modulesPath, moduleName)
|
|
if err != nil {
|
|
err = modProbe(modulesPath, moduleName)
|
|
if err != nil {
|
|
err = checkProcConfig(moduleName)
|
|
if err != nil {
|
|
return fmt.Errorf("checking /proc/config.gz: %w", err)
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// modProbe is the classic modprobe behavior.
|
|
func modProbe(modulesPath, moduleName string) error {
|
|
modulesInfo, err := getModulesInfo(modulesPath)
|
|
if err != nil {
|
|
return fmt.Errorf("getting modules information: %w", err)
|
|
}
|
|
|
|
modulePath, err := findModulePath(moduleName, modulesInfo)
|
|
if err != nil {
|
|
return fmt.Errorf("finding module path: %w", err)
|
|
}
|
|
|
|
info := modulesInfo[modulePath]
|
|
if info.state == builtin || info.state == loaded {
|
|
return nil
|
|
}
|
|
|
|
info.state = loading
|
|
for _, dependencyModulePath := range info.dependencyPaths {
|
|
err = initDependencies(dependencyModulePath, modulesInfo)
|
|
if err != nil {
|
|
return fmt.Errorf("init dependencies: %w", err)
|
|
}
|
|
}
|
|
|
|
err = initModule(modulePath)
|
|
if err != nil {
|
|
return fmt.Errorf("init module: %w", err)
|
|
}
|
|
return nil
|
|
}
|