[syserror] Change p9 server to use linuxerr.

Change the p9 server to use *errors.Error defined in pkg linuxerr. Done
separate from the client so that we ensure different p9 server/client versions
work with each other.

PiperOrigin-RevId: 380084491
This commit is contained in:
Zach Koopmans
2021-06-17 17:54:11 -07:00
committed by gVisor bot
parent bc27a99185
commit 1f2ce9f461
4 changed files with 61 additions and 6 deletions
+2 -1
View File
@@ -27,6 +27,7 @@ import (
const maxErrno uint32 = errno.EHWPOISON + 1
var (
NOERROR = errors.New(errno.NOERRNO, "not an error")
EPERM = errors.New(errno.EPERM, "operation not permitted")
ENOENT = errors.New(errno.ENOENT, "no such file or directory")
ESRCH = errors.New(errno.ESRCH, "no such process")
@@ -176,7 +177,7 @@ var errNotValidError = errors.New(errno.Errno(maxErrno), "not a valid error")
// errnos (especially uint32(sycall.Errno)) and *Error.
var errorSlice = []*errors.Error{
// Errno values from include/uapi/asm-generic/errno-base.h.
errno.NOERRNO: nil,
errno.NOERRNO: NOERROR,
errno.EPERM: EPERM,
errno.ENOENT: ENOENT,
errno.ESRCH: ESRCH,
+3
View File
@@ -22,6 +22,9 @@ go_library(
"version.go",
],
deps = [
"//pkg/abi/linux/errno",
"//pkg/errors",
"//pkg/errors/linuxerr",
"//pkg/fd",
"//pkg/fdchannel",
"//pkg/flipcall",
+42
View File
@@ -23,6 +23,9 @@ import (
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/errors"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/log"
)
@@ -62,6 +65,45 @@ func newErr(err error) *Rlerror {
return &Rlerror{Error: uint32(ExtractErrno(err))}
}
// ExtractLinuxerrErrno extracts a *errors.Error from a error, best effort.
// TODO(b/34162363): Merge this with ExtractErrno.
func ExtractLinuxerrErrno(err error) *errors.Error {
switch err {
case os.ErrNotExist:
return linuxerr.ENOENT
case os.ErrExist:
return linuxerr.EEXIST
case os.ErrPermission:
return linuxerr.EACCES
case os.ErrInvalid:
return linuxerr.EINVAL
}
// Attempt to unwrap.
switch e := err.(type) {
case *errors.Error:
return e
case unix.Errno:
return linuxerr.ErrorFromErrno(errno.Errno(e))
case *os.PathError:
return ExtractLinuxerrErrno(e.Err)
case *os.SyscallError:
return ExtractLinuxerrErrno(e.Err)
case *os.LinkError:
return ExtractLinuxerrErrno(e.Err)
}
// Default case.
log.Warningf("unknown error: %v", err)
return linuxerr.EIO
}
// newErrFromLinuxerr returns an Rlerror from the linuxerr list.
// TODO(b/34162363): Merge this with newErr.
func newErrFromLinuxerr(err error) *Rlerror {
return &Rlerror{Error: uint32(ExtractLinuxerrErrno(err).Errno())}
}
// handler is implemented for server-handled messages.
//
// See server.go for call information.
+14 -5
View File
@@ -19,7 +19,8 @@ import (
"runtime/debug"
"sync/atomic"
"golang.org/x/sys/unix"
"gvisor.dev/gvisor/pkg/abi/linux/errno"
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fd"
"gvisor.dev/gvisor/pkg/fdchannel"
"gvisor.dev/gvisor/pkg/flipcall"
@@ -483,7 +484,7 @@ func (cs *connState) lookupChannel(id uint32) *channel {
func (cs *connState) handle(m message) (r message) {
if !cs.reqGate.Enter() {
// connState.stop() has been called; the connection is shutting down.
r = newErr(unix.ECONNRESET)
r = newErrFromLinuxerr(linuxerr.ECONNRESET)
return
}
defer func() {
@@ -498,15 +499,23 @@ func (cs *connState) handle(m message) (r message) {
// Wrap in an EFAULT error; we don't really have a
// better way to describe this kind of error. It will
// usually manifest as a result of the test framework.
r = newErr(unix.EFAULT)
r = newErrFromLinuxerr(linuxerr.EFAULT)
}
}()
if handler, ok := m.(handler); ok {
// Call the message handler.
r = handler.handle(cs)
// TODO(b/34162363):This is only here to make sure the server works with
// only linuxerr Errors, as the handlers work with both client and server.
// It will be removed a followup, when all the unix.Errno errors are
// replaced with linuxerr.
if rlError, ok := r.(*Rlerror); ok {
e := linuxerr.ErrorFromErrno(errno.Errno(rlError.Error))
r = newErrFromLinuxerr(e)
}
} else {
// Produce an ENOSYS error.
r = newErr(unix.ENOSYS)
r = newErrFromLinuxerr(linuxerr.ENOSYS)
}
return
}
@@ -553,7 +562,7 @@ func (cs *connState) handleRequest() bool {
// If it's not a connection error, but some other protocol error,
// we can send a response immediately.
cs.sendMu.Lock()
err := send(cs.conn, tag, newErr(err))
err := send(cs.conn, tag, newErrFromLinuxerr(err))
cs.sendMu.Unlock()
if err != nil {
log.Debugf("p9.send: %v", err)