diff options
Diffstat (limited to 'pkg/sentry/fs/fdpipe')
-rw-r--r-- | pkg/sentry/fs/fdpipe/BUILD | 4 | ||||
-rw-r--r-- | pkg/sentry/fs/fdpipe/pipe.go | 22 | ||||
-rw-r--r-- | pkg/sentry/fs/fdpipe/pipe_opener.go | 8 | ||||
-rw-r--r-- | pkg/sentry/fs/fdpipe/pipe_opener_test.go | 14 | ||||
-rw-r--r-- | pkg/sentry/fs/fdpipe/pipe_state.go | 4 | ||||
-rw-r--r-- | pkg/sentry/fs/fdpipe/pipe_test.go | 70 |
6 files changed, 69 insertions, 53 deletions
diff --git a/pkg/sentry/fs/fdpipe/BUILD b/pkg/sentry/fs/fdpipe/BUILD index 098463e97..bf00b9c09 100644 --- a/pkg/sentry/fs/fdpipe/BUILD +++ b/pkg/sentry/fs/fdpipe/BUILD @@ -9,8 +9,8 @@ go_library( "pipe_opener.go", "pipe_state.go", ], - importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fdpipe", - imports = ["gvisor.googlesource.com/gvisor/pkg/sentry/fs"], + importpath = "gvisor.dev/gvisor/pkg/sentry/fs/fdpipe", + imports = ["gvisor.dev/gvisor/pkg/sentry/fs"], visibility = ["//pkg/sentry:internal"], deps = [ "//pkg/fd", diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go index 4ef7ea08a..5a0a67eab 100644 --- a/pkg/sentry/fs/fdpipe/pipe.go +++ b/pkg/sentry/fs/fdpipe/pipe.go @@ -20,17 +20,17 @@ import ( "sync" "syscall" - "gvisor.googlesource.com/gvisor/pkg/fd" - "gvisor.googlesource.com/gvisor/pkg/fdnotifier" - "gvisor.googlesource.com/gvisor/pkg/log" - "gvisor.googlesource.com/gvisor/pkg/secio" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs/fsutil" - "gvisor.googlesource.com/gvisor/pkg/sentry/safemem" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" - "gvisor.googlesource.com/gvisor/pkg/waiter" + "gvisor.dev/gvisor/pkg/fd" + "gvisor.dev/gvisor/pkg/fdnotifier" + "gvisor.dev/gvisor/pkg/log" + "gvisor.dev/gvisor/pkg/secio" + "gvisor.dev/gvisor/pkg/sentry/context" + "gvisor.dev/gvisor/pkg/sentry/fs" + "gvisor.dev/gvisor/pkg/sentry/fs/fsutil" + "gvisor.dev/gvisor/pkg/sentry/safemem" + "gvisor.dev/gvisor/pkg/sentry/usermem" + "gvisor.dev/gvisor/pkg/syserror" + "gvisor.dev/gvisor/pkg/waiter" ) // pipeOperations are the fs.FileOperations of a host pipe. diff --git a/pkg/sentry/fs/fdpipe/pipe_opener.go b/pkg/sentry/fs/fdpipe/pipe_opener.go index 0cabe2e18..64b558975 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener.go @@ -20,10 +20,10 @@ import ( "syscall" "time" - "gvisor.googlesource.com/gvisor/pkg/fd" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.dev/gvisor/pkg/fd" + "gvisor.dev/gvisor/pkg/sentry/context" + "gvisor.dev/gvisor/pkg/sentry/fs" + "gvisor.dev/gvisor/pkg/syserror" ) // NonBlockingOpener is a generic host file opener used to retry opening host diff --git a/pkg/sentry/fs/fdpipe/pipe_opener_test.go b/pkg/sentry/fs/fdpipe/pipe_opener_test.go index 8c8b1b40c..8e4d839e1 100644 --- a/pkg/sentry/fs/fdpipe/pipe_opener_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_opener_test.go @@ -25,12 +25,12 @@ import ( "time" "github.com/google/uuid" - "gvisor.googlesource.com/gvisor/pkg/fd" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.dev/gvisor/pkg/fd" + "gvisor.dev/gvisor/pkg/sentry/context" + "gvisor.dev/gvisor/pkg/sentry/context/contexttest" + "gvisor.dev/gvisor/pkg/sentry/fs" + "gvisor.dev/gvisor/pkg/sentry/usermem" + "gvisor.dev/gvisor/pkg/syserror" ) type hostOpener struct { @@ -359,7 +359,7 @@ func TestCopiedReadAheadBuffer(t *testing.T) { inode := fs.NewMockInode(ctx, fs.NewMockMountSource(nil), fs.StableAttr{ Type: fs.Pipe, }) - file := fs.NewFile(ctx, fs.NewDirent(inode, "pipe"), fs.FileFlags{Read: true}, pipeOps) + file := fs.NewFile(ctx, fs.NewDirent(ctx, inode, "pipe"), fs.FileFlags{Read: true}, pipeOps) // Check that the file we opened points to a pipe with a non-empty read ahead buffer. bufsize := len(pipeOps.readAheadBuffer) diff --git a/pkg/sentry/fs/fdpipe/pipe_state.go b/pkg/sentry/fs/fdpipe/pipe_state.go index 8b347aa11..29175fb3d 100644 --- a/pkg/sentry/fs/fdpipe/pipe_state.go +++ b/pkg/sentry/fs/fdpipe/pipe_state.go @@ -19,8 +19,8 @@ import ( "io/ioutil" "sync" - "gvisor.googlesource.com/gvisor/pkg/sentry/context" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" + "gvisor.dev/gvisor/pkg/sentry/context" + "gvisor.dev/gvisor/pkg/sentry/fs" ) // beforeSave is invoked by stateify. diff --git a/pkg/sentry/fs/fdpipe/pipe_test.go b/pkg/sentry/fs/fdpipe/pipe_test.go index b59a6aa0e..69abc1e71 100644 --- a/pkg/sentry/fs/fdpipe/pipe_test.go +++ b/pkg/sentry/fs/fdpipe/pipe_test.go @@ -21,12 +21,12 @@ import ( "syscall" "testing" - "gvisor.googlesource.com/gvisor/pkg/fd" - "gvisor.googlesource.com/gvisor/pkg/fdnotifier" - "gvisor.googlesource.com/gvisor/pkg/sentry/context/contexttest" - "gvisor.googlesource.com/gvisor/pkg/sentry/fs" - "gvisor.googlesource.com/gvisor/pkg/sentry/usermem" - "gvisor.googlesource.com/gvisor/pkg/syserror" + "gvisor.dev/gvisor/pkg/fd" + "gvisor.dev/gvisor/pkg/fdnotifier" + "gvisor.dev/gvisor/pkg/sentry/context/contexttest" + "gvisor.dev/gvisor/pkg/sentry/fs" + "gvisor.dev/gvisor/pkg/sentry/usermem" + "gvisor.dev/gvisor/pkg/syserror" ) func singlePipeFD() (int, error) { @@ -50,11 +50,11 @@ func mockPipeDirent(t *testing.T) *fs.Dirent { User: fs.PermMask{Read: true, Write: true}, }, } - inode := fs.NewInode(node, fs.NewMockMountSource(nil), fs.StableAttr{ + inode := fs.NewInode(ctx, node, fs.NewMockMountSource(nil), fs.StableAttr{ Type: fs.Pipe, BlockSize: usermem.PageSize, }) - return fs.NewDirent(inode, "") + return fs.NewDirent(ctx, inode, "") } func TestNewPipe(t *testing.T) { @@ -285,7 +285,7 @@ func TestPipeRequest(t *testing.T) { defer p.Release() inode := fs.NewMockInode(ctx, fs.NewMockMountSource(nil), fs.StableAttr{Type: fs.Pipe}) - file := fs.NewFile(ctx, fs.NewDirent(inode, "pipe"), fs.FileFlags{Read: true}, p) + file := fs.NewFile(ctx, fs.NewDirent(ctx, inode, "pipe"), fs.FileFlags{Read: true}, p) // Issue request via the appropriate function. switch c := test.context.(type) { @@ -339,7 +339,7 @@ func TestPipeReadAheadBuffer(t *testing.T) { inode := fs.NewMockInode(ctx, fs.NewMockMountSource(nil), fs.StableAttr{ Type: fs.Pipe, }) - file := fs.NewFile(ctx, fs.NewDirent(inode, "pipe"), fs.FileFlags{Read: true}, p) + file := fs.NewFile(ctx, fs.NewDirent(ctx, inode, "pipe"), fs.FileFlags{Read: true}, p) // In total we expect to read data + buffered. total := append(buffered, data...) @@ -358,9 +358,9 @@ func TestPipeReadAheadBuffer(t *testing.T) { } } -// This is very important for pipes in general because they can return EWOULDBLOCK and for -// those that block they must continue until they have read all of the data (and report it -// as such. +// This is very important for pipes in general because they can return +// EWOULDBLOCK and for those that block they must continue until they have read +// all of the data (and report it as such). func TestPipeReadsAccumulate(t *testing.T) { fds := make([]int, 2) if err := syscall.Pipe(fds); err != nil { @@ -385,7 +385,7 @@ func TestPipeReadsAccumulate(t *testing.T) { inode := fs.NewMockInode(ctx, fs.NewMockMountSource(nil), fs.StableAttr{ Type: fs.Pipe, }) - file := fs.NewFile(ctx, fs.NewDirent(inode, "pipe"), fs.FileFlags{Read: true}, p) + file := fs.NewFile(ctx, fs.NewDirent(ctx, inode, "pipe"), fs.FileFlags{Read: true}, p) // Write some some bytes to the pipe. data := []byte("some message") @@ -393,8 +393,8 @@ func TestPipeReadsAccumulate(t *testing.T) { t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(data)) } - // Construct a segment vec that is a bit more than we have written so we trigger - // an EWOULDBLOCK. + // Construct a segment vec that is a bit more than we have written so we + // trigger an EWOULDBLOCK. wantBytes := len(data) + 1 readBuffer := make([]byte, wantBytes) iov := usermem.BytesIOSequence(readBuffer) @@ -446,41 +446,57 @@ func TestPipeWritesAccumulate(t *testing.T) { wfile.Close() t.Fatalf("newPipeOperations got error %v, want nil", err) } - // Don't forget to remove the fd from the fd notifier. Otherwise other tests will - // likely be borked, because it's global :( + // Don't forget to remove the fd from the fd notifier. Otherwise other tests + // will likely be borked, because it's global :( defer p.Release() inode := fs.NewMockInode(ctx, fs.NewMockMountSource(nil), fs.StableAttr{ Type: fs.Pipe, }) - file := fs.NewFile(ctx, fs.NewDirent(inode, "pipe"), fs.FileFlags{Read: true}, p) + file := fs.NewFile(ctx, fs.NewDirent(ctx, inode, "pipe"), fs.FileFlags{Read: true}, p) + + pipeSize, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(wfile.FD()), syscall.F_GETPIPE_SZ, 0) + if errno != 0 { + t.Fatalf("fcntl(F_GETPIPE_SZ) failed: %v", errno) + } + t.Logf("Pipe buffer size: %d", pipeSize) - // Construct a segment vec that is larger than the pipe size to trigger an EWOULDBLOCK. - wantBytes := 65536 * 2 + // Construct a segment vec that is larger than the pipe size to trigger an + // EWOULDBLOCK. + wantBytes := int(pipeSize) * 2 writeBuffer := make([]byte, wantBytes) for i := 0; i < wantBytes; i++ { writeBuffer[i] = 'a' } iov := usermem.BytesIOSequence(writeBuffer) n, err := p.Write(ctx, file, iov, 0) - total := n - iov = iov.DropFirst64(n) if err != syserror.ErrWouldBlock { t.Fatalf("Writev got error %v, want %v", err, syserror.ErrWouldBlock) } + if n != int64(pipeSize) { + t.Fatalf("Writev partial write, got: %v, want %v", n, pipeSize) + } + total := n + iov = iov.DropFirst64(n) // Read the entire pipe buf size to make space for the second half. - throwAway := make([]byte, 65536) - if n, err := syscall.Read(fds[0], throwAway); n != len(throwAway) || err != nil { - t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(throwAway)) + readBuffer := make([]byte, n) + if n, err := syscall.Read(fds[0], readBuffer); n != len(readBuffer) || err != nil { + t.Fatalf("write to pipe got (%d, %v), want (%d, nil)", n, err, len(readBuffer)) + } + if !bytes.Equal(readBuffer, writeBuffer[:len(readBuffer)]) { + t.Fatalf("wrong data read from pipe, got: %v, want: %v", readBuffer, writeBuffer) } // This time we should not block. n, err = p.Write(ctx, file, iov, 0) - total += n if err != nil { t.Fatalf("Writev got error %v, want nil", err) } + if n != int64(pipeSize) { + t.Fatalf("Writev partial write, got: %v, want %v", n, pipeSize) + } + total += n // Assert that the result we got back is cumulative. if total != int64(wantBytes) { |