Files
hakurei/cmd/mbf/cache.go
Ophestra 0e56847754
All checks were successful
Test / Create distribution (push) Successful in 1m5s
Test / Sandbox (push) Successful in 2m49s
Test / ShareFS (push) Successful in 3m40s
Test / Hakurei (push) Successful in 3m48s
Test / Sandbox (race detector) (push) Successful in 5m23s
Test / Hakurei (race detector) (push) Successful in 6m30s
Test / Flake checks (push) Successful in 1m23s
cmd/mbf: add arm64 magic
Signed-off-by: Ophestra <cat@gensokyo.uk>
2026-05-08 00:23:09 +09:00

150 lines
2.8 KiB
Go

package main
import (
"context"
"os"
"path/filepath"
"runtime"
"testing"
"hakurei.app/check"
"hakurei.app/container"
"hakurei.app/internal/pkg"
"hakurei.app/internal/rosa"
"hakurei.app/message"
)
// cache refers to an instance of [pkg.Cache] that might be open.
type cache struct {
ctx context.Context
msg message.Msg
// Should generally not be used directly.
c *pkg.Cache
cures, jobs int
hostAbstract, idle bool
verboseInit bool
arch string
base string
}
// open opens the underlying [pkg.Cache].
func (cache *cache) open() (err error) {
if cache.c != nil {
return os.ErrInvalid
}
var base *check.Absolute
if cache.base, err = filepath.Abs(cache.base); err != nil {
return
} else if base, err = check.NewAbs(cache.base); err != nil {
return
}
var flags int
if cache.idle {
flags |= pkg.CSchedIdle
}
if cache.hostAbstract {
flags |= pkg.CHostAbstract
}
if !cache.verboseInit {
flags |= pkg.CSuppressInit
}
done := make(chan struct{})
defer close(done)
go func() {
select {
case <-cache.ctx.Done():
if testing.Testing() {
return
}
os.Exit(2)
case <-done:
return
}
}()
cache.msg.Verbosef("opening cache at %s", base)
cache.c, err = pkg.Open(
cache.ctx,
cache.msg,
flags,
cache.cures,
cache.jobs,
base,
)
if err != nil {
return
}
done <- struct{}{}
if cache.arch != "" && cache.arch != runtime.GOARCH {
var (
name string
offset byte
magic string
mask string
)
switch cache.arch {
case "riscv64":
name = "riscv64"
offset = 0
magic = "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00"
mask = "\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"
case "arm64":
name = "aarch64"
offset = 0
magic = "\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00"
mask = "\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff"
default:
cache.c.Close()
err = pkg.UnsupportedArchError(cache.arch)
return
}
var pathname *check.Absolute
pathname, _, err = cache.c.Cure(rosa.Std.Load(rosa.QEMU))
if err != nil {
cache.c.Close()
return
}
pkg.RegisterArch(cache.arch, container.BinfmtEntry{
Offset: offset,
Magic: magic,
Mask: mask,
Interpreter: pathname.Append(
"system/bin",
"qemu-"+name,
),
})
rosa.DropCaches(cache.arch, rosa.Flags())
}
return
}
// Close closes the underlying [pkg.Cache] if it is open.
func (cache *cache) Close() {
if cache.c != nil {
cache.c.Close()
}
}
// Do calls f on the underlying cache and returns its error value.
func (cache *cache) Do(f func(cache *pkg.Cache) error) error {
if cache.c == nil {
if err := cache.open(); err != nil {
return err
}
}
return f(cache.c)
}