mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
[syserror] Add linuxerr package.
Add linuxerr package to replace syserror and syserr errors. This is done to improve performance comparing/returning errors to on par with syscall.Errno. The below linuxerr_test (formerly syserror_test) shows linuxerr.Error on par with unix.Error (syscall.Errno) as desired. BenchmarkAssignErrno BenchmarkAssignErrno-6 1000000000 0.6291 ns/op BenchmarkLinuxerrAssignError BenchmarkLinuxerrAssignError-6 1000000000 0.5808 ns/op BenchmarkAssignSyserrorError BenchmarkAssignSyserrorError-6 1000000000 0.6188 ns/op BenchmarkCompareErrno BenchmarkCompareErrno-6 1000000000 0.5041 ns/op BenchmarkCompareLinuxerrError BenchmarkCompareLinuxerrError-6 1000000000 0.4660 ns/op BenchmarkCompareSyserrorError BenchmarkCompareSyserrorError-6 309026907 3.386 ns/op BenchmarkSwitchErrno BenchmarkSwitchErrno-6 722253750 1.440 ns/op BenchmarkSwitchLinuxerrError BenchmarkSwitchLinuxerrError-6 709108542 1.453 ns/op BenchmarkSwitchSyserrorError BenchmarkSwitchSyserrorError-6 106331331 11.21 ns/op PiperOrigin-RevId: 374507431
This commit is contained in:
committed by
gVisor bot
parent
5d04e0ae33
commit
8ff6694e54
@@ -0,0 +1,20 @@
|
||||
load("//tools:defs.bzl", "go_library", "go_test")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
go_library(
|
||||
name = "linuxerr",
|
||||
srcs = ["linuxerr.go"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//pkg/abi/linux"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "linuxerr_test",
|
||||
srcs = ["linuxerr_test.go"],
|
||||
deps = [
|
||||
":linuxerr",
|
||||
"//pkg/syserror",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,184 @@
|
||||
// Copyright 2021 The gVisor Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package linuxerr contains syscall error codes exported as an error interface
|
||||
// pointers. This allows for fast comparison and return operations comperable
|
||||
// to unix.Errno constants.
|
||||
package linuxerr
|
||||
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
)
|
||||
|
||||
// Error represents a syscall errno with a descriptive message.
|
||||
type Error struct {
|
||||
errno linux.Errno
|
||||
message string
|
||||
}
|
||||
|
||||
func new(err linux.Errno, message string) *Error {
|
||||
return &Error{
|
||||
errno: err,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
// Error implements error.Error.
|
||||
func (e *Error) Error() string { return e.message }
|
||||
|
||||
// Errno returns the underlying linux.Errno value.
|
||||
func (e *Error) Errno() linux.Errno { return e.errno }
|
||||
|
||||
// The following varables have the same meaning as their errno equivalent.
|
||||
|
||||
// Errno values from include/uapi/asm-generic/errno-base.h.
|
||||
var (
|
||||
EPERM = new(linux.EPERM, "operation not permitted")
|
||||
ENOENT = new(linux.ENOENT, "no such file or directory")
|
||||
ESRCH = new(linux.ESRCH, "no such process")
|
||||
EINTR = new(linux.EINTR, "interrupted system call")
|
||||
EIO = new(linux.EIO, "I/O error")
|
||||
ENXIO = new(linux.ENXIO, "no such device or address")
|
||||
E2BIG = new(linux.E2BIG, "argument list too long")
|
||||
ENOEXEC = new(linux.ENOEXEC, "exec format error")
|
||||
EBADF = new(linux.EBADF, "bad file number")
|
||||
ECHILD = new(linux.ECHILD, "no child processes")
|
||||
EAGAIN = new(linux.EAGAIN, "try again")
|
||||
ENOMEM = new(linux.ENOMEM, "out of memory")
|
||||
EACCES = new(linux.EACCES, "permission denied")
|
||||
EFAULT = new(linux.EFAULT, "bad address")
|
||||
ENOTBLK = new(linux.ENOTBLK, "block device required")
|
||||
EBUSY = new(linux.EBUSY, "device or resource busy")
|
||||
EEXIST = new(linux.EEXIST, "file exists")
|
||||
EXDEV = new(linux.EXDEV, "cross-device link")
|
||||
ENODEV = new(linux.ENODEV, "no such device")
|
||||
ENOTDIR = new(linux.ENOTDIR, "not a directory")
|
||||
EISDIR = new(linux.EISDIR, "is a directory")
|
||||
EINVAL = new(linux.EINVAL, "invalid argument")
|
||||
ENFILE = new(linux.ENFILE, "file table overflow")
|
||||
EMFILE = new(linux.EMFILE, "too many open files")
|
||||
ENOTTY = new(linux.ENOTTY, "not a typewriter")
|
||||
ETXTBSY = new(linux.ETXTBSY, "text file busy")
|
||||
EFBIG = new(linux.EFBIG, "file too large")
|
||||
ENOSPC = new(linux.ENOSPC, "no space left on device")
|
||||
ESPIPE = new(linux.ESPIPE, "illegal seek")
|
||||
EROFS = new(linux.EROFS, "read-only file system")
|
||||
EMLINK = new(linux.EMLINK, "too many links")
|
||||
EPIPE = new(linux.EPIPE, "broken pipe")
|
||||
EDOM = new(linux.EDOM, "math argument out of domain of func")
|
||||
ERANGE = new(linux.ERANGE, "math result not representable")
|
||||
)
|
||||
|
||||
// Errno values from include/uapi/asm-generic/errno.h.
|
||||
var (
|
||||
EDEADLK = new(linux.EDEADLK, "resource deadlock would occur")
|
||||
ENAMETOOLONG = new(linux.ENAMETOOLONG, "file name too long")
|
||||
ENOLCK = new(linux.ENOLCK, "no record locks available")
|
||||
ENOSYS = new(linux.ENOSYS, "invalid system call number")
|
||||
ENOTEMPTY = new(linux.ENOTEMPTY, "directory not empty")
|
||||
ELOOP = new(linux.ELOOP, "too many symbolic links encountered")
|
||||
EWOULDBLOCK = new(linux.EWOULDBLOCK, "operation would block")
|
||||
ENOMSG = new(linux.ENOMSG, "no message of desired type")
|
||||
EIDRM = new(linux.EIDRM, "identifier removed")
|
||||
ECHRNG = new(linux.ECHRNG, "channel number out of range")
|
||||
EL2NSYNC = new(linux.EL2NSYNC, "level 2 not synchronized")
|
||||
EL3HLT = new(linux.EL3HLT, "level 3 halted")
|
||||
EL3RST = new(linux.EL3RST, "level 3 reset")
|
||||
ELNRNG = new(linux.ELNRNG, "link number out of range")
|
||||
EUNATCH = new(linux.EUNATCH, "protocol driver not attached")
|
||||
ENOCSI = new(linux.ENOCSI, "no CSI structure available")
|
||||
EL2HLT = new(linux.EL2HLT, "level 2 halted")
|
||||
EBADE = new(linux.EBADE, "invalid exchange")
|
||||
EBADR = new(linux.EBADR, "invalid request descriptor")
|
||||
EXFULL = new(linux.EXFULL, "exchange full")
|
||||
ENOANO = new(linux.ENOANO, "no anode")
|
||||
EBADRQC = new(linux.EBADRQC, "invalid request code")
|
||||
EBADSLT = new(linux.EBADSLT, "invalid slot")
|
||||
EDEADLOCK = new(linux.EDEADLOCK, EDEADLK.message)
|
||||
EBFONT = new(linux.EBFONT, "bad font file format")
|
||||
ENOSTR = new(linux.ENOSTR, "device not a stream")
|
||||
ENODATA = new(linux.ENODATA, "no data available")
|
||||
ETIME = new(linux.ETIME, "timer expired")
|
||||
ENOSR = new(linux.ENOSR, "out of streams resources")
|
||||
ENONET = new(linux.ENOENT, "machine is not on the network")
|
||||
ENOPKG = new(linux.ENOPKG, "package not installed")
|
||||
EREMOTE = new(linux.EREMOTE, "object is remote")
|
||||
ENOLINK = new(linux.ENOLINK, "link has been severed")
|
||||
EADV = new(linux.EADV, "advertise error")
|
||||
ESRMNT = new(linux.ESRMNT, "srmount error")
|
||||
ECOMM = new(linux.ECOMM, "communication error on send")
|
||||
EPROTO = new(linux.EPROTO, "protocol error")
|
||||
EMULTIHOP = new(linux.EMULTIHOP, "multihop attempted")
|
||||
EDOTDOT = new(linux.EDOTDOT, "RFS specific error")
|
||||
EBADMSG = new(linux.EBADMSG, "not a data message")
|
||||
EOVERFLOW = new(linux.EOVERFLOW, "value too large for defined data type")
|
||||
ENOTUNIQ = new(linux.ENOTUNIQ, "name not unique on network")
|
||||
EBADFD = new(linux.EBADFD, "file descriptor in bad state")
|
||||
EREMCHG = new(linux.EREMCHG, "remote address changed")
|
||||
ELIBACC = new(linux.ELIBACC, "can not access a needed shared library")
|
||||
ELIBBAD = new(linux.ELIBBAD, "accessing a corrupted shared library")
|
||||
ELIBSCN = new(linux.ELIBSCN, ".lib section in a.out corrupted")
|
||||
ELIBMAX = new(linux.ELIBMAX, "attempting to link in too many shared libraries")
|
||||
ELIBEXEC = new(linux.ELIBEXEC, "cannot exec a shared library directly")
|
||||
EILSEQ = new(linux.EILSEQ, "illegal byte sequence")
|
||||
ERESTART = new(linux.ERESTART, "interrupted system call should be restarted")
|
||||
ESTRPIPE = new(linux.ESTRPIPE, "streams pipe error")
|
||||
EUSERS = new(linux.EUSERS, "too many users")
|
||||
ENOTSOCK = new(linux.ENOTSOCK, "socket operation on non-socket")
|
||||
EDESTADDRREQ = new(linux.EDESTADDRREQ, "destination address required")
|
||||
EMSGSIZE = new(linux.EMSGSIZE, "message too long")
|
||||
EPROTOTYPE = new(linux.EPROTOTYPE, "protocol wrong type for socket")
|
||||
ENOPROTOOPT = new(linux.ENOPROTOOPT, "protocol not available")
|
||||
EPROTONOSUPPORT = new(linux.EPROTONOSUPPORT, "protocol not supported")
|
||||
ESOCKTNOSUPPORT = new(linux.ESOCKTNOSUPPORT, "socket type not supported")
|
||||
EOPNOTSUPP = new(linux.EOPNOTSUPP, "operation not supported on transport endpoint")
|
||||
EPFNOSUPPORT = new(linux.EPFNOSUPPORT, "protocol family not supported")
|
||||
EAFNOSUPPORT = new(linux.EAFNOSUPPORT, "address family not supported by protocol")
|
||||
EADDRINUSE = new(linux.EADDRINUSE, "address already in use")
|
||||
EADDRNOTAVAIL = new(linux.EADDRNOTAVAIL, "cannot assign requested address")
|
||||
ENETDOWN = new(linux.ENETDOWN, "network is down")
|
||||
ENETUNREACH = new(linux.ENETUNREACH, "network is unreachable")
|
||||
ENETRESET = new(linux.ENETRESET, "network dropped connection because of reset")
|
||||
ECONNABORTED = new(linux.ECONNABORTED, "software caused connection abort")
|
||||
ECONNRESET = new(linux.ECONNRESET, "connection reset by peer")
|
||||
ENOBUFS = new(linux.ENOBUFS, "no buffer space available")
|
||||
EISCONN = new(linux.EISCONN, "transport endpoint is already connected")
|
||||
ENOTCONN = new(linux.ENOTCONN, "transport endpoint is not connected")
|
||||
ESHUTDOWN = new(linux.ESHUTDOWN, "cannot send after transport endpoint shutdown")
|
||||
ETOOMANYREFS = new(linux.ETOOMANYREFS, "too many references: cannot splice")
|
||||
ETIMEDOUT = new(linux.ETIMEDOUT, "connection timed out")
|
||||
ECONNREFUSED = new(linux.ECONNREFUSED, "connection refused")
|
||||
EHOSTDOWN = new(linux.EHOSTDOWN, "host is down")
|
||||
EHOSTUNREACH = new(linux.EHOSTUNREACH, "no route to host")
|
||||
EALREADY = new(linux.EALREADY, "operation already in progress")
|
||||
EINPROGRESS = new(linux.EINPROGRESS, "operation now in progress")
|
||||
ESTALE = new(linux.ESTALE, "stale file handle")
|
||||
EUCLEAN = new(linux.EUCLEAN, "structure needs cleaning")
|
||||
ENOTNAM = new(linux.ENOTNAM, "not a XENIX named type file")
|
||||
ENAVAIL = new(linux.ENAVAIL, "no XENIX semaphores available")
|
||||
EISNAM = new(linux.EISNAM, "is a named type file")
|
||||
EREMOTEIO = new(linux.EREMOTEIO, "remote I/O error")
|
||||
EDQUOT = new(linux.EDQUOT, "quota exceeded")
|
||||
ENOMEDIUM = new(linux.ENOMEDIUM, "no medium found")
|
||||
EMEDIUMTYPE = new(linux.EMEDIUMTYPE, "wrong medium type")
|
||||
ECANCELED = new(linux.ECANCELED, "operation Canceled")
|
||||
ENOKEY = new(linux.ENOKEY, "required key not available")
|
||||
EKEYEXPIRED = new(linux.EKEYEXPIRED, "key has expired")
|
||||
EKEYREVOKED = new(linux.EKEYREVOKED, "key has been revoked")
|
||||
EKEYREJECTED = new(linux.EKEYREJECTED, "key was rejected by service")
|
||||
EOWNERDEAD = new(linux.EOWNERDEAD, "owner died")
|
||||
ENOTRECOVERABLE = new(linux.ENOTRECOVERABLE, "state not recoverable")
|
||||
ERFKILL = new(linux.ERFKILL, "operation not possible due to RF-kill")
|
||||
EHWPOISON = new(linux.EHWPOISON, "memory page has hardware error")
|
||||
)
|
||||
@@ -19,6 +19,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/linuxerr"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
|
||||
@@ -30,7 +31,13 @@ func BenchmarkAssignErrno(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAssignError(b *testing.B) {
|
||||
func BenchmarkLinuxerrAssignError(b *testing.B) {
|
||||
for i := b.N; i > 0; i-- {
|
||||
globalError = linuxerr.EINVAL
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAssignSyserrorError(b *testing.B) {
|
||||
for i := b.N; i > 0; i-- {
|
||||
globalError = syserror.EINVAL
|
||||
}
|
||||
@@ -46,7 +53,17 @@ func BenchmarkCompareErrno(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCompareError(b *testing.B) {
|
||||
func BenchmarkCompareLinuxerrError(b *testing.B) {
|
||||
globalError = linuxerr.E2BIG
|
||||
j := 0
|
||||
for i := b.N; i > 0; i-- {
|
||||
if globalError == linuxerr.EINVAL {
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkCompareSyserrorError(b *testing.B) {
|
||||
globalError = syserror.EAGAIN
|
||||
j := 0
|
||||
for i := b.N; i > 0; i-- {
|
||||
@@ -62,7 +79,7 @@ func BenchmarkSwitchErrno(b *testing.B) {
|
||||
for i := b.N; i > 0; i-- {
|
||||
switch globalError {
|
||||
case unix.EINVAL:
|
||||
j += 1
|
||||
j++
|
||||
case unix.EINTR:
|
||||
j += 2
|
||||
case unix.EAGAIN:
|
||||
@@ -71,13 +88,28 @@ func BenchmarkSwitchErrno(b *testing.B) {
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSwitchError(b *testing.B) {
|
||||
func BenchmarkSwitchLinuxerrError(b *testing.B) {
|
||||
globalError = linuxerr.EPERM
|
||||
j := 0
|
||||
for i := b.N; i > 0; i-- {
|
||||
switch globalError {
|
||||
case linuxerr.EINVAL:
|
||||
j++
|
||||
case linuxerr.EINTR:
|
||||
j += 2
|
||||
case linuxerr.EAGAIN:
|
||||
j += 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSwitchSyserrorError(b *testing.B) {
|
||||
globalError = syserror.EPERM
|
||||
j := 0
|
||||
for i := b.N; i > 0; i-- {
|
||||
switch globalError {
|
||||
case syserror.EINVAL:
|
||||
j += 1
|
||||
j++
|
||||
case syserror.EINTR:
|
||||
j += 2
|
||||
case syserror.EAGAIN:
|
||||
+1
-10
@@ -1,4 +1,4 @@
|
||||
load("//tools:defs.bzl", "go_library", "go_test")
|
||||
load("//tools:defs.bzl", "go_library")
|
||||
|
||||
package(licenses = ["notice"])
|
||||
|
||||
@@ -8,12 +8,3 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@org_golang_x_sys//unix:go_default_library"],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "syserror_test",
|
||||
srcs = ["syserror_test.go"],
|
||||
deps = [
|
||||
":syserror",
|
||||
"@org_golang_x_sys//unix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user