blob: 5700ad428155b602e35b013cfa1c3f39c19394e2 [file] [edit]
// 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
}