mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Move pkg/sentry/vfs/{eventfd,timerfd} to new packages in pkg/sentry/fsimpl.
They don't depend on anything in VFS2, so they should be their own packages. PiperOrigin-RevId: 310416807
This commit is contained in:
committed by
gVisor bot
parent
92cab8e2c3
commit
d0b1d0233d
@@ -0,0 +1,33 @@
|
||||
load("//tools:defs.bzl", "go_library", "go_test")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
go_library(
|
||||
name = "eventfd",
|
||||
srcs = ["eventfd.go"],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/context",
|
||||
"//pkg/fdnotifier",
|
||||
"//pkg/log",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/syserror",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
name = "eventfd_test",
|
||||
size = "small",
|
||||
srcs = ["eventfd_test.go"],
|
||||
library = ":eventfd",
|
||||
deps = [
|
||||
"//pkg/abi/linux",
|
||||
"//pkg/sentry/contexttest",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
)
|
||||
@@ -12,7 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vfs
|
||||
// Package eventfd implements event fds.
|
||||
package eventfd
|
||||
|
||||
import (
|
||||
"math"
|
||||
@@ -23,6 +24,7 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
"gvisor.dev/gvisor/pkg/fdnotifier"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
@@ -32,9 +34,9 @@ import (
|
||||
// notification (eventfd). Eventfds are usually internal to the Sentry but in
|
||||
// certain situations they may be converted into a host-backed eventfd.
|
||||
type EventFileDescription struct {
|
||||
vfsfd FileDescription
|
||||
FileDescriptionDefaultImpl
|
||||
DentryMetadataFileDescriptionImpl
|
||||
vfsfd vfs.FileDescription
|
||||
vfs.FileDescriptionDefaultImpl
|
||||
vfs.DentryMetadataFileDescriptionImpl
|
||||
|
||||
// queue is used to notify interested parties when the event object
|
||||
// becomes readable or writable.
|
||||
@@ -53,18 +55,18 @@ type EventFileDescription struct {
|
||||
hostfd int
|
||||
}
|
||||
|
||||
var _ FileDescriptionImpl = (*EventFileDescription)(nil)
|
||||
var _ vfs.FileDescriptionImpl = (*EventFileDescription)(nil)
|
||||
|
||||
// NewEventFD creates a new event fd.
|
||||
func (vfs *VirtualFilesystem) NewEventFD(initVal uint64, semMode bool, flags uint32) (*FileDescription, error) {
|
||||
vd := vfs.NewAnonVirtualDentry("[eventfd]")
|
||||
// New creates a new event fd.
|
||||
func New(vfsObj *vfs.VirtualFilesystem, initVal uint64, semMode bool, flags uint32) (*vfs.FileDescription, error) {
|
||||
vd := vfsObj.NewAnonVirtualDentry("[eventfd]")
|
||||
defer vd.DecRef()
|
||||
efd := &EventFileDescription{
|
||||
val: initVal,
|
||||
semMode: semMode,
|
||||
hostfd: -1,
|
||||
}
|
||||
if err := efd.vfsfd.Init(efd, flags, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{
|
||||
if err := efd.vfsfd.Init(efd, flags, vd.Mount(), vd.Dentry(), &vfs.FileDescriptionOptions{
|
||||
UseDentryMetadata: true,
|
||||
DenyPRead: true,
|
||||
DenyPWrite: true,
|
||||
@@ -117,7 +119,7 @@ func (efd *EventFileDescription) Release() {
|
||||
}
|
||||
|
||||
// Read implements FileDescriptionImpl.Read.
|
||||
func (efd *EventFileDescription) Read(ctx context.Context, dst usermem.IOSequence, _ ReadOptions) (int64, error) {
|
||||
func (efd *EventFileDescription) Read(ctx context.Context, dst usermem.IOSequence, _ vfs.ReadOptions) (int64, error) {
|
||||
if dst.NumBytes() < 8 {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
@@ -128,7 +130,7 @@ func (efd *EventFileDescription) Read(ctx context.Context, dst usermem.IOSequenc
|
||||
}
|
||||
|
||||
// Write implements FileDescriptionImpl.Write.
|
||||
func (efd *EventFileDescription) Write(ctx context.Context, src usermem.IOSequence, _ WriteOptions) (int64, error) {
|
||||
func (efd *EventFileDescription) Write(ctx context.Context, src usermem.IOSequence, _ vfs.WriteOptions) (int64, error) {
|
||||
if src.NumBytes() < 8 {
|
||||
return 0, syscall.EINVAL
|
||||
}
|
||||
@@ -12,13 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vfs
|
||||
package eventfd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sentry/contexttest"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
)
|
||||
@@ -34,15 +35,15 @@ func TestEventFD(t *testing.T) {
|
||||
|
||||
for _, initVal := range initVals {
|
||||
ctx := contexttest.Context(t)
|
||||
vfsObj := &VirtualFilesystem{}
|
||||
vfsObj := &vfs.VirtualFilesystem{}
|
||||
if err := vfsObj.Init(); err != nil {
|
||||
t.Fatalf("VFS init: %v", err)
|
||||
}
|
||||
|
||||
// Make a new eventfd that is writable.
|
||||
eventfd, err := vfsObj.NewEventFD(initVal, false, linux.O_RDWR)
|
||||
eventfd, err := New(vfsObj, initVal, false, linux.O_RDWR)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEventFD failed: %v", err)
|
||||
t.Fatalf("New() failed: %v", err)
|
||||
}
|
||||
defer eventfd.DecRef()
|
||||
|
||||
@@ -53,7 +54,7 @@ func TestEventFD(t *testing.T) {
|
||||
|
||||
data := []byte("00000124")
|
||||
// Create and submit a write request.
|
||||
n, err := eventfd.Write(ctx, usermem.BytesIOSequence(data), WriteOptions{})
|
||||
n, err := eventfd.Write(ctx, usermem.BytesIOSequence(data), vfs.WriteOptions{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -72,19 +73,19 @@ func TestEventFD(t *testing.T) {
|
||||
|
||||
func TestEventFDStat(t *testing.T) {
|
||||
ctx := contexttest.Context(t)
|
||||
vfsObj := &VirtualFilesystem{}
|
||||
vfsObj := &vfs.VirtualFilesystem{}
|
||||
if err := vfsObj.Init(); err != nil {
|
||||
t.Fatalf("VFS init: %v", err)
|
||||
}
|
||||
|
||||
// Make a new eventfd that is writable.
|
||||
eventfd, err := vfsObj.NewEventFD(0, false, linux.O_RDWR)
|
||||
eventfd, err := New(vfsObj, 0, false, linux.O_RDWR)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEventFD failed: %v", err)
|
||||
t.Fatalf("New() failed: %v", err)
|
||||
}
|
||||
defer eventfd.DecRef()
|
||||
|
||||
statx, err := eventfd.Stat(ctx, StatOptions{
|
||||
statx, err := eventfd.Stat(ctx, vfs.StatOptions{
|
||||
Mask: linux.STATX_BASIC_STATS,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -0,0 +1,17 @@
|
||||
load("//tools:defs.bzl", "go_library")
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
go_library(
|
||||
name = "timerfd",
|
||||
srcs = ["timerfd.go"],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
deps = [
|
||||
"//pkg/context",
|
||||
"//pkg/sentry/kernel/time",
|
||||
"//pkg/sentry/vfs",
|
||||
"//pkg/syserror",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
)
|
||||
@@ -12,13 +12,15 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package vfs
|
||||
// Package timerfd implements timer fds.
|
||||
package timerfd
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
|
||||
"gvisor.dev/gvisor/pkg/context"
|
||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
"gvisor.dev/gvisor/pkg/usermem"
|
||||
"gvisor.dev/gvisor/pkg/waiter"
|
||||
@@ -27,9 +29,9 @@ import (
|
||||
// TimerFileDescription implements FileDescriptionImpl for timer fds. It also
|
||||
// implements ktime.TimerListener.
|
||||
type TimerFileDescription struct {
|
||||
vfsfd FileDescription
|
||||
FileDescriptionDefaultImpl
|
||||
DentryMetadataFileDescriptionImpl
|
||||
vfsfd vfs.FileDescription
|
||||
vfs.FileDescriptionDefaultImpl
|
||||
vfs.DentryMetadataFileDescriptionImpl
|
||||
|
||||
events waiter.Queue
|
||||
timer *ktime.Timer
|
||||
@@ -40,16 +42,16 @@ type TimerFileDescription struct {
|
||||
val uint64
|
||||
}
|
||||
|
||||
var _ FileDescriptionImpl = (*TimerFileDescription)(nil)
|
||||
var _ vfs.FileDescriptionImpl = (*TimerFileDescription)(nil)
|
||||
var _ ktime.TimerListener = (*TimerFileDescription)(nil)
|
||||
|
||||
// NewTimerFD returns a new timer fd.
|
||||
func (vfs *VirtualFilesystem) NewTimerFD(clock ktime.Clock, flags uint32) (*FileDescription, error) {
|
||||
vd := vfs.NewAnonVirtualDentry("[timerfd]")
|
||||
// New returns a new timer fd.
|
||||
func New(vfsObj *vfs.VirtualFilesystem, clock ktime.Clock, flags uint32) (*vfs.FileDescription, error) {
|
||||
vd := vfsObj.NewAnonVirtualDentry("[timerfd]")
|
||||
defer vd.DecRef()
|
||||
tfd := &TimerFileDescription{}
|
||||
tfd.timer = ktime.NewTimer(clock, tfd)
|
||||
if err := tfd.vfsfd.Init(tfd, flags, vd.Mount(), vd.Dentry(), &FileDescriptionOptions{
|
||||
if err := tfd.vfsfd.Init(tfd, flags, vd.Mount(), vd.Dentry(), &vfs.FileDescriptionOptions{
|
||||
UseDentryMetadata: true,
|
||||
DenyPRead: true,
|
||||
DenyPWrite: true,
|
||||
@@ -60,7 +62,7 @@ func (vfs *VirtualFilesystem) NewTimerFD(clock ktime.Clock, flags uint32) (*File
|
||||
}
|
||||
|
||||
// Read implements FileDescriptionImpl.Read.
|
||||
func (tfd *TimerFileDescription) Read(ctx context.Context, dst usermem.IOSequence, opts ReadOptions) (int64, error) {
|
||||
func (tfd *TimerFileDescription) Read(ctx context.Context, dst usermem.IOSequence, opts vfs.ReadOptions) (int64, error) {
|
||||
const sizeofUint64 = 8
|
||||
if dst.NumBytes() < sizeofUint64 {
|
||||
return 0, syserror.EINVAL
|
||||
@@ -172,6 +172,7 @@ go_library(
|
||||
"//pkg/sentry/fsimpl/kernfs",
|
||||
"//pkg/sentry/fsimpl/pipefs",
|
||||
"//pkg/sentry/fsimpl/sockfs",
|
||||
"//pkg/sentry/fsimpl/timerfd",
|
||||
"//pkg/sentry/hostcpu",
|
||||
"//pkg/sentry/inet",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
|
||||
@@ -48,10 +48,11 @@ import (
|
||||
"gvisor.dev/gvisor/pkg/refs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fs/timerfd"
|
||||
oldtimerfd "gvisor.dev/gvisor/pkg/sentry/fs/timerfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsbridge"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/pipefs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/sockfs"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/timerfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/hostcpu"
|
||||
"gvisor.dev/gvisor/pkg/sentry/inet"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
|
||||
@@ -1068,11 +1069,11 @@ func (k *Kernel) pauseTimeLocked() {
|
||||
if t.fdTable != nil {
|
||||
t.fdTable.forEach(func(_ int32, file *fs.File, fd *vfs.FileDescription, _ FDFlags) {
|
||||
if VFS2Enabled {
|
||||
if tfd, ok := fd.Impl().(*vfs.TimerFileDescription); ok {
|
||||
if tfd, ok := fd.Impl().(*timerfd.TimerFileDescription); ok {
|
||||
tfd.PauseTimer()
|
||||
}
|
||||
} else {
|
||||
if tfd, ok := file.FileOperations.(*timerfd.TimerOperations); ok {
|
||||
if tfd, ok := file.FileOperations.(*oldtimerfd.TimerOperations); ok {
|
||||
tfd.PauseTimer()
|
||||
}
|
||||
}
|
||||
@@ -1104,11 +1105,11 @@ func (k *Kernel) resumeTimeLocked() {
|
||||
if t.fdTable != nil {
|
||||
t.fdTable.forEach(func(_ int32, file *fs.File, fd *vfs.FileDescription, _ FDFlags) {
|
||||
if VFS2Enabled {
|
||||
if tfd, ok := fd.Impl().(*vfs.TimerFileDescription); ok {
|
||||
if tfd, ok := fd.Impl().(*timerfd.TimerFileDescription); ok {
|
||||
tfd.ResumeTimer()
|
||||
}
|
||||
} else {
|
||||
if tfd, ok := file.FileOperations.(*timerfd.TimerOperations); ok {
|
||||
if tfd, ok := file.FileOperations.(*oldtimerfd.TimerOperations); ok {
|
||||
tfd.ResumeTimer()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,8 +39,10 @@ go_library(
|
||||
"//pkg/gohacks",
|
||||
"//pkg/sentry/arch",
|
||||
"//pkg/sentry/fsbridge",
|
||||
"//pkg/sentry/fsimpl/eventfd",
|
||||
"//pkg/sentry/fsimpl/pipefs",
|
||||
"//pkg/sentry/fsimpl/signalfd",
|
||||
"//pkg/sentry/fsimpl/timerfd",
|
||||
"//pkg/sentry/kernel",
|
||||
"//pkg/sentry/kernel/auth",
|
||||
"//pkg/sentry/kernel/pipe",
|
||||
|
||||
@@ -17,6 +17,7 @@ package vfs2
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/eventfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
@@ -31,12 +32,13 @@ func Eventfd2(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
|
||||
return 0, nil, syserror.EINVAL
|
||||
}
|
||||
|
||||
vfsObj := t.Kernel().VFS()
|
||||
fileFlags := uint32(linux.O_RDWR)
|
||||
if flags&linux.EFD_NONBLOCK != 0 {
|
||||
fileFlags |= linux.O_NONBLOCK
|
||||
}
|
||||
semMode := flags&linux.EFD_SEMAPHORE != 0
|
||||
eventfd, err := t.Kernel().VFS().NewEventFD(initVal, semMode, fileFlags)
|
||||
eventfd, err := eventfd.New(vfsObj, initVal, semMode, fileFlags)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
|
||||
@@ -17,9 +17,9 @@ package vfs2
|
||||
import (
|
||||
"gvisor.dev/gvisor/pkg/abi/linux"
|
||||
"gvisor.dev/gvisor/pkg/sentry/arch"
|
||||
"gvisor.dev/gvisor/pkg/sentry/fsimpl/timerfd"
|
||||
"gvisor.dev/gvisor/pkg/sentry/kernel"
|
||||
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
|
||||
"gvisor.dev/gvisor/pkg/sentry/vfs"
|
||||
"gvisor.dev/gvisor/pkg/syserror"
|
||||
)
|
||||
|
||||
@@ -32,9 +32,12 @@ func TimerfdCreate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel
|
||||
return 0, nil, syserror.EINVAL
|
||||
}
|
||||
|
||||
var fileFlags uint32
|
||||
// Timerfds aren't writable per se (their implementation of Write just
|
||||
// returns EINVAL), but they are "opened for writing", which is necessary
|
||||
// to actually reach said implementation of Write.
|
||||
fileFlags := uint32(linux.O_RDWR)
|
||||
if flags&linux.TFD_NONBLOCK != 0 {
|
||||
fileFlags = linux.O_NONBLOCK
|
||||
fileFlags |= linux.O_NONBLOCK
|
||||
}
|
||||
|
||||
var clock ktime.Clock
|
||||
@@ -46,10 +49,8 @@ func TimerfdCreate(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel
|
||||
default:
|
||||
return 0, nil, syserror.EINVAL
|
||||
}
|
||||
// Timerfds aren't writable per se (their implementation of Write just
|
||||
// returns EINVAL), but they are "opened for writing", which is necessary
|
||||
// to actually reach said implementation of Write.
|
||||
file, err := t.Kernel().VFS().NewTimerFD(clock, linux.O_RDWR|fileFlags)
|
||||
vfsObj := t.Kernel().VFS()
|
||||
file, err := timerfd.New(vfsObj, clock, fileFlags)
|
||||
if err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
@@ -80,7 +81,7 @@ func TimerfdSettime(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kerne
|
||||
}
|
||||
defer file.DecRef()
|
||||
|
||||
tfd, ok := file.Impl().(*vfs.TimerFileDescription)
|
||||
tfd, ok := file.Impl().(*timerfd.TimerFileDescription)
|
||||
if !ok {
|
||||
return 0, nil, syserror.EINVAL
|
||||
}
|
||||
@@ -114,7 +115,7 @@ func TimerfdGettime(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kerne
|
||||
}
|
||||
defer file.DecRef()
|
||||
|
||||
tfd, ok := file.Impl().(*vfs.TimerFileDescription)
|
||||
tfd, ok := file.Impl().(*timerfd.TimerFileDescription)
|
||||
if !ok {
|
||||
return 0, nil, syserror.EINVAL
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ go_library(
|
||||
"device.go",
|
||||
"epoll.go",
|
||||
"epoll_interest_list.go",
|
||||
"eventfd.go",
|
||||
"file_description.go",
|
||||
"file_description_impl_util.go",
|
||||
"filesystem.go",
|
||||
@@ -37,7 +36,6 @@ go_library(
|
||||
"pathname.go",
|
||||
"permissions.go",
|
||||
"resolving_path.go",
|
||||
"timerfd.go",
|
||||
"vfs.go",
|
||||
],
|
||||
visibility = ["//pkg/sentry:internal"],
|
||||
@@ -71,7 +69,6 @@ go_test(
|
||||
name = "vfs_test",
|
||||
size = "small",
|
||||
srcs = [
|
||||
"eventfd_test.go",
|
||||
"file_description_impl_util_test.go",
|
||||
"mount_test.go",
|
||||
],
|
||||
@@ -83,6 +80,5 @@ go_test(
|
||||
"//pkg/sync",
|
||||
"//pkg/syserror",
|
||||
"//pkg/usermem",
|
||||
"//pkg/waiter",
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user