diff --git a/container/errors.go b/container/errors.go index e3f4b9d..884c8a0 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 923a36e..ff72c40 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: ¶ms.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 f9862a1..a48eaba 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 {