blob: 5c5dc11f13d56802aaf997fb724a5b0159b3d6c8 [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"
Lorenz Brunc7b036b2023-06-01 12:23:57 +02008
Tim Windelschmidt9f21f532024-05-07 15:14:20 +02009 kmodpb "source.monogon.dev/osbase/kmod/spec"
Lorenz Brunc7b036b2023-06-01 12:23:57 +020010)
11
12// MakeMetaFromModuleInfo is a more flexible alternative to MakeMeta. It only
13// relies on ModuleInfo structures, additional processing can be done outside of
14// this function. It does however require that for dynamically-loaded modules
15// the "path" key is set to the path of the .ko file relative to the module
16// root.
17func MakeMetaFromModuleInfo(modinfos []ModuleInfo) (*kmodpb.Meta, error) {
18 modIndices := make(map[string]uint32)
19 modInfoMap := make(map[string]ModuleInfo)
20 var meta kmodpb.Meta
21 meta.ModuleDeviceMatches = &kmodpb.RadixNode{
Tim Windelschmidta10d0cb2025-01-13 14:44:15 +010022 Type: kmodpb.RadixNode_TYPE_ROOT,
Lorenz Brunc7b036b2023-06-01 12:23:57 +020023 }
24 var i uint32
25 for _, m := range modinfos {
26 meta.Modules = append(meta.Modules, &kmodpb.Module{
27 Name: m.Name(),
28 Path: m.Get("path"),
29 })
30 for _, p := range m.Aliases() {
31 if m.Get("path") == "" {
32 // Ignore built-in modaliases as they do not need to be loaded.
33 continue
34 }
35 if err := AddPattern(meta.ModuleDeviceMatches, p, i); err != nil {
36 return nil, fmt.Errorf("failed adding device match %q: %w", p, err)
37 }
38 }
39 modIndices[m.Name()] = i
40 modInfoMap[m.Name()] = m
41 i++
42 }
43 for _, m := range meta.Modules {
44 for _, dep := range modInfoMap[m.Name].GetDependencies() {
45 if _, ok := modIndices[dep]; !ok {
Lorenz Brunba82bc62025-07-22 20:17:05 +020046 return nil, fmt.Errorf("unknown dependency %q for module %q", dep, m.Name)
Lorenz Brunc7b036b2023-06-01 12:23:57 +020047 }
48 m.Depends = append(m.Depends, modIndices[dep])
49 }
50 }
51 return &meta, nil
52}