summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fs/host
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fs/host')
-rw-r--r--pkg/sentry/fs/host/BUILD86
-rw-r--r--pkg/sentry/fs/host/descriptor_test.go78
-rw-r--r--pkg/sentry/fs/host/host_amd64_unsafe_state_autogen.go6
-rw-r--r--pkg/sentry/fs/host/host_arm64_unsafe_state_autogen.go6
-rw-r--r--pkg/sentry/fs/host/host_state_autogen.go220
-rw-r--r--pkg/sentry/fs/host/host_unsafe_state_autogen.go3
-rw-r--r--pkg/sentry/fs/host/inode_test.go45
-rw-r--r--pkg/sentry/fs/host/socket_test.go252
-rw-r--r--pkg/sentry/fs/host/wait_test.go69
9 files changed, 235 insertions, 530 deletions
diff --git a/pkg/sentry/fs/host/BUILD b/pkg/sentry/fs/host/BUILD
deleted file mode 100644
index 921612e9c..000000000
--- a/pkg/sentry/fs/host/BUILD
+++ /dev/null
@@ -1,86 +0,0 @@
-load("//tools:defs.bzl", "go_library", "go_test")
-
-package(licenses = ["notice"])
-
-go_library(
- name = "host",
- srcs = [
- "control.go",
- "descriptor.go",
- "descriptor_state.go",
- "device.go",
- "file.go",
- "host.go",
- "inode.go",
- "inode_state.go",
- "ioctl_unsafe.go",
- "socket.go",
- "socket_iovec.go",
- "socket_state.go",
- "socket_unsafe.go",
- "tty.go",
- "util.go",
- "util_amd64_unsafe.go",
- "util_arm64_unsafe.go",
- "util_unsafe.go",
- ],
- visibility = ["//pkg/sentry:internal"],
- deps = [
- "//pkg/abi/linux",
- "//pkg/context",
- "//pkg/errors/linuxerr",
- "//pkg/fd",
- "//pkg/fdnotifier",
- "//pkg/log",
- "//pkg/marshal/primitive",
- "//pkg/refs",
- "//pkg/safemem",
- "//pkg/secio",
- "//pkg/sentry/arch",
- "//pkg/sentry/device",
- "//pkg/sentry/fs",
- "//pkg/sentry/fs/fsutil",
- "//pkg/sentry/hostfd",
- "//pkg/sentry/kernel",
- "//pkg/sentry/kernel/auth",
- "//pkg/sentry/kernel/time",
- "//pkg/sentry/memmap",
- "//pkg/sentry/socket/control",
- "//pkg/sentry/socket/unix",
- "//pkg/sentry/socket/unix/transport",
- "//pkg/sentry/unimpl",
- "//pkg/sentry/uniqueid",
- "//pkg/sync",
- "//pkg/syserr",
- "//pkg/tcpip",
- "//pkg/unet",
- "//pkg/usermem",
- "//pkg/waiter",
- "@org_golang_x_sys//unix:go_default_library",
- ],
-)
-
-go_test(
- name = "host_test",
- size = "small",
- srcs = [
- "descriptor_test.go",
- "inode_test.go",
- "socket_test.go",
- "wait_test.go",
- ],
- library = ":host",
- deps = [
- "//pkg/fd",
- "//pkg/fdnotifier",
- "//pkg/sentry/contexttest",
- "//pkg/sentry/kernel/time",
- "//pkg/sentry/socket",
- "//pkg/sentry/socket/unix/transport",
- "//pkg/syserr",
- "//pkg/tcpip",
- "//pkg/usermem",
- "//pkg/waiter",
- "@org_golang_x_sys//unix:go_default_library",
- ],
-)
diff --git a/pkg/sentry/fs/host/descriptor_test.go b/pkg/sentry/fs/host/descriptor_test.go
deleted file mode 100644
index cb809ab2d..000000000
--- a/pkg/sentry/fs/host/descriptor_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 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 host
-
-import (
- "io/ioutil"
- "path/filepath"
- "testing"
-
- "golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/fdnotifier"
- "gvisor.dev/gvisor/pkg/waiter"
-)
-
-func TestDescriptorRelease(t *testing.T) {
- for _, tc := range []struct {
- name string
- saveable bool
- wouldBlock bool
- }{
- {name: "all false"},
- {name: "saveable", saveable: true},
- {name: "wouldBlock", wouldBlock: true},
- } {
- t.Run(tc.name, func(t *testing.T) {
- dir, err := ioutil.TempDir("", "descriptor_test")
- if err != nil {
- t.Fatal("ioutil.TempDir() failed:", err)
- }
-
- fd, err := unix.Open(filepath.Join(dir, "file"), unix.O_RDWR|unix.O_CREAT, 0666)
- if err != nil {
- t.Fatal("failed to open temp file:", err)
- }
-
- // FD ownership is transferred to the descritor.
- queue := &waiter.Queue{}
- d, err := newDescriptor(fd, tc.saveable, tc.wouldBlock, queue)
- if err != nil {
- unix.Close(fd)
- t.Fatalf("newDescriptor(%d, %t, %t, queue) failed, err: %v", fd, tc.saveable, tc.wouldBlock, err)
- }
- if tc.saveable {
- if d.origFD < 0 {
- t.Errorf("saveable descriptor must preserve origFD, desc: %+v", d)
- }
- }
- if tc.wouldBlock {
- if !fdnotifier.HasFD(int32(d.value)) {
- t.Errorf("FD not registered with notifier, desc: %+v", d)
- }
- }
-
- oldVal := d.value
- d.Release()
- if d.value != -1 {
- t.Errorf("d.value want: -1, got: %d", d.value)
- }
- if tc.wouldBlock {
- if fdnotifier.HasFD(int32(oldVal)) {
- t.Errorf("FD not unregistered with notifier, desc: %+v", d)
- }
- }
- })
- }
-}
diff --git a/pkg/sentry/fs/host/host_amd64_unsafe_state_autogen.go b/pkg/sentry/fs/host/host_amd64_unsafe_state_autogen.go
new file mode 100644
index 000000000..14cecc49f
--- /dev/null
+++ b/pkg/sentry/fs/host/host_amd64_unsafe_state_autogen.go
@@ -0,0 +1,6 @@
+// automatically generated by stateify.
+
+//go:build amd64
+// +build amd64
+
+package host
diff --git a/pkg/sentry/fs/host/host_arm64_unsafe_state_autogen.go b/pkg/sentry/fs/host/host_arm64_unsafe_state_autogen.go
new file mode 100644
index 000000000..a714e619e
--- /dev/null
+++ b/pkg/sentry/fs/host/host_arm64_unsafe_state_autogen.go
@@ -0,0 +1,6 @@
+// automatically generated by stateify.
+
+//go:build arm64
+// +build arm64
+
+package host
diff --git a/pkg/sentry/fs/host/host_state_autogen.go b/pkg/sentry/fs/host/host_state_autogen.go
new file mode 100644
index 000000000..b06247919
--- /dev/null
+++ b/pkg/sentry/fs/host/host_state_autogen.go
@@ -0,0 +1,220 @@
+// automatically generated by stateify.
+
+package host
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (d *descriptor) StateTypeName() string {
+ return "pkg/sentry/fs/host.descriptor"
+}
+
+func (d *descriptor) StateFields() []string {
+ return []string{
+ "origFD",
+ "wouldBlock",
+ }
+}
+
+// +checklocksignore
+func (d *descriptor) StateSave(stateSinkObject state.Sink) {
+ d.beforeSave()
+ stateSinkObject.Save(0, &d.origFD)
+ stateSinkObject.Save(1, &d.wouldBlock)
+}
+
+// +checklocksignore
+func (d *descriptor) StateLoad(stateSourceObject state.Source) {
+ stateSourceObject.Load(0, &d.origFD)
+ stateSourceObject.Load(1, &d.wouldBlock)
+ stateSourceObject.AfterLoad(d.afterLoad)
+}
+
+func (f *fileOperations) StateTypeName() string {
+ return "pkg/sentry/fs/host.fileOperations"
+}
+
+func (f *fileOperations) StateFields() []string {
+ return []string{
+ "iops",
+ "dirCursor",
+ }
+}
+
+func (f *fileOperations) beforeSave() {}
+
+// +checklocksignore
+func (f *fileOperations) StateSave(stateSinkObject state.Sink) {
+ f.beforeSave()
+ stateSinkObject.Save(0, &f.iops)
+ stateSinkObject.Save(1, &f.dirCursor)
+}
+
+func (f *fileOperations) afterLoad() {}
+
+// +checklocksignore
+func (f *fileOperations) StateLoad(stateSourceObject state.Source) {
+ stateSourceObject.LoadWait(0, &f.iops)
+ stateSourceObject.Load(1, &f.dirCursor)
+}
+
+func (f *filesystem) StateTypeName() string {
+ return "pkg/sentry/fs/host.filesystem"
+}
+
+func (f *filesystem) StateFields() []string {
+ return []string{}
+}
+
+func (f *filesystem) beforeSave() {}
+
+// +checklocksignore
+func (f *filesystem) StateSave(stateSinkObject state.Sink) {
+ f.beforeSave()
+}
+
+func (f *filesystem) afterLoad() {}
+
+// +checklocksignore
+func (f *filesystem) StateLoad(stateSourceObject state.Source) {
+}
+
+func (i *inodeOperations) StateTypeName() string {
+ return "pkg/sentry/fs/host.inodeOperations"
+}
+
+func (i *inodeOperations) StateFields() []string {
+ return []string{
+ "fileState",
+ "cachingInodeOps",
+ }
+}
+
+func (i *inodeOperations) beforeSave() {}
+
+// +checklocksignore
+func (i *inodeOperations) StateSave(stateSinkObject state.Sink) {
+ i.beforeSave()
+ stateSinkObject.Save(0, &i.fileState)
+ stateSinkObject.Save(1, &i.cachingInodeOps)
+}
+
+func (i *inodeOperations) afterLoad() {}
+
+// +checklocksignore
+func (i *inodeOperations) StateLoad(stateSourceObject state.Source) {
+ stateSourceObject.LoadWait(0, &i.fileState)
+ stateSourceObject.Load(1, &i.cachingInodeOps)
+}
+
+func (i *inodeFileState) StateTypeName() string {
+ return "pkg/sentry/fs/host.inodeFileState"
+}
+
+func (i *inodeFileState) StateFields() []string {
+ return []string{
+ "descriptor",
+ "sattr",
+ "savedUAttr",
+ }
+}
+
+func (i *inodeFileState) beforeSave() {}
+
+// +checklocksignore
+func (i *inodeFileState) StateSave(stateSinkObject state.Sink) {
+ i.beforeSave()
+ if !state.IsZeroValue(&i.queue) {
+ state.Failf("queue is %#v, expected zero", &i.queue)
+ }
+ stateSinkObject.Save(0, &i.descriptor)
+ stateSinkObject.Save(1, &i.sattr)
+ stateSinkObject.Save(2, &i.savedUAttr)
+}
+
+// +checklocksignore
+func (i *inodeFileState) StateLoad(stateSourceObject state.Source) {
+ stateSourceObject.LoadWait(0, &i.descriptor)
+ stateSourceObject.LoadWait(1, &i.sattr)
+ stateSourceObject.Load(2, &i.savedUAttr)
+ stateSourceObject.AfterLoad(i.afterLoad)
+}
+
+func (c *ConnectedEndpoint) StateTypeName() string {
+ return "pkg/sentry/fs/host.ConnectedEndpoint"
+}
+
+func (c *ConnectedEndpoint) StateFields() []string {
+ return []string{
+ "ref",
+ "queue",
+ "path",
+ "srfd",
+ "stype",
+ }
+}
+
+// +checklocksignore
+func (c *ConnectedEndpoint) StateSave(stateSinkObject state.Sink) {
+ c.beforeSave()
+ stateSinkObject.Save(0, &c.ref)
+ stateSinkObject.Save(1, &c.queue)
+ stateSinkObject.Save(2, &c.path)
+ stateSinkObject.Save(3, &c.srfd)
+ stateSinkObject.Save(4, &c.stype)
+}
+
+// +checklocksignore
+func (c *ConnectedEndpoint) StateLoad(stateSourceObject state.Source) {
+ stateSourceObject.Load(0, &c.ref)
+ stateSourceObject.Load(1, &c.queue)
+ stateSourceObject.Load(2, &c.path)
+ stateSourceObject.LoadWait(3, &c.srfd)
+ stateSourceObject.Load(4, &c.stype)
+ stateSourceObject.AfterLoad(c.afterLoad)
+}
+
+func (t *TTYFileOperations) StateTypeName() string {
+ return "pkg/sentry/fs/host.TTYFileOperations"
+}
+
+func (t *TTYFileOperations) StateFields() []string {
+ return []string{
+ "fileOperations",
+ "session",
+ "fgProcessGroup",
+ "termios",
+ }
+}
+
+func (t *TTYFileOperations) beforeSave() {}
+
+// +checklocksignore
+func (t *TTYFileOperations) StateSave(stateSinkObject state.Sink) {
+ t.beforeSave()
+ stateSinkObject.Save(0, &t.fileOperations)
+ stateSinkObject.Save(1, &t.session)
+ stateSinkObject.Save(2, &t.fgProcessGroup)
+ stateSinkObject.Save(3, &t.termios)
+}
+
+func (t *TTYFileOperations) afterLoad() {}
+
+// +checklocksignore
+func (t *TTYFileOperations) StateLoad(stateSourceObject state.Source) {
+ stateSourceObject.Load(0, &t.fileOperations)
+ stateSourceObject.Load(1, &t.session)
+ stateSourceObject.Load(2, &t.fgProcessGroup)
+ stateSourceObject.Load(3, &t.termios)
+}
+
+func init() {
+ state.Register((*descriptor)(nil))
+ state.Register((*fileOperations)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*inodeOperations)(nil))
+ state.Register((*inodeFileState)(nil))
+ state.Register((*ConnectedEndpoint)(nil))
+ state.Register((*TTYFileOperations)(nil))
+}
diff --git a/pkg/sentry/fs/host/host_unsafe_state_autogen.go b/pkg/sentry/fs/host/host_unsafe_state_autogen.go
new file mode 100644
index 000000000..b2d8c661f
--- /dev/null
+++ b/pkg/sentry/fs/host/host_unsafe_state_autogen.go
@@ -0,0 +1,3 @@
+// automatically generated by stateify.
+
+package host
diff --git a/pkg/sentry/fs/host/inode_test.go b/pkg/sentry/fs/host/inode_test.go
deleted file mode 100644
index 11738871b..000000000
--- a/pkg/sentry/fs/host/inode_test.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2018 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 host
-
-import (
- "testing"
-
- "golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/sentry/contexttest"
-)
-
-// TestCloseFD verifies fds will be closed.
-func TestCloseFD(t *testing.T) {
- var p [2]int
- if err := unix.Pipe(p[0:]); err != nil {
- t.Fatalf("Failed to create pipe %v", err)
- }
- defer unix.Close(p[0])
- defer unix.Close(p[1])
-
- // Use the write-end because we will detect if it's closed on the read end.
- ctx := contexttest.Context(t)
- file, err := NewFile(ctx, p[1])
- if err != nil {
- t.Fatalf("Failed to create File: %v", err)
- }
- file.DecRef(ctx)
-
- s := make([]byte, 10)
- if c, err := unix.Read(p[0], s); c != 0 || err != nil {
- t.Errorf("want 0, nil (EOF) from read end, got %v, %v", c, err)
- }
-}
diff --git a/pkg/sentry/fs/host/socket_test.go b/pkg/sentry/fs/host/socket_test.go
deleted file mode 100644
index f7014b6b1..000000000
--- a/pkg/sentry/fs/host/socket_test.go
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2018 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 host
-
-import (
- "reflect"
- "testing"
-
- "golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/fd"
- "gvisor.dev/gvisor/pkg/fdnotifier"
- "gvisor.dev/gvisor/pkg/sentry/contexttest"
- ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
- "gvisor.dev/gvisor/pkg/sentry/socket"
- "gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
- "gvisor.dev/gvisor/pkg/syserr"
- "gvisor.dev/gvisor/pkg/tcpip"
- "gvisor.dev/gvisor/pkg/usermem"
- "gvisor.dev/gvisor/pkg/waiter"
-)
-
-var (
- // Make sure that ConnectedEndpoint implements transport.ConnectedEndpoint.
- _ = transport.ConnectedEndpoint(new(ConnectedEndpoint))
-
- // Make sure that ConnectedEndpoint implements transport.Receiver.
- _ = transport.Receiver(new(ConnectedEndpoint))
-)
-
-func getFl(fd int) (uint32, error) {
- fl, _, err := unix.RawSyscall(unix.SYS_FCNTL, uintptr(fd), unix.F_GETFL, 0)
- if err == 0 {
- return uint32(fl), nil
- }
- return 0, err
-}
-
-func TestSocketIsBlocking(t *testing.T) {
- // Using socketpair here because it's already connected.
- pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("host socket creation failed: %v", err)
- }
-
- fl, err := getFl(pair[0])
- if err != nil {
- t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[0], err)
- }
- if fl&unix.O_NONBLOCK == unix.O_NONBLOCK {
- t.Fatalf("Expected socket %v to be blocking", pair[0])
- }
- if fl, err = getFl(pair[1]); err != nil {
- t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[1], err)
- }
- if fl&unix.O_NONBLOCK == unix.O_NONBLOCK {
- t.Fatalf("Expected socket %v to be blocking", pair[1])
- }
- ctx := contexttest.Context(t)
- sock, err := newSocket(ctx, pair[0], false)
- if err != nil {
- t.Fatalf("newSocket(%v) failed => %v", pair[0], err)
- }
- defer sock.DecRef(ctx)
- // Test that the socket now is non-blocking.
- if fl, err = getFl(pair[0]); err != nil {
- t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[0], err)
- }
- if fl&unix.O_NONBLOCK != unix.O_NONBLOCK {
- t.Errorf("Expected socket %v to have become non-blocking", pair[0])
- }
- if fl, err = getFl(pair[1]); err != nil {
- t.Fatalf("getFl: fcntl(%v, GETFL) => %v", pair[1], err)
- }
- if fl&unix.O_NONBLOCK == unix.O_NONBLOCK {
- t.Errorf("Did not expect socket %v to become non-blocking", pair[1])
- }
-}
-
-func TestSocketWritev(t *testing.T) {
- // Using socketpair here because it's already connected.
- pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("host socket creation failed: %v", err)
- }
- ctx := contexttest.Context(t)
- socket, err := newSocket(ctx, pair[0], false)
- if err != nil {
- t.Fatalf("newSocket(%v) => %v", pair[0], err)
- }
- defer socket.DecRef(ctx)
- buf := []byte("hello world\n")
- n, err := socket.Writev(contexttest.Context(t), usermem.BytesIOSequence(buf))
- if err != nil {
- t.Fatalf("socket writev failed: %v", err)
- }
-
- if n != int64(len(buf)) {
- t.Fatalf("socket writev wrote incorrect bytes: %d", n)
- }
-}
-
-func TestSocketWritevLen0(t *testing.T) {
- // Using socketpair here because it's already connected.
- pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("host socket creation failed: %v", err)
- }
- ctx := contexttest.Context(t)
- socket, err := newSocket(ctx, pair[0], false)
- if err != nil {
- t.Fatalf("newSocket(%v) => %v", pair[0], err)
- }
- defer socket.DecRef(ctx)
- n, err := socket.Writev(contexttest.Context(t), usermem.BytesIOSequence(nil))
- if err != nil {
- t.Fatalf("socket writev failed: %v", err)
- }
-
- if n != 0 {
- t.Fatalf("socket writev wrote incorrect bytes: %d", n)
- }
-}
-
-func TestSocketSendMsgLen0(t *testing.T) {
- // Using socketpair here because it's already connected.
- pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("host socket creation failed: %v", err)
- }
- ctx := contexttest.Context(t)
- sfile, err := newSocket(ctx, pair[0], false)
- if err != nil {
- t.Fatalf("newSocket(%v) => %v", pair[0], err)
- }
- defer sfile.DecRef(ctx)
-
- s := sfile.FileOperations.(socket.Socket)
- n, terr := s.SendMsg(nil, usermem.BytesIOSequence(nil), []byte{}, 0, false, ktime.Time{}, socket.ControlMessages{})
- if n != 0 {
- t.Fatalf("socket sendmsg() failed: %v wrote: %d", terr, n)
- }
-
- if terr != nil {
- t.Fatalf("socket sendmsg() failed: %v", terr)
- }
-}
-
-func TestListen(t *testing.T) {
- pair, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0) => %v", err)
- }
- ctx := contexttest.Context(t)
- sfile1, err := newSocket(ctx, pair[0], false)
- if err != nil {
- t.Fatalf("newSocket(%v) => %v", pair[0], err)
- }
- defer sfile1.DecRef(ctx)
- socket1 := sfile1.FileOperations.(socket.Socket)
-
- sfile2, err := newSocket(ctx, pair[1], false)
- if err != nil {
- t.Fatalf("newSocket(%v) => %v", pair[1], err)
- }
- defer sfile2.DecRef(ctx)
- socket2 := sfile2.FileOperations.(socket.Socket)
-
- // Socketpairs can not be listened to.
- if err := socket1.Listen(nil, 64); err != syserr.ErrInvalidEndpointState {
- t.Fatalf("socket1.Listen(nil, 64) => %v, want syserr.ErrInvalidEndpointState", err)
- }
- if err := socket2.Listen(nil, 64); err != syserr.ErrInvalidEndpointState {
- t.Fatalf("socket2.Listen(nil, 64) => %v, want syserr.ErrInvalidEndpointState", err)
- }
-
- // Create a Unix socket, do not bind it.
- sock, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0)
- if err != nil {
- t.Fatalf("unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM, 0) => %v", err)
- }
- sfile3, err := newSocket(ctx, sock, false)
- if err != nil {
- t.Fatalf("newSocket(%v) => %v", sock, err)
- }
- defer sfile3.DecRef(ctx)
- socket3 := sfile3.FileOperations.(socket.Socket)
-
- // This socket is not bound so we can't listen on it.
- if err := socket3.Listen(nil, 64); err != syserr.ErrInvalidEndpointState {
- t.Fatalf("socket3.Listen(nil, 64) => %v, want syserr.ErrInvalidEndpointState", err)
- }
-}
-
-func TestPasscred(t *testing.T) {
- e := &ConnectedEndpoint{}
- if got, want := e.Passcred(), false; got != want {
- t.Errorf("Got %#v.Passcred() = %t, want = %t", e, got, want)
- }
-}
-
-func TestGetLocalAddress(t *testing.T) {
- e := &ConnectedEndpoint{path: "foo"}
- want := tcpip.FullAddress{Addr: tcpip.Address("foo")}
- if got, err := e.GetLocalAddress(); err != nil || got != want {
- t.Errorf("Got %#v.GetLocalAddress() = %#v, %v, want = %#v, %v", e, got, err, want, nil)
- }
-}
-
-func TestQueuedSize(t *testing.T) {
- e := &ConnectedEndpoint{}
- tests := []struct {
- name string
- f func() int64
- }{
- {"SendQueuedSize", e.SendQueuedSize},
- {"RecvQueuedSize", e.RecvQueuedSize},
- }
-
- for _, test := range tests {
- if got, want := test.f(), int64(-1); got != want {
- t.Errorf("Got %#v.%s() = %d, want = %d", e, test.name, got, want)
- }
- }
-}
-
-func TestRelease(t *testing.T) {
- f, err := unix.Socket(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_NONBLOCK|unix.SOCK_CLOEXEC, 0)
- if err != nil {
- t.Fatal("Creating socket:", err)
- }
- c := &ConnectedEndpoint{queue: &waiter.Queue{}, file: fd.New(f)}
- want := &ConnectedEndpoint{queue: c.queue}
- ctx := contexttest.Context(t)
- want.ref.DecRef(ctx)
- fdnotifier.AddFD(int32(c.file.FD()), nil)
- c.Release(ctx)
- if !reflect.DeepEqual(c, want) {
- t.Errorf("got = %#v, want = %#v", c, want)
- }
-}
diff --git a/pkg/sentry/fs/host/wait_test.go b/pkg/sentry/fs/host/wait_test.go
deleted file mode 100644
index bd6188e03..000000000
--- a/pkg/sentry/fs/host/wait_test.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2018 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 host
-
-import (
- "testing"
- "time"
-
- "golang.org/x/sys/unix"
- "gvisor.dev/gvisor/pkg/sentry/contexttest"
- "gvisor.dev/gvisor/pkg/waiter"
-)
-
-func TestWait(t *testing.T) {
- var fds [2]int
- err := unix.Pipe(fds[:])
- if err != nil {
- t.Fatalf("Unable to create pipe: %v", err)
- }
-
- defer unix.Close(fds[1])
-
- ctx := contexttest.Context(t)
- file, err := NewFile(ctx, fds[0])
- if err != nil {
- unix.Close(fds[0])
- t.Fatalf("NewFile failed: %v", err)
- }
-
- defer file.DecRef(ctx)
-
- r := file.Readiness(waiter.ReadableEvents)
- if r != 0 {
- t.Fatalf("File is ready for read when it shouldn't be.")
- }
-
- e, ch := waiter.NewChannelEntry(nil)
- file.EventRegister(&e, waiter.ReadableEvents)
- defer file.EventUnregister(&e)
-
- // Check that there are no notifications yet.
- if len(ch) != 0 {
- t.Fatalf("Channel is non-empty")
- }
-
- // Write to the pipe, so it should be writable now.
- unix.Write(fds[1], []byte{1})
-
- // Check that we get a notification. We need to yield the current thread
- // so that the fdnotifier can deliver notifications, so we use a
- // 1-second timeout instead of just checking the length of the channel.
- select {
- case <-ch:
- case <-time.After(1 * time.Second):
- t.Fatalf("Channel not notified")
- }
-}