blob: 1eb2c36afbdfa7913624d237a40bf4ab69542a75 [file] [log] [blame]
Tim Windelschmidt6d33a432025-02-04 14:34:25 +01001// Copyright The Monogon Project Authors.
2// SPDX-License-Identifier: Apache-2.0
3
Lorenz Brunc7b036b2023-06-01 12:23:57 +02004package kmod
5
6import (
7 "fmt"
8 "log"
9
Tim Windelschmidt9f21f532024-05-07 15:14:20 +020010 kmodpb "source.monogon.dev/osbase/kmod/spec"
Lorenz Brunc7b036b2023-06-01 12:23:57 +020011)
12
13// MakeMetaFromModuleInfo is a more flexible alternative to MakeMeta. It only
14// relies on ModuleInfo structures, additional processing can be done outside of
15// this function. It does however require that for dynamically-loaded modules
16// the "path" key is set to the path of the .ko file relative to the module
17// root.
18func MakeMetaFromModuleInfo(modinfos []ModuleInfo) (*kmodpb.Meta, error) {
19 modIndices := make(map[string]uint32)
20 modInfoMap := make(map[string]ModuleInfo)
21 var meta kmodpb.Meta
22 meta.ModuleDeviceMatches = &kmodpb.RadixNode{
Tim Windelschmidta10d0cb2025-01-13 14:44:15 +010023 Type: kmodpb.RadixNode_TYPE_ROOT,
Lorenz Brunc7b036b2023-06-01 12:23:57 +020024 }
25 var i uint32
26 for _, m := range modinfos {
27 meta.Modules = append(meta.Modules, &kmodpb.Module{
28 Name: m.Name(),
29 Path: m.Get("path"),
30 })
31 for _, p := range m.Aliases() {
32 if m.Get("path") == "" {
33 // Ignore built-in modaliases as they do not need to be loaded.
34 continue
35 }
36 if err := AddPattern(meta.ModuleDeviceMatches, p, i); err != nil {
37 return nil, fmt.Errorf("failed adding device match %q: %w", p, err)
38 }
39 }
40 modIndices[m.Name()] = i
41 modInfoMap[m.Name()] = m
42 i++
43 }
44 for _, m := range meta.Modules {
45 for _, dep := range modInfoMap[m.Name].GetDependencies() {
46 if _, ok := modIndices[dep]; !ok {
47 log.Printf("Unknown dependency %q for module %q", modInfoMap[m.Name].GetDependencies(), m.Name)
48 }
49 m.Depends = append(m.Depends, modIndices[dep])
50 }
51 }
52 return &meta, nil
53}