Add fsimpl/gofer.InternalFilesystemOptions.OpenSocketsByConnecting.
PiperOrigin-RevId: 311014995
This commit is contained in:
parent
633e1b89bb
commit
15de8cc9e0
|
@ -21,6 +21,8 @@ import (
|
|||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fspath"
|
||||
"gvisor.dev/gvisor/pkg/p9"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/host"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/pipe"
|
||||
"gvisor.dev/gvisor/pkg/sentry/socket/unix/transport"
|
||||
|
@ -835,6 +837,9 @@ func (d *dentry) openLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vf
|
|||
if d.isSynthetic() {
|
||||
return nil, syserror.ENXIO
|
||||
}
|
||||
if d.fs.iopts.OpenSocketsByConnecting {
|
||||
return d.connectSocketLocked(ctx, opts)
|
||||
}
|
||||
case linux.S_IFIFO:
|
||||
if d.isSynthetic() {
|
||||
return d.pipe.Open(ctx, mnt, &d.vfsd, opts.Flags)
|
||||
|
@ -843,10 +848,28 @@ func (d *dentry) openLocked(ctx context.Context, rp *vfs.ResolvingPath, opts *vf
|
|||
return d.openSpecialFileLocked(ctx, mnt, opts)
|
||||
}
|
||||
|
||||
func (d *dentry) connectSocketLocked(ctx context.Context, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
|
||||
if opts.Flags&linux.O_DIRECT != 0 {
|
||||
return nil, syserror.EINVAL
|
||||
}
|
||||
fdObj, err := d.file.connect(ctx, p9.AnonymousSocket)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fd, err := host.NewFD(ctx, kernel.KernelFromContext(ctx).HostMount(), fdObj.FD(), &host.NewFDOptions{
|
||||
HaveFlags: true,
|
||||
Flags: opts.Flags,
|
||||
})
|
||||
if err != nil {
|
||||
fdObj.Close()
|
||||
return nil, err
|
||||
}
|
||||
fdObj.Release()
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
func (d *dentry) openSpecialFileLocked(ctx context.Context, mnt *vfs.Mount, opts *vfs.OpenOptions) (*vfs.FileDescription, error) {
|
||||
ats := vfs.AccessTypesForOpenFlags(opts)
|
||||
// Treat as a special file. This is done for non-synthetic pipes as well as
|
||||
// regular files when d.fs.opts.regularFilesUseSpecialFileFD is true.
|
||||
if opts.Flags&linux.O_DIRECT != 0 {
|
||||
return nil, syserror.EINVAL
|
||||
}
|
||||
|
|
|
@ -221,6 +221,10 @@ type InternalFilesystemOptions struct {
|
|||
// which servers can handle only a single client and report failure if that
|
||||
// client disconnects.
|
||||
LeakConnection bool
|
||||
|
||||
// If OpenSocketsByConnecting is true, silently translate attempts to open
|
||||
// files identifying as sockets to connect RPCs.
|
||||
OpenSocketsByConnecting bool
|
||||
}
|
||||
|
||||
// Name implements vfs.FilesystemType.Name.
|
||||
|
|
|
@ -40,8 +40,20 @@ import (
|
|||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
|
||||
// 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) {
|
||||
// NewFDOptions contains options to NewFD.
|
||||
type NewFDOptions struct {
|
||||
// If IsTTY is true, the file descriptor is a TTY.
|
||||
IsTTY bool
|
||||
|
||||
// If HaveFlags is true, use Flags for the new file description. Otherwise,
|
||||
// the new file description will inherit flags from hostFD.
|
||||
HaveFlags bool
|
||||
Flags uint32
|
||||
}
|
||||
|
||||
// NewFD returns a vfs.FileDescription representing the given host file
|
||||
// descriptor. mnt must be Kernel.HostMount().
|
||||
func NewFD(ctx context.Context, mnt *vfs.Mount, hostFD int, opts *NewFDOptions) (*vfs.FileDescription, error) {
|
||||
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())
|
||||
|
@ -53,10 +65,14 @@ func ImportFD(ctx context.Context, mnt *vfs.Mount, hostFD int, isTTY bool) (*vfs
|
|||
return nil, err
|
||||
}
|
||||
|
||||
// Get flags for the imported FD.
|
||||
flags, err := unix.FcntlInt(uintptr(hostFD), syscall.F_GETFL, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
flags := opts.Flags
|
||||
if !opts.HaveFlags {
|
||||
// Get flags for the imported FD.
|
||||
flagsInt, err := unix.FcntlInt(uintptr(hostFD), syscall.F_GETFL, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
flags = uint32(flagsInt)
|
||||
}
|
||||
|
||||
fileMode := linux.FileMode(s.Mode)
|
||||
|
@ -65,13 +81,13 @@ func ImportFD(ctx context.Context, mnt *vfs.Mount, hostFD int, isTTY bool) (*vfs
|
|||
// Determine if hostFD is seekable. If not, this syscall will return ESPIPE
|
||||
// (see fs/read_write.c:llseek), e.g. for pipes, sockets, and some character
|
||||
// devices.
|
||||
_, err = unix.Seek(hostFD, 0, linux.SEEK_CUR)
|
||||
_, err := unix.Seek(hostFD, 0, linux.SEEK_CUR)
|
||||
seekable := err != syserror.ESPIPE
|
||||
|
||||
i := &inode{
|
||||
hostFD: hostFD,
|
||||
seekable: seekable,
|
||||
isTTY: isTTY,
|
||||
isTTY: opts.IsTTY,
|
||||
canMap: canMap(uint32(fileType)),
|
||||
wouldBlock: wouldBlock(uint32(fileType)),
|
||||
ino: fs.NextIno(),
|
||||
|
@ -101,7 +117,14 @@ func ImportFD(ctx context.Context, mnt *vfs.Mount, hostFD int, isTTY bool) (*vfs
|
|||
|
||||
// i.open will take a reference on d.
|
||||
defer d.DecRef()
|
||||
return i.open(ctx, d.VFSDentry(), mnt, uint32(flags))
|
||||
return i.open(ctx, d.VFSDentry(), mnt, flags)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
return NewFD(ctx, mnt, hostFD, &NewFDOptions{
|
||||
IsTTY: isTTY,
|
||||
})
|
||||
}
|
||||
|
||||
// filesystemType implements vfs.FilesystemType.
|
||||
|
|
Loading…
Reference in New Issue