aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2026-02-28 20:42:33 +0900
committerOphestra <cat@gensokyo.uk>2026-02-28 20:44:44 +0900
commitc74c269b66770f0eddde255d2805b79f274409e9 (patch)
tree02cb3e1bed01d24776d8d47a9c8fca47ed3d7343
parent4b0cce4db5f8e75c79e104f8c5ec02cb4541ed76 (diff)
container: use /proc/self/exe directly
This is a more reliable form of pathname to self and also cheaper than os.Executable. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/sharefs/fuse.go8
-rw-r--r--container/container.go2
-rw-r--r--container/container_test.go5
-rw-r--r--container/executable.go3
-rw-r--r--container/fhs/abs.go2
-rw-r--r--container/fhs/fhs.go4
-rw-r--r--internal/lockedfile/internal/filelock/filelock_test.go4
-rw-r--r--internal/lockedfile/lockedfile_test.go4
8 files changed, 18 insertions, 14 deletions
diff --git a/cmd/sharefs/fuse.go b/cmd/sharefs/fuse.go
index d35ff8b9..a52ee035 100644
--- a/cmd/sharefs/fuse.go
+++ b/cmd/sharefs/fuse.go
@@ -33,6 +33,7 @@ import (
"hakurei.app/container"
"hakurei.app/container/check"
+ "hakurei.app/container/fhs"
"hakurei.app/container/std"
"hakurei.app/hst"
"hakurei.app/internal/helper/proc"
@@ -441,12 +442,7 @@ func _main(s ...string) (exitCode int) {
// keep fuse_parse_cmdline happy in the container
z.Tmpfs(check.MustAbs(container.Nonexistent), 1<<10, 0755)
- if a, err := check.NewAbs(container.MustExecutable(msg)); err != nil {
- log.Println(err)
- return 5
- } else {
- z.Path = a
- }
+ z.Path = fhs.AbsProcSelfExe
z.Args = s
z.ForwardCancel = true
z.SeccompPresets |= std.PresetStrict
diff --git a/container/container.go b/container/container.go
index a6457714..8b5ec01d 100644
--- a/container/container.go
+++ b/container/container.go
@@ -525,7 +525,7 @@ func New(ctx context.Context, msg message.Msg) *Container {
p := &Container{ctx: ctx, msg: msg, Params: Params{Ops: new(Ops)}}
c, cancel := context.WithCancel(ctx)
p.cancel = cancel
- p.cmd = exec.CommandContext(c, MustExecutable(msg))
+ p.cmd = exec.CommandContext(c, fhs.ProcSelfExe)
return p
}
diff --git a/container/container_test.go b/container/container_test.go
index 852304e7..e00a63c7 100644
--- a/container/container_test.go
+++ b/container/container_test.go
@@ -773,14 +773,13 @@ func TestMain(m *testing.M) {
func helperNewContainerLibPaths(ctx context.Context, libPaths *[]*check.Absolute, args ...string) (c *container.Container) {
msg := message.New(nil)
msg.SwapVerbose(testing.Verbose())
- executable := check.MustAbs(container.MustExecutable(msg))
c = container.NewCommand(ctx, msg, absHelperInnerPath, "helper", args...)
c.Env = append(c.Env, envDoCheck+"=1")
- c.Bind(executable, absHelperInnerPath, 0)
+ c.Bind(fhs.AbsProcSelfExe, absHelperInnerPath, 0)
// in case test has cgo enabled
- if entries, err := ldd.Resolve(ctx, msg, executable); err != nil {
+ if entries, err := ldd.Resolve(ctx, msg, nil); err != nil {
log.Fatalf("ldd: %v", err)
} else {
*libPaths = ldd.Path(entries)
diff --git a/container/executable.go b/container/executable.go
index 67c43a70..b825306a 100644
--- a/container/executable.go
+++ b/container/executable.go
@@ -28,6 +28,9 @@ func copyExecutable(msg message.Msg) {
}
}
+// MustExecutable calls [os.Executable] and terminates the process on error.
+//
+// Deprecated: This is no longer used and will be removed in 0.4.
func MustExecutable(msg message.Msg) string {
executableOnce.Do(func() { copyExecutable(msg) })
return executable
diff --git a/container/fhs/abs.go b/container/fhs/abs.go
index fda6971d..45c50bfd 100644
--- a/container/fhs/abs.go
+++ b/container/fhs/abs.go
@@ -42,6 +42,8 @@ var (
AbsDevShm = unsafeAbs(DevShm)
// AbsProc is [Proc] as [check.Absolute].
AbsProc = unsafeAbs(Proc)
+ // AbsProcSelfExe is [ProcSelfExe] as [check.Absolute].
+ AbsProcSelfExe = unsafeAbs(ProcSelfExe)
// AbsSys is [Sys] as [check.Absolute].
AbsSys = unsafeAbs(Sys)
)
diff --git a/container/fhs/fhs.go b/container/fhs/fhs.go
index e0c1d861..6d098d0c 100644
--- a/container/fhs/fhs.go
+++ b/container/fhs/fhs.go
@@ -41,6 +41,10 @@ const (
// ProcSys points to a hierarchy below /proc/ that exposes a number of
// kernel tunables.
ProcSys = Proc + "sys/"
+ // ProcSelf resolves to the process's own /proc/pid directory.
+ ProcSelf = Proc + "self/"
+ // ProcSelfExe is a symbolic link to program pathname.
+ ProcSelfExe = ProcSelf + "exe"
// Sys points to a virtual kernel file system exposing discovered devices
// and other functionality.
Sys = "/sys/"
diff --git a/internal/lockedfile/internal/filelock/filelock_test.go b/internal/lockedfile/internal/filelock/filelock_test.go
index 4e407394..4498423a 100644
--- a/internal/lockedfile/internal/filelock/filelock_test.go
+++ b/internal/lockedfile/internal/filelock/filelock_test.go
@@ -14,7 +14,7 @@ import (
"testing"
"time"
- "hakurei.app/container"
+ "hakurei.app/container/fhs"
"hakurei.app/internal/lockedfile/internal/filelock"
"hakurei.app/internal/lockedfile/internal/testexec"
)
@@ -197,7 +197,7 @@ func TestLockNotDroppedByExecCommand(t *testing.T) {
// Some kinds of file locks are dropped when a duplicated or forked file
// descriptor is unlocked. Double-check that the approach used by os/exec does
// not accidentally drop locks.
- cmd := testexec.CommandContext(t, t.Context(), container.MustExecutable(nil), "-test.run=^$")
+ cmd := testexec.CommandContext(t, t.Context(), fhs.ProcSelfExe, "-test.run=^$")
if err := cmd.Run(); err != nil {
t.Fatalf("exec failed: %v", err)
}
diff --git a/internal/lockedfile/lockedfile_test.go b/internal/lockedfile/lockedfile_test.go
index 6182dd99..7ad3c2c5 100644
--- a/internal/lockedfile/lockedfile_test.go
+++ b/internal/lockedfile/lockedfile_test.go
@@ -15,7 +15,7 @@ import (
"testing"
"time"
- "hakurei.app/container"
+ "hakurei.app/container/fhs"
"hakurei.app/internal/lockedfile"
"hakurei.app/internal/lockedfile/internal/testexec"
)
@@ -215,7 +215,7 @@ func TestSpuriousEDEADLK(t *testing.T) {
t.Fatal(err)
}
- cmd := testexec.CommandContext(t, t.Context(), container.MustExecutable(nil), "-test.run=^"+t.Name()+"$")
+ cmd := testexec.CommandContext(t, t.Context(), fhs.ProcSelfExe, "-test.run=^"+t.Name()+"$")
cmd.Env = append(os.Environ(), fmt.Sprintf("%s=%s", dirVar, dir))
qDone := make(chan struct{})