internal/uevent: synthetic events for coldboot
All checks were successful
Test / Create distribution (push) Successful in 1m15s
Test / Sandbox (push) Successful in 3m5s
Test / Hakurei (push) Successful in 4m12s
Test / ShareFS (push) Successful in 4m16s
Test / Sandbox (race detector) (push) Successful in 5m35s
Test / Hakurei (race detector) (push) Successful in 6m39s
Test / Flake checks (push) Successful in 1m24s
All checks were successful
Test / Create distribution (push) Successful in 1m15s
Test / Sandbox (push) Successful in 3m5s
Test / Hakurei (push) Successful in 4m12s
Test / ShareFS (push) Successful in 4m16s
Test / Sandbox (race detector) (push) Successful in 5m35s
Test / Hakurei (race detector) (push) Successful in 6m39s
Test / Flake checks (push) Successful in 1m24s
This causes the kernel to regenerate events that happened before earlyinit started. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
71
internal/uevent/coldboot.go
Normal file
71
internal/uevent/coldboot.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package uevent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// synthAdd is prepared bytes written to uevent to cause a synthetic add event
|
||||
// to be emitted during coldboot.
|
||||
var synthAdd = []byte(KOBJ_ADD.String())
|
||||
|
||||
// Coldboot writes "add" to every uevent file that it finds in /sys/devices.
|
||||
// This causes the kernel to regenerate the uevents for these paths.
|
||||
//
|
||||
// The specified pathname must present the sysfs root.
|
||||
//
|
||||
// Note that while [AOSP documentation] claims to also scan /sys/class and
|
||||
// /sys/block, this is no longer the case, and the documentation was not updated
|
||||
// when this changed.
|
||||
//
|
||||
// [AOSP documentation]: https://android.googlesource.com/platform/system/core/+/master/init/README.ueventd.md
|
||||
func Coldboot(
|
||||
ctx context.Context,
|
||||
pathname string,
|
||||
visited chan<- string,
|
||||
handleWalkErr func(error) error,
|
||||
) error {
|
||||
if handleWalkErr == nil {
|
||||
handleWalkErr = func(err error) error {
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
log.Println("coldboot", err)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return filepath.WalkDir(filepath.Join(pathname, "devices"), func(
|
||||
path string,
|
||||
d fs.DirEntry,
|
||||
err error,
|
||||
) error {
|
||||
if err != nil {
|
||||
return handleWalkErr(err)
|
||||
}
|
||||
if err = ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if d.IsDir() || d.Name() != "uevent" {
|
||||
return nil
|
||||
}
|
||||
if err = os.WriteFile(path, synthAdd, 0); err != nil {
|
||||
return handleWalkErr(err)
|
||||
}
|
||||
|
||||
select {
|
||||
case visited <- path:
|
||||
break
|
||||
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user