| 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 | 
 | } |