mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Allow sending and importing a host event fd.
PiperOrigin-RevId: 724046820
This commit is contained in:
committed by
gVisor bot
parent
213917f3ea
commit
a4a0e84b5c
@@ -82,6 +82,25 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, initVal uint64, sem
|
||||
return &efd.vfsfd, nil
|
||||
}
|
||||
|
||||
// NewFromHost creates a new event fd from the given host fd.
|
||||
func NewFromHost(ctx context.Context, vfsObj *vfs.VirtualFilesystem, hostfd int, flags uint32) (*vfs.FileDescription, error) {
|
||||
semMode := flags&linux.EFD_SEMAPHORE != 0
|
||||
fileFlags := uint32(linux.O_RDWR)
|
||||
if flags&linux.EFD_NONBLOCK != 0 {
|
||||
fileFlags |= linux.O_NONBLOCK
|
||||
}
|
||||
fd, err := New(ctx, vfsObj, 0, semMode, flags)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
efd := fd.Impl().(*EventFileDescription)
|
||||
efd.hostfd = hostfd
|
||||
if err := fdnotifier.AddFD(int32(hostfd), &efd.queue); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fd, nil
|
||||
}
|
||||
|
||||
// HostFD returns the host eventfd associated with this event.
|
||||
func (efd *EventFileDescription) HostFD() (int, error) {
|
||||
efd.mu.Lock()
|
||||
|
||||
@@ -42,6 +42,7 @@ go_library(
|
||||
"//pkg/refs",
|
||||
"//pkg/safemem",
|
||||
"//pkg/sentry/arch",
|
||||
"//pkg/sentry/fsimpl/eventfd",
|
||||
"//pkg/sentry/fsimpl/kernfs",
|
||||
"//pkg/sentry/fsimpl/lock",
|
||||
"//pkg/sentry/fsutil",
|
||||
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/hostarch"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/eventfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/kernfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/hostfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
@@ -281,6 +282,11 @@ func NewFD(ctx context.Context, mnt *vfs.Mount, hostFD int, opts *NewFDOptions)
|
||||
}
|
||||
|
||||
fileType := linux.FileMode(stat.Mode).FileType()
|
||||
if fileType == 0 && isHostEventFdDevice(stat.Dev) {
|
||||
// This is an event fd. No inode needed.
|
||||
vfsObj := mnt.Filesystem().VirtualFilesystem()
|
||||
return eventfd.NewFromHost(ctx, vfsObj, hostFD, flags)
|
||||
}
|
||||
i, err := newInode(ctx, fs, hostFD, opts.Savable, opts.RestoreKey, fileType, opts.IsTTY, opts.Readonly)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -1027,3 +1033,28 @@ func (f *fileDescription) Ioctl(ctx context.Context, uio usermem.IO, sysno uintp
|
||||
|
||||
return f.FileDescriptionDefaultImpl.Ioctl(ctx, uio, sysno, args)
|
||||
}
|
||||
|
||||
// hostEventFdDevice is the host device that host event fds are associated
|
||||
// with. It is calculated once lazily.
|
||||
var hostEventFdDevice uint64
|
||||
var hostEventFdDeviceOnce sync.Once
|
||||
|
||||
// isHostEventFdDevice initializes hostEventFdDevice and compares it to the
|
||||
// given host device id.
|
||||
func isHostEventFdDevice(dev uint64) bool {
|
||||
hostEventFdDeviceOnce.Do(func() {
|
||||
efd, _, err := unix.RawSyscall(unix.SYS_EVENTFD2, 0, 0, 0)
|
||||
if err != 0 {
|
||||
log.Warningf("failed to create dummy eventfd: %v. Importing eventfds will fail", error(err))
|
||||
return
|
||||
}
|
||||
defer unix.Close(int(efd))
|
||||
var stat unix.Stat_t
|
||||
if err := unix.Fstat(int(efd), &stat); err != nil {
|
||||
log.Warningf("failed to stat dummy eventfd: %v. Importing eventfds will fail", error(err))
|
||||
return
|
||||
}
|
||||
hostEventFdDevice = stat.Dev
|
||||
})
|
||||
return dev == hostEventFdDevice
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user