| // Package module provides tools for interacting with kernel modules. |
| package module |
| |
| import ( |
| "fmt" |
| "strings" |
| |
| "cos-extensions/tools/osutils" |
| |
| "github.com/golang/glog" |
| ) |
| |
| var ( |
| run = osutils.Run |
| ) |
| |
| type set map[string]bool |
| |
| // RetrieveInstalledModules takes in a list of compiled kernel module file paths and returns |
| // a mapping of the file paths of modules that have been loaded to the kernel to their |
| // module name. |
| func RetrieveInstalledModules(moduleFiles []string) (map[string]string, error) { |
| // Retrieving a mapping of the module name to their file paths. |
| modFileMap := RetrieveLocalModulesInfo(moduleFiles) |
| |
| // Retrieving all loaded modules |
| installedModules, err := retrieveAllInstalledModules() |
| if err != nil { |
| return nil, fmt.Errorf("failed to retrieve loaded modules: %v", err) |
| } |
| installedModFileMap := make(map[string]string) |
| |
| // Mapping installed modules file paths to their names |
| for filePath, name := range modFileMap { |
| if installedModules[name] { |
| installedModFileMap[filePath] = name |
| } |
| } |
| |
| return installedModFileMap, nil |
| } |
| |
| // RetrieveLocalModulesInfo takes in a list of compiled kernel module file names and returns |
| // a mapping of their file paths to their module name |
| func RetrieveLocalModulesInfo(moduleFiles []string) map[string]string { |
| modFileNameMap := make(map[string]string) |
| for _, modFile := range moduleFiles { |
| name, err := run("modinfo", []string{modFile, "-F", "name"}, false) |
| // Skipping file if there is an error retrieving module name |
| if err != nil { |
| glog.Errorf("Failed to retrieve module name for file %s [skipping]: %v\n", modFile, err) |
| continue |
| } |
| modFileNameMap[modFile] = strings.TrimSuffix(name, "\n") |
| } |
| |
| return modFileNameMap |
| } |
| |
| // InstallModule loads a module to the kernel. |
| func InstallModule(modPath string, args []string) error { |
| // Installing the module using insmod |
| modArgs := append([]string{modPath}, args...) |
| _, err := run("insmod", modArgs, false) |
| if err != nil { |
| return fmt.Errorf("failed to install module (%s) with args (%s) using insmod: %v", |
| modPath, args, err) |
| } |
| return nil |
| } |
| |
| func retrieveAllInstalledModules() (set, error) { |
| installedModules, err := run("lsmod", []string{}, false) |
| if err != nil { |
| return nil, fmt.Errorf("failed to retrieve installed modules using 'lsmod': %v", err) |
| } |
| modNames := make(set) |
| |
| // Retrieving name from lsmod output. Line syntax: "[module name] [size] [used by]" |
| for _, mod := range strings.Split(installedModules, "\n")[1:] { |
| info := strings.Fields(mod) |
| if len(info) > 1 { |
| modNames[info[0]] = true |
| } |
| } |
| |
| return modNames, nil |
| } |