diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-12-03 14:26:57 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-12-03 14:26:57 +0000 |
commit | b90360c0c293247f6e755e937ef518c1a9e0d2df (patch) | |
tree | 270a799d3b616e8648be3c22db446eb7ab9ee51c /pkg/sentry/vfs | |
parent | 194d07eeb5e3f0708fbfe4afd0d4d7dadd364863 (diff) | |
parent | 6f60a2b0a27a742690aa6acd5df1912ccb5fc8d3 (diff) |
Merge release-20201130.0-30-g6f60a2b0a (automated)
Diffstat (limited to 'pkg/sentry/vfs')
-rw-r--r-- | pkg/sentry/vfs/epoll.go | 10 | ||||
-rw-r--r-- | pkg/sentry/vfs/file_description.go | 9 | ||||
-rw-r--r-- | pkg/sentry/vfs/save_restore.go | 19 | ||||
-rw-r--r-- | pkg/sentry/vfs/vfs_state_autogen.go | 5 |
4 files changed, 31 insertions, 12 deletions
diff --git a/pkg/sentry/vfs/epoll.go b/pkg/sentry/vfs/epoll.go index a98aac52b..072655fe8 100644 --- a/pkg/sentry/vfs/epoll.go +++ b/pkg/sentry/vfs/epoll.go @@ -204,8 +204,8 @@ func (ep *EpollInstance) AddInterest(file *FileDescription, num int32, event lin file.EventRegister(&epi.waiter, wmask) // Check if the file is already ready. - if file.Readiness(wmask)&wmask != 0 { - epi.Callback(nil) + if m := file.Readiness(wmask) & wmask; m != 0 { + epi.Callback(nil, m) } // Add epi to file.epolls so that it is removed when the last @@ -274,8 +274,8 @@ func (ep *EpollInstance) ModifyInterest(file *FileDescription, num int32, event file.EventRegister(&epi.waiter, wmask) // Check if the file is already ready with the new mask. - if file.Readiness(wmask)&wmask != 0 { - epi.Callback(nil) + if m := file.Readiness(wmask) & wmask; m != 0 { + epi.Callback(nil, m) } return nil @@ -311,7 +311,7 @@ func (ep *EpollInstance) DeleteInterest(file *FileDescription, num int32) error } // Callback implements waiter.EntryCallback.Callback. -func (epi *epollInterest) Callback(*waiter.Entry) { +func (epi *epollInterest) Callback(*waiter.Entry, waiter.EventMask) { newReady := false epi.epoll.mu.Lock() if !epi.ready { diff --git a/pkg/sentry/vfs/file_description.go b/pkg/sentry/vfs/file_description.go index 51fddbaff..2153382e9 100644 --- a/pkg/sentry/vfs/file_description.go +++ b/pkg/sentry/vfs/file_description.go @@ -43,7 +43,7 @@ import ( type FileDescription struct { FileDescriptionRefs - // flagsMu protects statusFlags and asyncHandler below. + // flagsMu protects `statusFlags`, `saved`, and `asyncHandler` below. flagsMu sync.Mutex `state:"nosave"` // statusFlags contains status flags, "initialized by open(2) and possibly @@ -52,6 +52,11 @@ type FileDescription struct { // access to asyncHandler. statusFlags uint32 + // saved is true after beforeSave is called. This is used to prevent + // double-unregistration of asyncHandler. This does not work properly for + // save-resume, which is not currently supported in gVisor (see b/26588733). + saved bool `state:"nosave"` + // asyncHandler handles O_ASYNC signal generation. It is set with the // F_SETOWN or F_SETOWN_EX fcntls. For asyncHandler to be used, O_ASYNC must // also be set by fcntl(2). @@ -184,7 +189,7 @@ func (fd *FileDescription) DecRef(ctx context.Context) { } fd.vd.DecRef(ctx) fd.flagsMu.Lock() - if fd.statusFlags&linux.O_ASYNC != 0 && fd.asyncHandler != nil { + if !fd.saved && fd.statusFlags&linux.O_ASYNC != 0 && fd.asyncHandler != nil { fd.asyncHandler.Unregister(fd) } fd.asyncHandler = nil diff --git a/pkg/sentry/vfs/save_restore.go b/pkg/sentry/vfs/save_restore.go index 7723ed643..8f070ed53 100644 --- a/pkg/sentry/vfs/save_restore.go +++ b/pkg/sentry/vfs/save_restore.go @@ -18,8 +18,10 @@ import ( "fmt" "sync/atomic" + "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/refsvfs2" + "gvisor.dev/gvisor/pkg/waiter" ) // FilesystemImplSaveRestoreExtension is an optional extension to @@ -120,5 +122,20 @@ func (mnt *Mount) afterLoad() { func (epi *epollInterest) afterLoad() { // Mark all epollInterests as ready after restore so that the next call to // EpollInstance.ReadEvents() rechecks their readiness. - epi.Callback(nil) + epi.Callback(nil, waiter.EventMaskFromLinux(epi.mask)) +} + +// beforeSave is called by stateify. +func (fd *FileDescription) beforeSave() { + fd.saved = true + if fd.statusFlags&linux.O_ASYNC != 0 && fd.asyncHandler != nil { + fd.asyncHandler.Unregister(fd) + } +} + +// afterLoad is called by stateify. +func (fd *FileDescription) afterLoad() { + if fd.statusFlags&linux.O_ASYNC != 0 && fd.asyncHandler != nil { + fd.asyncHandler.Register(fd) + } } diff --git a/pkg/sentry/vfs/vfs_state_autogen.go b/pkg/sentry/vfs/vfs_state_autogen.go index 2cae3bc44..006d315be 100644 --- a/pkg/sentry/vfs/vfs_state_autogen.go +++ b/pkg/sentry/vfs/vfs_state_autogen.go @@ -422,8 +422,6 @@ func (fd *FileDescription) StateFields() []string { } } -func (fd *FileDescription) beforeSave() {} - func (fd *FileDescription) StateSave(stateSinkObject state.Sink) { fd.beforeSave() stateSinkObject.Save(0, &fd.FileDescriptionRefs) @@ -438,8 +436,6 @@ func (fd *FileDescription) StateSave(stateSinkObject state.Sink) { stateSinkObject.Save(9, &fd.impl) } -func (fd *FileDescription) afterLoad() {} - func (fd *FileDescription) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(0, &fd.FileDescriptionRefs) stateSourceObject.Load(1, &fd.statusFlags) @@ -451,6 +447,7 @@ func (fd *FileDescription) StateLoad(stateSourceObject state.Source) { stateSourceObject.Load(7, &fd.writable) stateSourceObject.Load(8, &fd.usedLockBSD) stateSourceObject.Load(9, &fd.impl) + stateSourceObject.AfterLoad(fd.afterLoad) } func (f *FileDescriptionOptions) StateTypeName() string { |