aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/app/dispatcher.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-22 06:55:02 +0900
committerOphestra <cat@gensokyo.uk>2025-10-22 06:58:45 +0900
commit8accd3b2190d0527ec0d848c877b1a68abaac28c (patch)
tree831d6ce88a4d461fd7c37165dbd1bb1549bf8092 /internal/app/dispatcher.go
parentc5f59c5488cc529a5a7c7a89e1da56c2b44db16c (diff)
internal/app/shim: use syscall dispatcher
This enables instrumented testing of the shim. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/dispatcher.go')
-rw-r--r--internal/app/dispatcher.go71
1 files changed, 63 insertions, 8 deletions
diff --git a/internal/app/dispatcher.go b/internal/app/dispatcher.go
index d298d6b6..b081ece1 100644
--- a/internal/app/dispatcher.go
+++ b/internal/app/dispatcher.go
@@ -1,16 +1,18 @@
package app
import (
+ "context"
"io"
"io/fs"
- "log"
"os"
"os/exec"
+ "os/signal"
"os/user"
"path/filepath"
"hakurei.app/container"
"hakurei.app/container/check"
+ "hakurei.app/container/seccomp"
"hakurei.app/internal"
"hakurei.app/message"
"hakurei.app/system/dbus"
@@ -28,7 +30,7 @@ type syscallDispatcher interface {
// new starts a goroutine with a new instance of syscallDispatcher.
// A syscallDispatcher must never be used in any goroutine other than the one owning it,
// just synchronising access is not enough, as this is for test instrumentation.
- new(f func(k syscallDispatcher))
+ new(f func(k syscallDispatcher, msg message.Msg))
// getpid provides [os.Getpid].
getpid() int
@@ -38,6 +40,8 @@ type syscallDispatcher interface {
getgid() int
// lookupEnv provides [os.LookupEnv].
lookupEnv(key string) (string, bool)
+ // pipe provides os.Pipe.
+ pipe() (r, w *os.File, err error)
// stat provides [os.Stat].
stat(name string) (os.FileInfo, error)
// open provides [os.Open].
@@ -46,6 +50,8 @@ type syscallDispatcher interface {
readdir(name string) ([]os.DirEntry, error)
// tempdir provides [os.TempDir].
tempdir() string
+ // exit provides [os.Exit].
+ exit(code int)
// evalSymlinks provides [filepath.EvalSymlinks].
evalSymlinks(path string) (string, error)
@@ -56,10 +62,29 @@ type syscallDispatcher interface {
// cmdOutput provides the Output method of [exec.Cmd].
cmdOutput(cmd *exec.Cmd) ([]byte, error)
+ // notifyContext provides [signal.NotifyContext].
+ notifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc)
+
+ // prctl provides [container.Prctl].
+ prctl(op, arg2, arg3 uintptr) error
// overflowUid provides [container.OverflowUid].
overflowUid(msg message.Msg) int
// overflowGid provides [container.OverflowGid].
overflowGid(msg message.Msg) int
+ // setDumpable provides [container.SetDumpable].
+ setDumpable(dumpable uintptr) error
+ // receive provides [container.Receive].
+ receive(key string, e any, fdp *uintptr) (closeFunc func() error, err error)
+
+ // containerStart provides the Start method of [container.Container].
+ containerStart(z *container.Container) error
+ // containerStart provides the Serve method of [container.Container].
+ containerServe(z *container.Container) error
+ // containerStart provides the Wait method of [container.Container].
+ containerWait(z *container.Container) error
+
+ // seccompLoad provides [seccomp.Load].
+ seccompLoad(rules []seccomp.NativeRule, flags seccomp.ExportFlag) error
// mustHsuPath provides [internal.MustHsuPath].
mustHsuPath() *check.Absolute
@@ -67,23 +92,32 @@ type syscallDispatcher interface {
// dbusAddress provides [dbus.Address].
dbusAddress() (session, system string)
+ // setupContSignal provides setupContSignal.
+ setupContSignal(pid int) (io.ReadCloser, func(), error)
+
+ // getMsg returns the [message.Msg] held by syscallDispatcher.
+ getMsg() message.Msg
+ // fatal provides [log.Fatal].
+ fatal(v ...any)
// fatalf provides [log.Fatalf].
fatalf(format string, v ...any)
}
// direct implements syscallDispatcher on the current kernel.
-type direct struct{}
+type direct struct{ msg message.Msg }
-func (k direct) new(f func(k syscallDispatcher)) { go f(k) }
+func (k direct) new(f func(k syscallDispatcher, msg message.Msg)) { go f(k, k.msg) }
func (direct) getpid() int { return os.Getpid() }
func (direct) getuid() int { return os.Getuid() }
func (direct) getgid() int { return os.Getgid() }
func (direct) lookupEnv(key string) (string, bool) { return os.LookupEnv(key) }
+func (direct) pipe() (r, w *os.File, err error) { return os.Pipe() }
func (direct) stat(name string) (os.FileInfo, error) { return os.Stat(name) }
func (direct) open(name string) (osFile, error) { return os.Open(name) }
func (direct) readdir(name string) ([]os.DirEntry, error) { return os.ReadDir(name) }
func (direct) tempdir() string { return os.TempDir() }
+func (direct) exit(code int) { os.Exit(code) }
func (direct) evalSymlinks(path string) (string, error) { return filepath.EvalSymlinks(path) }
@@ -98,11 +132,32 @@ func (direct) lookupGroupId(name string) (gid string, err error) {
func (direct) cmdOutput(cmd *exec.Cmd) ([]byte, error) { return cmd.Output() }
-func (direct) overflowUid(msg message.Msg) int { return container.OverflowUid(msg) }
-func (direct) overflowGid(msg message.Msg) int { return container.OverflowGid(msg) }
+func (direct) notifyContext(parent context.Context, signals ...os.Signal) (ctx context.Context, stop context.CancelFunc) {
+ return signal.NotifyContext(parent, signals...)
+}
+
+func (direct) prctl(op, arg2, arg3 uintptr) error { return container.Prctl(op, arg2, arg3) }
+func (direct) overflowUid(msg message.Msg) int { return container.OverflowUid(msg) }
+func (direct) overflowGid(msg message.Msg) int { return container.OverflowGid(msg) }
+func (direct) setDumpable(dumpable uintptr) error { return container.SetDumpable(dumpable) }
+func (direct) receive(key string, e any, fdp *uintptr) (func() error, error) {
+ return container.Receive(key, e, fdp)
+}
+
+func (direct) containerStart(z *container.Container) error { return z.Start() }
+func (direct) containerServe(z *container.Container) error { return z.Serve() }
+func (direct) containerWait(z *container.Container) error { return z.Wait() }
+
+func (direct) seccompLoad(rules []seccomp.NativeRule, flags seccomp.ExportFlag) error {
+ return seccomp.Load(rules, flags)
+}
func (direct) mustHsuPath() *check.Absolute { return internal.MustHsuPath() }
-func (k direct) dbusAddress() (session, system string) { return dbus.Address() }
+func (direct) dbusAddress() (session, system string) { return dbus.Address() }
+
+func (direct) setupContSignal(pid int) (io.ReadCloser, func(), error) { return setupContSignal(pid) }
-func (direct) fatalf(format string, v ...any) { log.Fatalf(format, v...) }
+func (k direct) getMsg() message.Msg { return k.msg }
+func (k direct) fatal(v ...any) { k.msg.GetLogger().Fatal(v...) }
+func (k direct) fatalf(format string, v ...any) { k.msg.GetLogger().Fatalf(format, v...) }