aboutsummaryrefslogtreecommitdiffhomepage
path: root/container
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-10-09 22:04:35 +0900
committerOphestra <cat@gensokyo.uk>2025-10-09 22:04:35 +0900
commita941ac025f9f3a942cab04a6f2447e4cab0e616c (patch)
treea309e19a16505b27457e0e1d1bac2d28d0a99105 /container
parent87b5c30ef6d5b7b8a10d6a5a8610054c403923e6 (diff)
container/init: unwrap descriptive fatal error
These errors are printed with a descriptive message prefixed to them, so it is more readable to expose the underlying errno. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'container')
-rw-r--r--container/errors.go11
-rw-r--r--container/init.go8
-rw-r--r--container/params.go2
3 files changed, 16 insertions, 5 deletions
diff --git a/container/errors.go b/container/errors.go
index e3f4b9d9..884c8a04 100644
--- a/container/errors.go
+++ b/container/errors.go
@@ -59,6 +59,7 @@ func messagePrefixP[V any, T interface {
return zeroString, false
}
+// MountError wraps errors returned by syscall.Mount.
type MountError struct {
Source, Target, Fstype string
@@ -74,6 +75,7 @@ func (e *MountError) Unwrap() error {
return e.Errno
}
+func (e *MountError) Message() string { return "cannot " + e.Error() }
func (e *MountError) Error() string {
if e.Flags&syscall.MS_BIND != 0 {
if e.Flags&syscall.MS_REMOUNT != 0 {
@@ -90,6 +92,15 @@ func (e *MountError) Error() string {
return "mount " + e.Target + ": " + e.Errno.Error()
}
+// optionalErrorUnwrap calls [errors.Unwrap] and returns the resulting value
+// if it is not nil, or the original value if it is.
+func optionalErrorUnwrap(err error) error {
+ if underlyingErr := errors.Unwrap(err); underlyingErr != nil {
+ return underlyingErr
+ }
+ return err
+}
+
// errnoFallback returns the concrete errno from an error, or a [os.PathError] fallback.
func errnoFallback(op, path string, err error) (syscall.Errno, *os.PathError) {
var errno syscall.Errno
diff --git a/container/init.go b/container/init.go
index 923a36e8..ff72c403 100644
--- a/container/init.go
+++ b/container/init.go
@@ -178,7 +178,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
lastcap := k.lastcap(msg)
if err := k.mount(zeroString, fhs.Root, zeroString, MS_SILENT|MS_SLAVE|MS_REC, zeroString); err != nil {
- k.fatalf(msg, "cannot make / rslave: %v", err)
+ k.fatalf(msg, "cannot make / rslave: %v", optionalErrorUnwrap(err))
}
state := &setupState{Params: &params.Params, Msg: msg}
@@ -202,7 +202,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
}
if err := k.mount(SourceTmpfsRootfs, intermediateHostPath, FstypeTmpfs, MS_NODEV|MS_NOSUID, zeroString); err != nil {
- k.fatalf(msg, "cannot mount intermediate root: %v", err)
+ k.fatalf(msg, "cannot mount intermediate root: %v", optionalErrorUnwrap(err))
}
if err := k.chdir(intermediateHostPath); err != nil {
k.fatalf(msg, "cannot enter intermediate host path: %v", err)
@@ -212,7 +212,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
k.fatalf(msg, "%v", err)
}
if err := k.mount(sysrootDir, sysrootDir, zeroString, MS_SILENT|MS_BIND|MS_REC, zeroString); err != nil {
- k.fatalf(msg, "cannot bind sysroot: %v", err)
+ k.fatalf(msg, "cannot bind sysroot: %v", optionalErrorUnwrap(err))
}
if err := k.mkdir(hostDir, 0755); err != nil {
@@ -246,7 +246,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
// setup requiring host root complete at this point
if err := k.mount(hostDir, hostDir, zeroString, MS_SILENT|MS_REC|MS_PRIVATE, zeroString); err != nil {
- k.fatalf(msg, "cannot make host root rprivate: %v", err)
+ k.fatalf(msg, "cannot make host root rprivate: %v", optionalErrorUnwrap(err))
}
if err := k.unmount(hostDir, MNT_DETACH); err != nil {
k.fatalf(msg, "cannot unmount host root: %v", err)
diff --git a/container/params.go b/container/params.go
index f9862a19..a48eabaf 100644
--- a/container/params.go
+++ b/container/params.go
@@ -31,7 +31,7 @@ func Receive(key string, e any, fdp *uintptr) (func() error, error) {
return nil, ErrReceiveEnv
} else {
if fd, err := strconv.Atoi(s); err != nil {
- return nil, errors.Unwrap(err)
+ return nil, optionalErrorUnwrap(err)
} else {
setup = os.NewFile(uintptr(fd), "setup")
if setup == nil {