Return correct name for imported host files

Implement PrependPath() in host.filesystem to correctly format
name for host files.

Updates #1672

PiperOrigin-RevId: 309959135
This commit is contained in:
Fabricio Voznika
2020-05-05 09:21:14 -07:00
committed by gVisor bot
parent 35951c3671
commit b3bd41434c
8 changed files with 60 additions and 64 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
// master inode. It returns the filesystem and root Dentry.
func (fstype FilesystemType) newFilesystem(vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials) (*kernfs.Filesystem, *kernfs.Dentry) {
fs := &kernfs.Filesystem{}
fs.Init(vfsObj, fstype)
fs.VFSFilesystem().Init(vfsObj, fstype, fs)
// Construct the root directory. This is always inode id 1.
root := &rootInode{
+1
View File
@@ -20,6 +20,7 @@ go_library(
"//pkg/abi/linux",
"//pkg/context",
"//pkg/fdnotifier",
"//pkg/fspath",
"//pkg/log",
"//pkg/refs",
"//pkg/sentry/arch",
+38 -30
View File
@@ -25,6 +25,7 @@ import (
"gvisor.dev/gvisor/pkg/abi/linux"
"gvisor.dev/gvisor/pkg/context"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/fspath"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/refs"
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
@@ -39,37 +40,9 @@ import (
"gvisor.dev/gvisor/pkg/waiter"
)
// filesystemType implements vfs.FilesystemType.
type filesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
func (filesystemType) GetFilesystem(context.Context, *vfs.VirtualFilesystem, *auth.Credentials, string, vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
panic("host.filesystemType.GetFilesystem should never be called")
}
// Name implements FilesystemType.Name.
func (filesystemType) Name() string {
return "none"
}
// filesystem implements vfs.FilesystemImpl.
type filesystem struct {
kernfs.Filesystem
}
// NewFilesystem sets up and returns a new hostfs filesystem.
//
// Note that there should only ever be one instance of host.filesystem,
// a global mount for host fds.
func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
fs := &filesystem{}
fs.Init(vfsObj, filesystemType{})
return fs.VFSFilesystem()
}
// ImportFD sets up and returns a vfs.FileDescription from a donated fd.
func ImportFD(ctx context.Context, mnt *vfs.Mount, hostFD int, isTTY bool) (*vfs.FileDescription, error) {
fs, ok := mnt.Filesystem().Impl().(*kernfs.Filesystem)
fs, ok := mnt.Filesystem().Impl().(*filesystem)
if !ok {
return nil, fmt.Errorf("can't import host FDs into filesystems of type %T", mnt.Filesystem().Impl())
}
@@ -119,12 +92,47 @@ func ImportFD(ctx context.Context, mnt *vfs.Mount, hostFD int, isTTY bool) (*vfs
d := &kernfs.Dentry{}
d.Init(i)
// i.open will take a reference on d.
defer d.DecRef()
return i.open(ctx, d.VFSDentry(), mnt)
}
// filesystemType implements vfs.FilesystemType.
type filesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
func (filesystemType) GetFilesystem(context.Context, *vfs.VirtualFilesystem, *auth.Credentials, string, vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
panic("host.filesystemType.GetFilesystem should never be called")
}
// Name implements FilesystemType.Name.
func (filesystemType) Name() string {
return "none"
}
// NewFilesystem sets up and returns a new hostfs filesystem.
//
// Note that there should only ever be one instance of host.filesystem,
// a global mount for host fds.
func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
fs := &filesystem{}
fs.VFSFilesystem().Init(vfsObj, filesystemType{}, fs)
return fs.VFSFilesystem()
}
// filesystem implements vfs.FilesystemImpl.
type filesystem struct {
kernfs.Filesystem
}
func (fs *filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDentry, b *fspath.Builder) error {
d := vd.Dentry().Impl().(*kernfs.Dentry)
inode := d.Inode().(*inode)
b.PrependComponent(fmt.Sprintf("host:[%d]", inode.ino))
return vfs.PrependPathSyntheticError{}
}
// inode implements kernfs.Inode.
type inode struct {
kernfs.InodeNotDirectory
+5 -7
View File
@@ -132,13 +132,6 @@ func (fs *Filesystem) processDeferredDecRefsLocked() {
fs.droppedDentriesMu.Unlock()
}
// Init initializes a kernfs filesystem. This should be called from during
// vfs.FilesystemType.NewFilesystem for the concrete filesystem embedding
// kernfs.
func (fs *Filesystem) Init(vfsObj *vfs.VirtualFilesystem, fsType vfs.FilesystemType) {
fs.vfsfs.Init(vfsObj, fsType, fs)
}
// VFSFilesystem returns the generic vfs filesystem object.
func (fs *Filesystem) VFSFilesystem() *vfs.Filesystem {
return &fs.vfsfs
@@ -261,6 +254,11 @@ func (d *Dentry) insertChildLocked(name string, child *Dentry) {
d.children[name] = child
}
// Inode returns the dentry's inode.
func (d *Dentry) Inode() Inode {
return d.inode
}
// The Inode interface maps filesystem-level operations that operate on paths to
// equivalent operations on specific filesystem nodes.
//
+1 -1
View File
@@ -195,7 +195,7 @@ func (fsType) Name() string {
func (fst fsType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opt vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
fs := &filesystem{}
fs.Init(vfsObj, &fst)
fs.VFSFilesystem().Init(vfsObj, &fst, fs)
root := fst.rootFn(creds, fs)
return fs.VFSFilesystem(), root.VFSDentry(), nil
}
+11 -17
View File
@@ -40,25 +40,19 @@ func (filesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFile
panic("pipefs.filesystemType.GetFilesystem should never be called")
}
// filesystem implements vfs.FilesystemImpl.
type filesystem struct {
kernfs.Filesystem
// TODO(gvisor.dev/issue/1193):
//
// - kernfs does not provide a way to implement statfs, from which we
// should indicate PIPEFS_MAGIC.
//
// - kernfs does not provide a way to override names for
// vfs.FilesystemImpl.PrependPath(); pipefs inodes should use synthetic
// name fmt.Sprintf("pipe:[%d]", inode.ino).
// TODO(gvisor.dev/issue/1193):
//
// - kernfs does not provide a way to implement statfs, from which we
// should indicate PIPEFS_MAGIC.
//
// - kernfs does not provide a way to override names for
// vfs.FilesystemImpl.PrependPath(); pipefs inodes should use synthetic
// name fmt.Sprintf("pipe:[%d]", inode.ino).
}
// NewFilesystem sets up and returns a new vfs.Filesystem implemented by
// pipefs.
// NewFilesystem sets up and returns a new vfs.Filesystem implemented by pipefs.
func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
fs := &filesystem{}
fs.Init(vfsObj, filesystemType{})
fs := &kernfs.Filesystem{}
fs.VFSFilesystem().Init(vfsObj, filesystemType{}, fs)
return fs.VFSFilesystem()
}
+2 -7
View File
@@ -41,18 +41,13 @@ func (filesystemType) Name() string {
return "sockfs"
}
// filesystem implements vfs.FilesystemImpl.
type filesystem struct {
kernfs.Filesystem
}
// NewFilesystem sets up and returns a new sockfs filesystem.
//
// Note that there should only ever be one instance of sockfs.Filesystem,
// backing a global socket mount.
func NewFilesystem(vfsObj *vfs.VirtualFilesystem) *vfs.Filesystem {
fs := &filesystem{}
fs.Init(vfsObj, filesystemType{})
fs := &kernfs.Filesystem{}
fs.VFSFilesystem().Init(vfsObj, filesystemType{}, fs)
return fs.VFSFilesystem()
}
+1 -1
View File
@@ -47,7 +47,7 @@ func (FilesystemType) Name() string {
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
func (fsType FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFilesystem, creds *auth.Credentials, source string, opts vfs.GetFilesystemOptions) (*vfs.Filesystem, *vfs.Dentry, error) {
fs := &filesystem{}
fs.Filesystem.Init(vfsObj, &fsType)
fs.VFSFilesystem().Init(vfsObj, &fsType, fs)
k := kernel.KernelFromContext(ctx)
maxCPUCores := k.ApplicationCores()
defaultSysDirMode := linux.FileMode(0755)