summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@gmail.com>2018-07-31 11:18:02 -0700
committerShentubot <shentubot@google.com>2018-07-31 11:19:15 -0700
commita7a0167716d71895919021692b15bd000f63b24f (patch)
tree5e41d11fe25b533a59387649e4f90c0801e1eb1e /pkg
parent543c997978525ac7de3a24ff73203ddbb2cef6dc (diff)
proc: show file flags in fdinfo
Currently, there is an attempt to print FD flags, but they are not decoded into a number, so we see something like this: /criu # cat /proc/self/fdinfo/0 flags: {%!o(bool=000false)} Actually, fdinfo has to contain file flags. Change-Id: Idcbb7db908067447eb9ae6f2c3cfb861f2be1a97 PiperOrigin-RevId: 206794498
Diffstat (limited to 'pkg')
-rw-r--r--pkg/sentry/fs/flags.go39
-rw-r--r--pkg/sentry/fs/proc/fds.go21
-rw-r--r--pkg/sentry/kernel/fd_map.go16
-rw-r--r--pkg/sentry/syscalls/linux/flags.go43
-rw-r--r--pkg/sentry/syscalls/linux/sys_file.go4
5 files changed, 69 insertions, 54 deletions
diff --git a/pkg/sentry/fs/flags.go b/pkg/sentry/fs/flags.go
index 810452584..da0ff58af 100644
--- a/pkg/sentry/fs/flags.go
+++ b/pkg/sentry/fs/flags.go
@@ -14,6 +14,10 @@
package fs
+import (
+ "gvisor.googlesource.com/gvisor/pkg/abi/linux"
+)
+
// FileFlags encodes file flags.
type FileFlags struct {
// Direct indicates that I/O should be done directly.
@@ -78,3 +82,38 @@ func (f FileFlags) Settable() SettableFileFlags {
Async: f.Async,
}
}
+
+// ToLinux converts a FileFlags object to a Linux representation.
+func (f FileFlags) ToLinux() (mask uint) {
+ if f.Direct {
+ mask |= linux.O_DIRECT
+ }
+ if f.NonBlocking {
+ mask |= linux.O_NONBLOCK
+ }
+ if f.Sync {
+ mask |= linux.O_SYNC
+ }
+ if f.Append {
+ mask |= linux.O_APPEND
+ }
+ if f.Directory {
+ mask |= linux.O_DIRECTORY
+ }
+ if f.Async {
+ mask |= linux.O_ASYNC
+ }
+ if f.LargeFile {
+ mask |= linux.O_LARGEFILE
+ }
+
+ switch {
+ case f.Read && f.Write:
+ mask |= linux.O_RDWR
+ case f.Write:
+ mask |= linux.O_WRONLY
+ case f.Read:
+ mask |= linux.O_RDONLY
+ }
+ return
+}
diff --git a/pkg/sentry/fs/proc/fds.go b/pkg/sentry/fs/proc/fds.go
index 2eca9ac31..194a9c12a 100644
--- a/pkg/sentry/fs/proc/fds.go
+++ b/pkg/sentry/fs/proc/fds.go
@@ -40,16 +40,16 @@ func walkDescriptors(t *kernel.Task, p string, toInode func(*fs.File, kernel.FDF
}
var file *fs.File
- var flags kernel.FDFlags
+ var fdFlags kernel.FDFlags
t.WithMuLocked(func(t *kernel.Task) {
if fdm := t.FDMap(); fdm != nil {
- file, flags = fdm.GetDescriptor(kdefs.FD(n))
+ file, fdFlags = fdm.GetDescriptor(kdefs.FD(n))
}
})
if file == nil {
return nil, syserror.ENOENT
}
- return toInode(file, flags), nil
+ return toInode(file, fdFlags), nil
}
// readDescriptors reads fds in the task starting at offset, and calls the
@@ -200,17 +200,20 @@ func (f *fdDir) DeprecatedReaddir(ctx context.Context, dirCtx *fs.DirCtx, offset
type fdInfo struct {
ramfs.File
- flags kernel.FDFlags
+ flags fs.FileFlags
+ fdFlags kernel.FDFlags
}
// newFdInfo returns a new fdInfo based on an existing file.
-func newFdInfo(t *kernel.Task, _ *fs.File, flags kernel.FDFlags, msrc *fs.MountSource) *fs.Inode {
- fdi := &fdInfo{flags: flags}
+func newFdInfo(t *kernel.Task, file *fs.File, fdFlags kernel.FDFlags, msrc *fs.MountSource) *fs.Inode {
+ fdi := &fdInfo{flags: file.Flags(), fdFlags: fdFlags}
fdi.InitFile(t, fs.RootOwner, fs.FilePermissions{User: fs.PermMask{Read: true}})
// TODO: Get pos, locks, and other data. For now we only
// have flags.
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
- fdi.Append([]byte(fmt.Sprintf("flags: %08o\n", flags)))
+
+ flags := file.Flags().ToLinux() | fdFlags.ToLinuxFileFlags()
+ fdi.Append([]byte(fmt.Sprintf("flags:\t0%o\n", flags)))
return newFile(fdi, msrc, fs.SpecialFile, t)
}
@@ -241,8 +244,8 @@ func newFdInfoDir(t *kernel.Task, msrc *fs.MountSource) *fs.Inode {
// Lookup loads an fd in /proc/TID/fdinfo into a Dirent.
func (fdid *fdInfoDir) Lookup(ctx context.Context, dir *fs.Inode, p string) (*fs.Dirent, error) {
- n, err := walkDescriptors(fdid.t, p, func(file *fs.File, flags kernel.FDFlags) *fs.Inode {
- return newFdInfo(fdid.t, file, flags, dir.MountSource)
+ n, err := walkDescriptors(fdid.t, p, func(file *fs.File, fdFlags kernel.FDFlags) *fs.Inode {
+ return newFdInfo(fdid.t, file, fdFlags, dir.MountSource)
})
if err != nil {
return nil, err
diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go
index ef73125fd..299506330 100644
--- a/pkg/sentry/kernel/fd_map.go
+++ b/pkg/sentry/kernel/fd_map.go
@@ -51,6 +51,22 @@ type FDFlags struct {
CloseOnExec bool
}
+// ToLinuxFileFlags converts a kernel.FDFlags object to a Linux file flags representation.
+func (f FDFlags) ToLinuxFileFlags() (mask uint) {
+ if f.CloseOnExec {
+ mask |= linux.O_CLOEXEC
+ }
+ return
+}
+
+// ToLinuxFDFlags converts a kernel.FDFlags object to a Linux descriptor flags representation.
+func (f FDFlags) ToLinuxFDFlags() (mask uint) {
+ if f.CloseOnExec {
+ mask |= linux.FD_CLOEXEC
+ }
+ return
+}
+
// descriptor holds the details about a file descriptor, namely a pointer the
// file itself and the descriptor flags.
type descriptor struct {
diff --git a/pkg/sentry/syscalls/linux/flags.go b/pkg/sentry/syscalls/linux/flags.go
index b2e173f3e..e8db3e0de 100644
--- a/pkg/sentry/syscalls/linux/flags.go
+++ b/pkg/sentry/syscalls/linux/flags.go
@@ -17,7 +17,6 @@ package linux
import (
"gvisor.googlesource.com/gvisor/pkg/abi/linux"
"gvisor.googlesource.com/gvisor/pkg/sentry/fs"
- "gvisor.googlesource.com/gvisor/pkg/sentry/kernel"
)
// flagsToPermissions returns a Permissions object from Linux flags.
@@ -35,48 +34,6 @@ func flagsToPermissions(mask uint) (p fs.PermMask) {
return
}
-// fdFlagsToLinux converts a kernel.FDFlags object to a Linux representation.
-func fdFlagsToLinux(flags kernel.FDFlags) (mask uint) {
- if flags.CloseOnExec {
- mask |= linux.FD_CLOEXEC
- }
- return
-}
-
-// flagsToLinux converts a FileFlags object to a Linux representation.
-func flagsToLinux(flags fs.FileFlags) (mask uint) {
- if flags.Direct {
- mask |= linux.O_DIRECT
- }
- if flags.NonBlocking {
- mask |= linux.O_NONBLOCK
- }
- if flags.Sync {
- mask |= linux.O_SYNC
- }
- if flags.Append {
- mask |= linux.O_APPEND
- }
- if flags.Directory {
- mask |= linux.O_DIRECTORY
- }
- if flags.Async {
- mask |= linux.O_ASYNC
- }
- if flags.LargeFile {
- mask |= linux.O_LARGEFILE
- }
- switch {
- case flags.Read && flags.Write:
- mask |= linux.O_RDWR
- case flags.Write:
- mask |= linux.O_WRONLY
- case flags.Read:
- mask |= linux.O_RDONLY
- }
- return
-}
-
// linuxToFlags converts linux file flags to a FileFlags object.
func linuxToFlags(mask uint) (flags fs.FileFlags) {
return fs.FileFlags{
diff --git a/pkg/sentry/syscalls/linux/sys_file.go b/pkg/sentry/syscalls/linux/sys_file.go
index 2f28fbea6..692f11ed7 100644
--- a/pkg/sentry/syscalls/linux/sys_file.go
+++ b/pkg/sentry/syscalls/linux/sys_file.go
@@ -809,14 +809,14 @@ func Fcntl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Syscall
}
return uintptr(fd), nil, nil
case linux.F_GETFD:
- return uintptr(fdFlagsToLinux(flags)), nil, nil
+ return uintptr(flags.ToLinuxFDFlags()), nil, nil
case linux.F_SETFD:
flags := args[2].Uint()
t.FDMap().SetFlags(fd, kernel.FDFlags{
CloseOnExec: flags&syscall.FD_CLOEXEC != 0,
})
case linux.F_GETFL:
- return uintptr(flagsToLinux(file.Flags())), nil, nil
+ return uintptr(file.Flags().ToLinux()), nil, nil
case linux.F_SETFL:
flags := uint(args[2].Uint())
file.SetFlags(linuxToSettableFlags(flags))