From a9441aea2780da8c93da1c73da860219f98438de Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Wed, 3 Mar 2021 10:23:55 -0800 Subject: [op] Replace syscall package usage with golang.org/x/sys/unix in pkg/. The syscall package has been deprecated in favor of golang.org/x/sys. Note that syscall is still used in the following places: - pkg/sentry/socket/hostinet/stack.go: some netlink related functionalities are not yet available in golang.org/x/sys. - syscall.Stat_t is still used in some places because os.FileInfo.Sys() still returns it and not unix.Stat_t. Updates #214 PiperOrigin-RevId: 360701387 --- pkg/unet/BUILD | 5 ++- pkg/unet/unet.go | 88 ++++++++++++++++++++++++------------------------- pkg/unet/unet_test.go | 20 +++++------ pkg/unet/unet_unsafe.go | 55 +++++++++++++++---------------- 4 files changed, 85 insertions(+), 83 deletions(-) (limited to 'pkg/unet') diff --git a/pkg/unet/BUILD b/pkg/unet/BUILD index 155d99a0d..234125c38 100644 --- a/pkg/unet/BUILD +++ b/pkg/unet/BUILD @@ -22,5 +22,8 @@ go_test( "unet_test.go", ], library = ":unet", - deps = ["//pkg/sync"], + deps = [ + "//pkg/sync", + "@org_golang_x_sys//unix:go_default_library", + ], ) diff --git a/pkg/unet/unet.go b/pkg/unet/unet.go index 22dd40f21..40fa72925 100644 --- a/pkg/unet/unet.go +++ b/pkg/unet/unet.go @@ -21,8 +21,8 @@ package unet import ( "errors" "sync/atomic" - "syscall" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/sync" ) @@ -39,15 +39,15 @@ var errMessageTruncated = errors.New("message truncated") // socketType returns the appropriate type. func socketType(packet bool) int { if packet { - return syscall.SOCK_SEQPACKET + return unix.SOCK_SEQPACKET } - return syscall.SOCK_STREAM + return unix.SOCK_STREAM } // socket creates a new host socket. func socket(packet bool) (int, error) { // Make a new socket. - fd, err := syscall.Socket(syscall.AF_UNIX, socketType(packet), 0) + fd, err := unix.Socket(unix.AF_UNIX, socketType(packet), 0) if err != nil { return 0, err } @@ -57,7 +57,7 @@ func socket(packet bool) (int, error) { // eventFD returns a new event FD with initial value 0. func eventFD() (int, error) { - f, _, e := syscall.Syscall(syscall.SYS_EVENTFD2, 0, 0, 0) + f, _, e := unix.Syscall(unix.SYS_EVENTFD2, 0, 0, 0) if e != 0 { return -1, e } @@ -89,9 +89,9 @@ type Socket struct { // // NewSocket takes ownership of fd. func NewSocket(fd int) (*Socket, error) { - // fd must be non-blocking for non-blocking syscall.Accept in + // fd must be non-blocking for non-blocking unix.Accept in // ServerSocket.Accept. - if err := syscall.SetNonblock(fd, true); err != nil { + if err := unix.SetNonblock(fd, true); err != nil { return nil, err } @@ -112,14 +112,14 @@ func (s *Socket) finish() error { // Signal any blocked or future polls. // // N.B. eventfd writes must be 8 bytes. - if _, err := syscall.Write(s.efd, []byte{1, 0, 0, 0, 0, 0, 0, 0}); err != nil { + if _, err := unix.Write(s.efd, []byte{1, 0, 0, 0, 0, 0, 0, 0}); err != nil { return err } // Close the gate, blocking until all FD users leave. s.gate.Close() - return syscall.Close(s.efd) + return unix.Close(s.efd) } // Close closes the socket. @@ -129,7 +129,7 @@ func (s *Socket) Close() error { fd := int(atomic.SwapInt32(&s.fd, -1)) if fd < 0 { // Already closed or closing. - return syscall.EBADF + return unix.EBADF } // Shutdown the socket to cancel any pending accepts. @@ -139,7 +139,7 @@ func (s *Socket) Close() error { return err } - return syscall.Close(fd) + return unix.Close(fd) } // Release releases ownership of the socket FD. @@ -153,7 +153,7 @@ func (s *Socket) Release() (int, error) { fd := int(atomic.SwapInt32(&s.fd, -1)) if fd < 0 { // Already closed or closing. - return -1, syscall.EBADF + return -1, unix.EBADF } if err := s.finish(); err != nil { @@ -201,7 +201,7 @@ func (s *Socket) enterFD() (int, bool) { // SocketPair creates a pair of connected sockets. func SocketPair(packet bool) (*Socket, *Socket, error) { // Make a new pair. - fds, err := syscall.Socketpair(syscall.AF_UNIX, socketType(packet)|syscall.SOCK_CLOEXEC, 0) + fds, err := unix.Socketpair(unix.AF_UNIX, socketType(packet)|unix.SOCK_CLOEXEC, 0) if err != nil { return nil, nil, err } @@ -216,15 +216,15 @@ func SocketPair(packet bool) (*Socket, *Socket, error) { var race int32 a, err := NewSocket(fds[0]) if err != nil { - syscall.Close(fds[0]) - syscall.Close(fds[1]) + unix.Close(fds[0]) + unix.Close(fds[1]) return nil, nil, err } a.race = &race b, err := NewSocket(fds[1]) if err != nil { a.Close() - syscall.Close(fds[1]) + unix.Close(fds[1]) return nil, nil, err } b.race = &race @@ -239,9 +239,9 @@ func Connect(addr string, packet bool) (*Socket, error) { } // Connect the socket. - usa := &syscall.SockaddrUnix{Name: addr} - if err := syscall.Connect(fd, usa); err != nil { - syscall.Close(fd) + usa := &unix.SockaddrUnix{Name: addr} + if err := unix.Connect(fd, usa); err != nil { + unix.Close(fd) return nil, err } @@ -260,20 +260,20 @@ type ControlMessage []byte // // This must be called prior to ReadVec if you want to receive FDs. func (c *ControlMessage) EnableFDs(count int) { - *c = make([]byte, syscall.CmsgSpace(count*4)) + *c = make([]byte, unix.CmsgSpace(count*4)) } // ExtractFDs returns the list of FDs in the control message. // // Either this or CloseFDs should be used after EnableFDs. func (c *ControlMessage) ExtractFDs() ([]int, error) { - msgs, err := syscall.ParseSocketControlMessage(*c) + msgs, err := unix.ParseSocketControlMessage(*c) if err != nil { return nil, err } var fds []int for _, msg := range msgs { - thisFds, err := syscall.ParseUnixRights(&msg) + thisFds, err := unix.ParseUnixRights(&msg) if err != nil { // Different control message. return nil, err @@ -294,7 +294,7 @@ func (c *ControlMessage) CloseFDs() { fds, _ := c.ExtractFDs() for _, fd := range fds { if fd >= 0 { - syscall.Close(fd) + unix.Close(fd) } } } @@ -303,7 +303,7 @@ func (c *ControlMessage) CloseFDs() { // // This must be used prior to WriteVec. func (c *ControlMessage) PackFDs(fds ...int) { - *c = ControlMessage(syscall.UnixRights(fds...)) + *c = ControlMessage(unix.UnixRights(fds...)) } // UnpackFDs clears the control message. @@ -338,7 +338,7 @@ func (s *Socket) Write(p []byte) (int, error) { func (s *Socket) GetSockOpt(level int, name int, b []byte) (uint32, error) { fd, ok := s.enterFD() if !ok { - return 0, syscall.EBADF + return 0, unix.EBADF } defer s.gate.Leave() @@ -349,7 +349,7 @@ func (s *Socket) GetSockOpt(level int, name int, b []byte) (uint32, error) { func (s *Socket) SetSockOpt(level, name int, b []byte) error { fd, ok := s.enterFD() if !ok { - return syscall.EBADF + return unix.EBADF } defer s.gate.Leave() @@ -360,12 +360,12 @@ func (s *Socket) SetSockOpt(level, name int, b []byte) error { func (s *Socket) GetSockName() ([]byte, error) { fd, ok := s.enterFD() if !ok { - return nil, syscall.EBADF + return nil, unix.EBADF } defer s.gate.Leave() var buf []byte - l := syscall.SizeofSockaddrAny + l := unix.SizeofSockaddrAny for { // If the buffer is not large enough, allocate a new one with the hint. @@ -385,12 +385,12 @@ func (s *Socket) GetSockName() ([]byte, error) { func (s *Socket) GetPeerName() ([]byte, error) { fd, ok := s.enterFD() if !ok { - return nil, syscall.EBADF + return nil, unix.EBADF } defer s.gate.Leave() var buf []byte - l := syscall.SizeofSockaddrAny + l := unix.SizeofSockaddrAny for { // See above. @@ -407,14 +407,14 @@ func (s *Socket) GetPeerName() ([]byte, error) { } // GetPeerCred returns the peer's unix credentials. -func (s *Socket) GetPeerCred() (*syscall.Ucred, error) { +func (s *Socket) GetPeerCred() (*unix.Ucred, error) { fd, ok := s.enterFD() if !ok { - return nil, syscall.EBADF + return nil, unix.EBADF } defer s.gate.Leave() - return syscall.GetsockoptUcred(fd, syscall.SOL_SOCKET, syscall.SO_PEERCRED) + return unix.GetsockoptUcred(fd, unix.SOL_SOCKET, unix.SO_PEERCRED) } // SocketReader wraps an individual receive operation. @@ -445,14 +445,14 @@ func (s *Socket) Read(p []byte) (int, error) { func (s *Socket) shutdown(fd int) error { // Shutdown the socket to cancel any pending accepts. - return syscall.Shutdown(fd, syscall.SHUT_RDWR) + return unix.Shutdown(fd, unix.SHUT_RDWR) } // Shutdown closes the socket for read and write. func (s *Socket) Shutdown() error { fd, ok := s.enterFD() if !ok { - return syscall.EBADF + return unix.EBADF } defer s.gate.Leave() @@ -481,9 +481,9 @@ func Bind(addr string, packet bool) (*ServerSocket, error) { } // Do the bind. - usa := &syscall.SockaddrUnix{Name: addr} - if err := syscall.Bind(fd, usa); err != nil { - syscall.Close(fd) + usa := &unix.SockaddrUnix{Name: addr} + if err := unix.Bind(fd, usa); err != nil { + unix.Close(fd) return nil, err } @@ -510,11 +510,11 @@ func BindAndListen(addr string, packet bool) (*ServerSocket, error) { func (s *ServerSocket) Listen() error { fd, ok := s.socket.enterFD() if !ok { - return syscall.EBADF + return unix.EBADF } defer s.socket.gate.Leave() - return syscall.Listen(fd, backlog) + return unix.Listen(fd, backlog) } // Accept accepts a new connection. @@ -526,19 +526,19 @@ func (s *ServerSocket) Listen() error { func (s *ServerSocket) Accept() (*Socket, error) { fd, ok := s.socket.enterFD() if !ok { - return nil, syscall.EBADF + return nil, unix.EBADF } defer s.socket.gate.Leave() for { - nfd, _, err := syscall.Accept(fd) + nfd, _, err := unix.Accept(fd) switch err { case nil: return NewSocket(nfd) - case syscall.EAGAIN: + case unix.EAGAIN: err = s.socket.wait(false) if err == errClosing { - err = syscall.EBADF + err = unix.EBADF } } if err != nil { diff --git a/pkg/unet/unet_test.go b/pkg/unet/unet_test.go index a38ffc19d..9875a3cda 100644 --- a/pkg/unet/unet_test.go +++ b/pkg/unet/unet_test.go @@ -19,10 +19,10 @@ import ( "os" "path/filepath" "reflect" - "syscall" "testing" "time" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/sync" ) @@ -291,7 +291,7 @@ func TestNonBlockingSend(t *testing.T) { for i := 0; i < 1000; i++ { w := client.Writer(false) if n, err := w.WriteVec([][]byte{make([]byte, 1000)}); n != 1000 || err != nil { - if err == syscall.EWOULDBLOCK || err == syscall.EAGAIN { + if err == unix.EWOULDBLOCK || err == unix.EAGAIN { // We're good. That's what we wanted. blockCount++ } else { @@ -319,7 +319,7 @@ func TestNonBlockingRecv(t *testing.T) { // Expected to block immediately. _, err := r.ReadVec(b) - if err != syscall.EWOULDBLOCK && err != syscall.EAGAIN { + if err != unix.EWOULDBLOCK && err != unix.EAGAIN { t.Fatalf("Read didn't block, got err %v expected blocking err", err) } @@ -337,7 +337,7 @@ func TestNonBlockingRecv(t *testing.T) { // Expect it to return a block error again. r = client.Reader(false) _, err = r.ReadVec(b) - if err != syscall.EWOULDBLOCK && err != syscall.EAGAIN { + if err != unix.EWOULDBLOCK && err != unix.EAGAIN { t.Fatalf("Read didn't block, got err %v expected blocking err", err) } } @@ -469,8 +469,8 @@ func recvFDs(t *testing.T, s *Socket, enableSize int, origFDs []int) { // Make sure they can be accessed as expected. for i := 0; i < len(fds); i++ { - var st syscall.Stat_t - if err := syscall.Fstat(fds[i], &st); err != nil { + var st unix.Stat_t + if err := unix.Fstat(fds[i], &st); err != nil { t.Errorf("fds[%d] can't be stated, got err %v expected nil", i, err) } } @@ -561,7 +561,7 @@ func TestGetPeerCred(t *testing.T) { defer server.Close() defer client.Close() - want := &syscall.Ucred{ + want := &unix.Ucred{ Pid: int32(os.Getpid()), Uid: uint32(os.Getuid()), Gid: uint32(os.Getgid()), @@ -573,14 +573,14 @@ func TestGetPeerCred(t *testing.T) { } func newClosedSocket() (*Socket, error) { - fd, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0) + fd, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0) if err != nil { return nil, err } s, err := NewSocket(fd) if err != nil { - syscall.Close(fd) + unix.Close(fd) return nil, err } @@ -667,7 +667,7 @@ func TestReleaseAfterAcceptStart(t *testing.T) { if err != nil { t.Errorf("Release failed, got err %v expected nil", err) } - syscall.Close(fd) + unix.Close(fd) }() if _, err := ss.Accept(); err == nil { diff --git a/pkg/unet/unet_unsafe.go b/pkg/unet/unet_unsafe.go index 85ef46edf..f0bf93ddd 100644 --- a/pkg/unet/unet_unsafe.go +++ b/pkg/unet/unet_unsafe.go @@ -17,7 +17,6 @@ package unet import ( "io" "sync/atomic" - "syscall" "unsafe" "golang.org/x/sys/unix" @@ -52,8 +51,8 @@ func (s *Socket) wait(write bool) error { events[0].Events = unix.POLLOUT } - _, _, e := syscall.Syscall6(syscall.SYS_PPOLL, uintptr(unsafe.Pointer(&events[0])), 2, 0, 0, 0, 0) - if e == syscall.EINTR { + _, _, e := unix.Syscall6(unix.SYS_PPOLL, uintptr(unsafe.Pointer(&events[0])), 2, 0, 0, 0, 0) + if e == unix.EINTR { continue } if e != 0 { @@ -72,11 +71,11 @@ func (s *Socket) wait(write bool) error { // buildIovec builds an iovec slice from the given []byte slice. // // iovecs is used as an initial slice, to avoid excessive allocations. -func buildIovec(bufs [][]byte, iovecs []syscall.Iovec) ([]syscall.Iovec, int) { +func buildIovec(bufs [][]byte, iovecs []unix.Iovec) ([]unix.Iovec, int) { var length int for i := range bufs { if l := len(bufs[i]); l > 0 { - iovecs = append(iovecs, syscall.Iovec{ + iovecs = append(iovecs, unix.Iovec{ Base: &bufs[i][0], Len: uint64(l), }) @@ -93,9 +92,9 @@ func buildIovec(bufs [][]byte, iovecs []syscall.Iovec) ([]syscall.Iovec, int) { // This function is not guaranteed to read all available data, it // returns as soon as a single recvmsg call succeeds. func (r *SocketReader) ReadVec(bufs [][]byte) (int, error) { - iovecs, length := buildIovec(bufs, make([]syscall.Iovec, 0, 2)) + iovecs, length := buildIovec(bufs, make([]unix.Iovec, 0, 2)) - var msg syscall.Msghdr + var msg unix.Msghdr if len(r.source) != 0 { msg.Name = &r.source[0] msg.Namelen = uint32(len(r.source)) @@ -116,25 +115,25 @@ func (r *SocketReader) ReadVec(bufs [][]byte) (int, error) { fd, ok := r.socket.enterFD() if !ok { - return 0, syscall.EBADF + return 0, unix.EBADF } // Leave on returns below. for { - var e syscall.Errno + var e unix.Errno // Try a non-blocking recv first, so we don't give up the go runtime M. - n, _, e = syscall.RawSyscall(syscall.SYS_RECVMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), syscall.MSG_DONTWAIT|syscall.MSG_TRUNC) + n, _, e = unix.RawSyscall(unix.SYS_RECVMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), unix.MSG_DONTWAIT|unix.MSG_TRUNC) if e == 0 { break } - if e == syscall.EINTR { + if e == unix.EINTR { continue } if !r.blocking { r.socket.gate.Leave() return 0, e } - if e != syscall.EAGAIN && e != syscall.EWOULDBLOCK { + if e != unix.EAGAIN && e != unix.EWOULDBLOCK { r.socket.gate.Leave() return 0, e } @@ -142,7 +141,7 @@ func (r *SocketReader) ReadVec(bufs [][]byte) (int, error) { // Wait for the socket to become readable. err := r.socket.wait(false) if err == errClosing { - err = syscall.EBADF + err = unix.EBADF } if err != nil { r.socket.gate.Leave() @@ -184,14 +183,14 @@ func (r *SocketReader) ReadVec(bufs [][]byte) (int, error) { // This function is not guaranteed to send all data, it returns // as soon as a single sendmsg call succeeds. func (w *SocketWriter) WriteVec(bufs [][]byte) (int, error) { - iovecs, _ := buildIovec(bufs, make([]syscall.Iovec, 0, 2)) + iovecs, _ := buildIovec(bufs, make([]unix.Iovec, 0, 2)) if w.race != nil { // See comments on Socket.race. atomic.AddInt32(w.race, 1) } - var msg syscall.Msghdr + var msg unix.Msghdr if len(w.to) != 0 { msg.Name = &w.to[0] msg.Namelen = uint32(len(w.to)) @@ -209,24 +208,24 @@ func (w *SocketWriter) WriteVec(bufs [][]byte) (int, error) { fd, ok := w.socket.enterFD() if !ok { - return 0, syscall.EBADF + return 0, unix.EBADF } // Leave on returns below. for { // Try a non-blocking send first, so we don't give up the go runtime M. - n, _, e := syscall.RawSyscall(syscall.SYS_SENDMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), syscall.MSG_DONTWAIT|syscall.MSG_NOSIGNAL) + n, _, e := unix.RawSyscall(unix.SYS_SENDMSG, uintptr(fd), uintptr(unsafe.Pointer(&msg)), unix.MSG_DONTWAIT|unix.MSG_NOSIGNAL) if e == 0 { w.socket.gate.Leave() return int(n), nil } - if e == syscall.EINTR { + if e == unix.EINTR { continue } if !w.blocking { w.socket.gate.Leave() return 0, e } - if e != syscall.EAGAIN && e != syscall.EWOULDBLOCK { + if e != unix.EAGAIN && e != unix.EWOULDBLOCK { w.socket.gate.Leave() return 0, e } @@ -234,7 +233,7 @@ func (w *SocketWriter) WriteVec(bufs [][]byte) (int, error) { // Wait for the socket to become writeable. err := w.socket.wait(true) if err == errClosing { - err = syscall.EBADF + err = unix.EBADF } if err != nil { w.socket.gate.Leave() @@ -244,10 +243,10 @@ func (w *SocketWriter) WriteVec(bufs [][]byte) (int, error) { // Unreachable, no s.gate.Leave needed. } -// getsockopt issues a getsockopt syscall. +// getsockopt issues a getsockopt unix. func getsockopt(fd int, level int, optname int, buf []byte) (uint32, error) { l := uint32(len(buf)) - _, _, e := syscall.RawSyscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&l)), 0) + _, _, e := unix.RawSyscall6(unix.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&l)), 0) if e != 0 { return 0, e } @@ -255,9 +254,9 @@ func getsockopt(fd int, level int, optname int, buf []byte) (uint32, error) { return l, nil } -// setsockopt issues a setsockopt syscall. +// setsockopt issues a setsockopt unix. func setsockopt(fd int, level int, optname int, buf []byte) error { - _, _, e := syscall.RawSyscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0) + _, _, e := unix.RawSyscall6(unix.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0) if e != 0 { return e } @@ -265,10 +264,10 @@ func setsockopt(fd int, level int, optname int, buf []byte) error { return nil } -// getsockname issues a getsockname syscall. +// getsockname issues a getsockname unix. func getsockname(fd int, buf []byte) (uint32, error) { l := uint32(len(buf)) - _, _, e := syscall.RawSyscall(syscall.SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&l))) + _, _, e := unix.RawSyscall(unix.SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&l))) if e != 0 { return 0, e } @@ -276,10 +275,10 @@ func getsockname(fd int, buf []byte) (uint32, error) { return l, nil } -// getpeername issues a getpeername syscall. +// getpeername issues a getpeername unix. func getpeername(fd int, buf []byte) (uint32, error) { l := uint32(len(buf)) - _, _, e := syscall.RawSyscall(syscall.SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&l))) + _, _, e := unix.RawSyscall(unix.SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&l))) if e != 0 { return 0, e } -- cgit v1.2.3