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 }