blob: 2554c3363ae5e060437ecb02b125f9bc3a084add [file] [log] [blame] [edit]
package kmod
import (
"fmt"
"log"
kmodpb "source.monogon.dev/metropolis/pkg/kmod/spec"
)
// MakeMetaFromModuleInfo is a more flexible alternative to MakeMeta. It only
// relies on ModuleInfo structures, additional processing can be done outside of
// this function. It does however require that for dynamically-loaded modules
// the "path" key is set to the path of the .ko file relative to the module
// root.
func MakeMetaFromModuleInfo(modinfos []ModuleInfo) (*kmodpb.Meta, error) {
modIndices := make(map[string]uint32)
modInfoMap := make(map[string]ModuleInfo)
var meta kmodpb.Meta
meta.ModuleDeviceMatches = &kmodpb.RadixNode{
Type: kmodpb.RadixNode_ROOT,
}
var i uint32
for _, m := range modinfos {
meta.Modules = append(meta.Modules, &kmodpb.Module{
Name: m.Name(),
Path: m.Get("path"),
})
for _, p := range m.Aliases() {
if m.Get("path") == "" {
// Ignore built-in modaliases as they do not need to be loaded.
continue
}
if err := AddPattern(meta.ModuleDeviceMatches, p, i); err != nil {
return nil, fmt.Errorf("failed adding device match %q: %w", p, err)
}
}
modIndices[m.Name()] = i
modInfoMap[m.Name()] = m
i++
}
for _, m := range meta.Modules {
for _, dep := range modInfoMap[m.Name].GetDependencies() {
if _, ok := modIndices[dep]; !ok {
log.Printf("Unknown dependency %q for module %q", modInfoMap[m.Name].GetDependencies(), m.Name)
}
m.Depends = append(m.Depends, modIndices[dep])
}
}
return &meta, nil
}