cmd/earlyinit: load device drivers
All checks were successful
Test / Create distribution (push) Successful in 1m11s
Test / Sandbox (push) Successful in 2m56s
Test / ShareFS (push) Successful in 4m1s
Test / Sandbox (race detector) (push) Successful in 5m38s
Test / Hakurei (race detector) (push) Successful in 6m41s
Test / Hakurei (push) Successful in 2m32s
Test / Flake checks (push) Successful in 1m17s

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2026-05-27 18:54:05 +09:00
parent 598c7aa30f
commit a2cc28f53c
2 changed files with 74 additions and 0 deletions

View File

@@ -242,5 +242,6 @@ func main() {
[]byte("/system/lib/firmware"), []byte("/system/lib/firmware"),
0, 0,
)) ))
go dispatchModprobe(ctx, s)
} }

73
cmd/earlyinit/modprobe.go Normal file
View File

@@ -0,0 +1,73 @@
package main
import (
"context"
"errors"
"fmt"
"log"
"os/exec"
"strings"
"hakurei.app/internal/kobject"
"hakurei.app/internal/report"
"hakurei.app/internal/uevent"
)
// ModprobeError describes an unsuccessful modprobe invocation.
type ModprobeError struct {
ModAlias string `json:"modalias"`
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
ExitCode int `json:"exit_code"`
}
var _ report.RepresentableError = ModprobeError{}
func (ModprobeError) Representable() {}
func (e ModprobeError) Error() string {
return fmt.Sprintf(
"modprobe exit status %d: %s",
e.ExitCode, strings.TrimSpace(e.Stderr),
)
}
// dispatchModprobe invokes modprobe for [uevent.KOBJ_ADD] events raising new
// MODALIAS strings.
func dispatchModprobe(
ctx context.Context,
s *kobject.State,
) {
aliases := make(chan string, 1<<8)
go func() {
defer close(aliases)
s.Range(ctx, func(o *kobject.Object, act uevent.KobjectAction) bool {
if act == uevent.KOBJ_ADD && o.Driver == "" && o.ModAlias != "" {
aliases <- o.ModAlias
}
return true
})
}()
for alias := range aliases {
stdout, err := exec.Command("/system/sbin/modprobe", alias).Output()
if err == nil {
if len(stdout) > 0 {
log.Println(string(stdout))
}
continue
}
var exitError *exec.ExitError
if !errors.As(err, &exitError) || exitError == nil {
r.Dispatch(report.Degraded, "invoke modprobe", err)
continue
}
r.Dispatch(report.Trivial, "load device driver", ModprobeError{
ModAlias: alias,
Stdout: string(stdout),
Stderr: string(exitError.Stderr),
ExitCode: exitError.ExitCode(),
})
}
}