summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go15
-rw-r--r--pkg/sentry/fs/fdpipe/pipe.go3
-rw-r--r--pkg/sentry/fs/fs_state_autogen.go19
-rw-r--r--pkg/sentry/fs/host/host_state_autogen.go14
-rw-r--r--pkg/sentry/fs/host/inode.go2
-rw-r--r--pkg/sentry/fs/inotify.go2
-rw-r--r--pkg/sentry/fs/lock/lock.go2
-rw-r--r--pkg/sentry/fs/lock/lock_state_autogen.go6
-rw-r--r--pkg/sentry/fs/timerfd/timerfd.go2
-rw-r--r--pkg/sentry/fs/timerfd/timerfd_state_autogen.go14
-rw-r--r--pkg/sentry/fs/tty/line_discipline.go4
-rw-r--r--pkg/sentry/fs/tty/tty_state_autogen.go12
-rw-r--r--pkg/sentry/kernel/epoll/epoll.go15
-rw-r--r--pkg/sentry/kernel/epoll/epoll_state.go2
-rw-r--r--pkg/sentry/kernel/epoll/epoll_state_autogen.go37
-rw-r--r--pkg/sentry/kernel/eventfd/eventfd.go2
-rw-r--r--pkg/sentry/kernel/eventfd/eventfd_state_autogen.go18
-rw-r--r--pkg/sentry/kernel/kernel.go32
-rw-r--r--pkg/sentry/kernel/kernel_state_autogen.go237
-rw-r--r--pkg/sentry/kernel/pipe/pipe.go2
-rw-r--r--pkg/sentry/kernel/pipe/pipe_state_autogen.go35
-rw-r--r--pkg/sentry/kernel/task.go2
-rw-r--r--pkg/sentry/kernel/threads.go6
23 files changed, 225 insertions, 258 deletions
diff --git a/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go b/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go
index 68406ce66..247aba66b 100644
--- a/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go
+++ b/pkg/sentry/fs/fdpipe/fdpipe_state_autogen.go
@@ -13,6 +13,7 @@ func (p *pipeOperations) StateTypeName() string {
func (p *pipeOperations) StateFields() []string {
return []string{
+ "Queue",
"flags",
"opener",
"readAheadBuffer",
@@ -24,16 +25,18 @@ func (p *pipeOperations) StateSave(stateSinkObject state.Sink) {
p.beforeSave()
var flagsValue fs.FileFlags
flagsValue = p.saveFlags()
- stateSinkObject.SaveValue(0, flagsValue)
- stateSinkObject.Save(1, &p.opener)
- stateSinkObject.Save(2, &p.readAheadBuffer)
+ stateSinkObject.SaveValue(1, flagsValue)
+ stateSinkObject.Save(0, &p.Queue)
+ stateSinkObject.Save(2, &p.opener)
+ stateSinkObject.Save(3, &p.readAheadBuffer)
}
// +checklocksignore
func (p *pipeOperations) StateLoad(stateSourceObject state.Source) {
- stateSourceObject.LoadWait(1, &p.opener)
- stateSourceObject.Load(2, &p.readAheadBuffer)
- stateSourceObject.LoadValue(0, new(fs.FileFlags), func(y interface{}) { p.loadFlags(y.(fs.FileFlags)) })
+ stateSourceObject.Load(0, &p.Queue)
+ stateSourceObject.LoadWait(2, &p.opener)
+ stateSourceObject.Load(3, &p.readAheadBuffer)
+ stateSourceObject.LoadValue(1, new(fs.FileFlags), func(y interface{}) { p.loadFlags(y.(fs.FileFlags)) })
stateSourceObject.AfterLoad(p.afterLoad)
}
diff --git a/pkg/sentry/fs/fdpipe/pipe.go b/pkg/sentry/fs/fdpipe/pipe.go
index 4370cce33..d2eb03bb7 100644
--- a/pkg/sentry/fs/fdpipe/pipe.go
+++ b/pkg/sentry/fs/fdpipe/pipe.go
@@ -45,7 +45,8 @@ type pipeOperations struct {
fsutil.FileNoIoctl `state:"nosave"`
fsutil.FileNoSplice `state:"nosave"`
fsutil.FileUseInodeUnstableAttr `state:"nosave"`
- waiter.Queue `state:"nosave"`
+
+ waiter.Queue
// flags are the flags used to open the pipe.
flags fs.FileFlags `state:".(fs.FileFlags)"`
diff --git a/pkg/sentry/fs/fs_state_autogen.go b/pkg/sentry/fs/fs_state_autogen.go
index 62ab34d6f..22059a271 100644
--- a/pkg/sentry/fs/fs_state_autogen.go
+++ b/pkg/sentry/fs/fs_state_autogen.go
@@ -833,6 +833,7 @@ func (i *Inotify) StateTypeName() string {
func (i *Inotify) StateFields() []string {
return []string{
"id",
+ "Queue",
"events",
"scratch",
"nextWatch",
@@ -846,10 +847,11 @@ func (i *Inotify) beforeSave() {}
func (i *Inotify) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.id)
- stateSinkObject.Save(1, &i.events)
- stateSinkObject.Save(2, &i.scratch)
- stateSinkObject.Save(3, &i.nextWatch)
- stateSinkObject.Save(4, &i.watches)
+ stateSinkObject.Save(1, &i.Queue)
+ stateSinkObject.Save(2, &i.events)
+ stateSinkObject.Save(3, &i.scratch)
+ stateSinkObject.Save(4, &i.nextWatch)
+ stateSinkObject.Save(5, &i.watches)
}
func (i *Inotify) afterLoad() {}
@@ -857,10 +859,11 @@ func (i *Inotify) afterLoad() {}
// +checklocksignore
func (i *Inotify) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.id)
- stateSourceObject.Load(1, &i.events)
- stateSourceObject.Load(2, &i.scratch)
- stateSourceObject.Load(3, &i.nextWatch)
- stateSourceObject.Load(4, &i.watches)
+ stateSourceObject.Load(1, &i.Queue)
+ stateSourceObject.Load(2, &i.events)
+ stateSourceObject.Load(3, &i.scratch)
+ stateSourceObject.Load(4, &i.nextWatch)
+ stateSourceObject.Load(5, &i.watches)
}
func (e *Event) StateTypeName() string {
diff --git a/pkg/sentry/fs/host/host_state_autogen.go b/pkg/sentry/fs/host/host_state_autogen.go
index b06247919..50869fd79 100644
--- a/pkg/sentry/fs/host/host_state_autogen.go
+++ b/pkg/sentry/fs/host/host_state_autogen.go
@@ -115,6 +115,7 @@ func (i *inodeFileState) StateTypeName() string {
func (i *inodeFileState) StateFields() []string {
return []string{
"descriptor",
+ "queue",
"sattr",
"savedUAttr",
}
@@ -125,19 +126,18 @@ func (i *inodeFileState) beforeSave() {}
// +checklocksignore
func (i *inodeFileState) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
- if !state.IsZeroValue(&i.queue) {
- state.Failf("queue is %#v, expected zero", &i.queue)
- }
stateSinkObject.Save(0, &i.descriptor)
- stateSinkObject.Save(1, &i.sattr)
- stateSinkObject.Save(2, &i.savedUAttr)
+ stateSinkObject.Save(1, &i.queue)
+ stateSinkObject.Save(2, &i.sattr)
+ stateSinkObject.Save(3, &i.savedUAttr)
}
// +checklocksignore
func (i *inodeFileState) StateLoad(stateSourceObject state.Source) {
stateSourceObject.LoadWait(0, &i.descriptor)
- stateSourceObject.LoadWait(1, &i.sattr)
- stateSourceObject.Load(2, &i.savedUAttr)
+ stateSourceObject.Load(1, &i.queue)
+ stateSourceObject.LoadWait(2, &i.sattr)
+ stateSourceObject.Load(3, &i.savedUAttr)
stateSourceObject.AfterLoad(i.afterLoad)
}
diff --git a/pkg/sentry/fs/host/inode.go b/pkg/sentry/fs/host/inode.go
index 92d58e3e9..99c37291e 100644
--- a/pkg/sentry/fs/host/inode.go
+++ b/pkg/sentry/fs/host/inode.go
@@ -70,7 +70,7 @@ type inodeFileState struct {
descriptor *descriptor `state:"wait"`
// Event queue for blocking operations.
- queue waiter.Queue `state:"zerovalue"`
+ queue waiter.Queue
// sattr is used to restore the inodeOperations.
sattr fs.StableAttr `state:"wait"`
diff --git a/pkg/sentry/fs/inotify.go b/pkg/sentry/fs/inotify.go
index 51cd6cd37..941f37116 100644
--- a/pkg/sentry/fs/inotify.go
+++ b/pkg/sentry/fs/inotify.go
@@ -43,7 +43,7 @@ type Inotify struct {
// user, since we may aggressively reuse an id on S/R.
id uint64
- waiter.Queue `state:"nosave"`
+ waiter.Queue
// evMu *only* protects the events list. We need a separate lock because
// while queuing events, a watch needs to lock the event queue, and using mu
diff --git a/pkg/sentry/fs/lock/lock.go b/pkg/sentry/fs/lock/lock.go
index 7d7a207cc..e39d340fe 100644
--- a/pkg/sentry/fs/lock/lock.go
+++ b/pkg/sentry/fs/lock/lock.go
@@ -132,7 +132,7 @@ type Locks struct {
locks LockSet
// blockedQueue is the queue of waiters that are waiting on a lock.
- blockedQueue waiter.Queue `state:"zerovalue"`
+ blockedQueue waiter.Queue
}
// Blocker is the interface used for blocking locks. Passing a nil Blocker
diff --git a/pkg/sentry/fs/lock/lock_state_autogen.go b/pkg/sentry/fs/lock/lock_state_autogen.go
index 4a9d0a1d8..8ddb3795c 100644
--- a/pkg/sentry/fs/lock/lock_state_autogen.go
+++ b/pkg/sentry/fs/lock/lock_state_autogen.go
@@ -69,6 +69,7 @@ func (l *Locks) StateTypeName() string {
func (l *Locks) StateFields() []string {
return []string{
"locks",
+ "blockedQueue",
}
}
@@ -77,10 +78,8 @@ func (l *Locks) beforeSave() {}
// +checklocksignore
func (l *Locks) StateSave(stateSinkObject state.Sink) {
l.beforeSave()
- if !state.IsZeroValue(&l.blockedQueue) {
- state.Failf("blockedQueue is %#v, expected zero", &l.blockedQueue)
- }
stateSinkObject.Save(0, &l.locks)
+ stateSinkObject.Save(1, &l.blockedQueue)
}
func (l *Locks) afterLoad() {}
@@ -88,6 +87,7 @@ func (l *Locks) afterLoad() {}
// +checklocksignore
func (l *Locks) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &l.locks)
+ stateSourceObject.Load(1, &l.blockedQueue)
}
func (r *LockRange) StateTypeName() string {
diff --git a/pkg/sentry/fs/timerfd/timerfd.go b/pkg/sentry/fs/timerfd/timerfd.go
index 1c8518d71..ca8be8683 100644
--- a/pkg/sentry/fs/timerfd/timerfd.go
+++ b/pkg/sentry/fs/timerfd/timerfd.go
@@ -43,7 +43,7 @@ type TimerOperations struct {
fsutil.FileNoopFlush `state:"nosave"`
fsutil.FileUseInodeUnstableAttr `state:"nosave"`
- events waiter.Queue `state:"zerovalue"`
+ events waiter.Queue
timer *ktime.Timer
// val is the number of timer expirations since the last successful call to
diff --git a/pkg/sentry/fs/timerfd/timerfd_state_autogen.go b/pkg/sentry/fs/timerfd/timerfd_state_autogen.go
index 822eecdd6..6cab87796 100644
--- a/pkg/sentry/fs/timerfd/timerfd_state_autogen.go
+++ b/pkg/sentry/fs/timerfd/timerfd_state_autogen.go
@@ -12,6 +12,7 @@ func (t *TimerOperations) StateTypeName() string {
func (t *TimerOperations) StateFields() []string {
return []string{
+ "events",
"timer",
"val",
}
@@ -22,19 +23,18 @@ func (t *TimerOperations) beforeSave() {}
// +checklocksignore
func (t *TimerOperations) StateSave(stateSinkObject state.Sink) {
t.beforeSave()
- if !state.IsZeroValue(&t.events) {
- state.Failf("events is %#v, expected zero", &t.events)
- }
- stateSinkObject.Save(0, &t.timer)
- stateSinkObject.Save(1, &t.val)
+ stateSinkObject.Save(0, &t.events)
+ stateSinkObject.Save(1, &t.timer)
+ stateSinkObject.Save(2, &t.val)
}
func (t *TimerOperations) afterLoad() {}
// +checklocksignore
func (t *TimerOperations) StateLoad(stateSourceObject state.Source) {
- stateSourceObject.Load(0, &t.timer)
- stateSourceObject.Load(1, &t.val)
+ stateSourceObject.Load(0, &t.events)
+ stateSourceObject.Load(1, &t.timer)
+ stateSourceObject.Load(2, &t.val)
}
func init() {
diff --git a/pkg/sentry/fs/tty/line_discipline.go b/pkg/sentry/fs/tty/line_discipline.go
index f9fca6d8e..f2c9e9668 100644
--- a/pkg/sentry/fs/tty/line_discipline.go
+++ b/pkg/sentry/fs/tty/line_discipline.go
@@ -102,10 +102,10 @@ type lineDiscipline struct {
column int
// masterWaiter is used to wait on the master end of the TTY.
- masterWaiter waiter.Queue `state:"zerovalue"`
+ masterWaiter waiter.Queue
// replicaWaiter is used to wait on the replica end of the TTY.
- replicaWaiter waiter.Queue `state:"zerovalue"`
+ replicaWaiter waiter.Queue
}
func newLineDiscipline(termios linux.KernelTermios) *lineDiscipline {
diff --git a/pkg/sentry/fs/tty/tty_state_autogen.go b/pkg/sentry/fs/tty/tty_state_autogen.go
index 2fb0a8d27..1319a8d28 100644
--- a/pkg/sentry/fs/tty/tty_state_autogen.go
+++ b/pkg/sentry/fs/tty/tty_state_autogen.go
@@ -127,6 +127,8 @@ func (l *lineDiscipline) StateFields() []string {
"outQueue",
"termios",
"column",
+ "masterWaiter",
+ "replicaWaiter",
}
}
@@ -135,17 +137,13 @@ func (l *lineDiscipline) beforeSave() {}
// +checklocksignore
func (l *lineDiscipline) StateSave(stateSinkObject state.Sink) {
l.beforeSave()
- if !state.IsZeroValue(&l.masterWaiter) {
- state.Failf("masterWaiter is %#v, expected zero", &l.masterWaiter)
- }
- if !state.IsZeroValue(&l.replicaWaiter) {
- state.Failf("replicaWaiter is %#v, expected zero", &l.replicaWaiter)
- }
stateSinkObject.Save(0, &l.size)
stateSinkObject.Save(1, &l.inQueue)
stateSinkObject.Save(2, &l.outQueue)
stateSinkObject.Save(3, &l.termios)
stateSinkObject.Save(4, &l.column)
+ stateSinkObject.Save(5, &l.masterWaiter)
+ stateSinkObject.Save(6, &l.replicaWaiter)
}
func (l *lineDiscipline) afterLoad() {}
@@ -157,6 +155,8 @@ func (l *lineDiscipline) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(2, &l.outQueue)
stateSourceObject.Load(3, &l.termios)
stateSourceObject.Load(4, &l.column)
+ stateSourceObject.Load(5, &l.masterWaiter)
+ stateSourceObject.Load(6, &l.replicaWaiter)
}
func (o *outputQueueTransformer) StateTypeName() string {
diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go
index 6006c46a9..8d0a21baf 100644
--- a/pkg/sentry/kernel/epoll/epoll.go
+++ b/pkg/sentry/kernel/epoll/epoll.go
@@ -66,7 +66,7 @@ type pollEntry struct {
file *refs.WeakRef `state:"manual"`
id FileIdentifier `state:"wait"`
userData [2]int32
- waiter waiter.Entry `state:"manual"`
+ waiter waiter.Entry
mask waiter.EventMask
flags EntryFlags
@@ -102,7 +102,7 @@ type EventPoll struct {
// Wait queue is used to notify interested parties when the event poll
// object itself becomes readable or writable.
- waiter.Queue `state:"zerovalue"`
+ waiter.Queue
// files is the map of all the files currently being observed, it is
// protected by mu.
@@ -454,14 +454,3 @@ func (e *EventPoll) RemoveEntry(ctx context.Context, id FileIdentifier) error {
return nil
}
-
-// UnregisterEpollWaiters removes the epoll waiter objects from the waiting
-// queues. This is different from Release() as the file is not dereferenced.
-func (e *EventPoll) UnregisterEpollWaiters() {
- e.mu.Lock()
- defer e.mu.Unlock()
-
- for _, entry := range e.files {
- entry.id.File.EventUnregister(&entry.waiter)
- }
-}
diff --git a/pkg/sentry/kernel/epoll/epoll_state.go b/pkg/sentry/kernel/epoll/epoll_state.go
index e08d6287f..135a6d72c 100644
--- a/pkg/sentry/kernel/epoll/epoll_state.go
+++ b/pkg/sentry/kernel/epoll/epoll_state.go
@@ -21,9 +21,7 @@ import (
// afterLoad is invoked by stateify.
func (p *pollEntry) afterLoad() {
- p.waiter.Callback = p
p.file = refs.NewWeakRef(p.id.File, p)
- p.id.File.EventRegister(&p.waiter, p.mask)
}
// afterLoad is invoked by stateify.
diff --git a/pkg/sentry/kernel/epoll/epoll_state_autogen.go b/pkg/sentry/kernel/epoll/epoll_state_autogen.go
index 44bd520ac..25fbc8f72 100644
--- a/pkg/sentry/kernel/epoll/epoll_state_autogen.go
+++ b/pkg/sentry/kernel/epoll/epoll_state_autogen.go
@@ -43,6 +43,7 @@ func (p *pollEntry) StateFields() []string {
"pollEntryEntry",
"id",
"userData",
+ "waiter",
"mask",
"flags",
"epoll",
@@ -57,9 +58,10 @@ func (p *pollEntry) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(0, &p.pollEntryEntry)
stateSinkObject.Save(1, &p.id)
stateSinkObject.Save(2, &p.userData)
- stateSinkObject.Save(3, &p.mask)
- stateSinkObject.Save(4, &p.flags)
- stateSinkObject.Save(5, &p.epoll)
+ stateSinkObject.Save(3, &p.waiter)
+ stateSinkObject.Save(4, &p.mask)
+ stateSinkObject.Save(5, &p.flags)
+ stateSinkObject.Save(6, &p.epoll)
}
// +checklocksignore
@@ -67,9 +69,10 @@ func (p *pollEntry) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &p.pollEntryEntry)
stateSourceObject.LoadWait(1, &p.id)
stateSourceObject.Load(2, &p.userData)
- stateSourceObject.Load(3, &p.mask)
- stateSourceObject.Load(4, &p.flags)
- stateSourceObject.Load(5, &p.epoll)
+ stateSourceObject.Load(3, &p.waiter)
+ stateSourceObject.Load(4, &p.mask)
+ stateSourceObject.Load(5, &p.flags)
+ stateSourceObject.Load(6, &p.epoll)
stateSourceObject.AfterLoad(p.afterLoad)
}
@@ -79,6 +82,7 @@ func (e *EventPoll) StateTypeName() string {
func (e *EventPoll) StateFields() []string {
return []string{
+ "Queue",
"files",
"readyList",
"waitingList",
@@ -109,21 +113,20 @@ func (e *EventPoll) StateSave(stateSinkObject state.Sink) {
if !state.IsZeroValue(&e.FileNoMMap) {
state.Failf("FileNoMMap is %#v, expected zero", &e.FileNoMMap)
}
- if !state.IsZeroValue(&e.Queue) {
- state.Failf("Queue is %#v, expected zero", &e.Queue)
- }
- stateSinkObject.Save(0, &e.files)
- stateSinkObject.Save(1, &e.readyList)
- stateSinkObject.Save(2, &e.waitingList)
- stateSinkObject.Save(3, &e.disabledList)
+ stateSinkObject.Save(0, &e.Queue)
+ stateSinkObject.Save(1, &e.files)
+ stateSinkObject.Save(2, &e.readyList)
+ stateSinkObject.Save(3, &e.waitingList)
+ stateSinkObject.Save(4, &e.disabledList)
}
// +checklocksignore
func (e *EventPoll) StateLoad(stateSourceObject state.Source) {
- stateSourceObject.Load(0, &e.files)
- stateSourceObject.Load(1, &e.readyList)
- stateSourceObject.Load(2, &e.waitingList)
- stateSourceObject.Load(3, &e.disabledList)
+ stateSourceObject.Load(0, &e.Queue)
+ stateSourceObject.Load(1, &e.files)
+ stateSourceObject.Load(2, &e.readyList)
+ stateSourceObject.Load(3, &e.waitingList)
+ stateSourceObject.Load(4, &e.disabledList)
stateSourceObject.AfterLoad(e.afterLoad)
}
diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go
index 5ea44a2c2..bf625dede 100644
--- a/pkg/sentry/kernel/eventfd/eventfd.go
+++ b/pkg/sentry/kernel/eventfd/eventfd.go
@@ -54,7 +54,7 @@ type EventOperations struct {
// Queue is used to notify interested parties when the event object
// becomes readable or writable.
- wq waiter.Queue `state:"zerovalue"`
+ wq waiter.Queue
// val is the current value of the event counter.
val uint64
diff --git a/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go b/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go
index 596920c42..97b5089d1 100644
--- a/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go
+++ b/pkg/sentry/kernel/eventfd/eventfd_state_autogen.go
@@ -12,6 +12,7 @@ func (e *EventOperations) StateTypeName() string {
func (e *EventOperations) StateFields() []string {
return []string{
+ "wq",
"val",
"semMode",
"hostfd",
@@ -23,21 +24,20 @@ func (e *EventOperations) beforeSave() {}
// +checklocksignore
func (e *EventOperations) StateSave(stateSinkObject state.Sink) {
e.beforeSave()
- if !state.IsZeroValue(&e.wq) {
- state.Failf("wq is %#v, expected zero", &e.wq)
- }
- stateSinkObject.Save(0, &e.val)
- stateSinkObject.Save(1, &e.semMode)
- stateSinkObject.Save(2, &e.hostfd)
+ stateSinkObject.Save(0, &e.wq)
+ stateSinkObject.Save(1, &e.val)
+ stateSinkObject.Save(2, &e.semMode)
+ stateSinkObject.Save(3, &e.hostfd)
}
func (e *EventOperations) afterLoad() {}
// +checklocksignore
func (e *EventOperations) StateLoad(stateSourceObject state.Source) {
- stateSourceObject.Load(0, &e.val)
- stateSourceObject.Load(1, &e.semMode)
- stateSourceObject.Load(2, &e.hostfd)
+ stateSourceObject.Load(0, &e.wq)
+ stateSourceObject.Load(1, &e.val)
+ stateSourceObject.Load(2, &e.semMode)
+ stateSourceObject.Load(3, &e.hostfd)
}
func init() {
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go
index f913d25db..5dc821a48 100644
--- a/pkg/sentry/kernel/kernel.go
+++ b/pkg/sentry/kernel/kernel.go
@@ -57,7 +57,6 @@ import (
"gvisor.dev/gvisor/pkg/sentry/hostcpu"
"gvisor.dev/gvisor/pkg/sentry/inet"
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
- "gvisor.dev/gvisor/pkg/sentry/kernel/epoll"
"gvisor.dev/gvisor/pkg/sentry/kernel/futex"
"gvisor.dev/gvisor/pkg/sentry/kernel/sched"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
@@ -486,11 +485,6 @@ func (k *Kernel) SaveTo(ctx context.Context, w wire.Writer) error {
return err
}
- // Remove all epoll waiter objects from underlying wait queues.
- // NOTE: for programs to resume execution in future snapshot scenarios,
- // we will need to re-establish these waiter objects after saving.
- k.tasks.unregisterEpollWaiters(ctx)
-
// Clear the dirent cache before saving because Dirents must be Loaded in a
// particular order (parents before children), and Loading dirents from a cache
// breaks that order.
@@ -623,32 +617,6 @@ func (k *Kernel) flushWritesToFiles(ctx context.Context) error {
})
}
-// Preconditions: !VFS2Enabled.
-func (ts *TaskSet) unregisterEpollWaiters(ctx context.Context) {
- ts.mu.RLock()
- defer ts.mu.RUnlock()
-
- // Tasks that belong to the same process could potentially point to the
- // same FDTable. So we retain a map of processed ones to avoid
- // processing the same FDTable multiple times.
- processed := make(map[*FDTable]struct{})
- for t := range ts.Root.tids {
- // We can skip locking Task.mu here since the kernel is paused.
- if t.fdTable == nil {
- continue
- }
- if _, ok := processed[t.fdTable]; ok {
- continue
- }
- t.fdTable.forEach(ctx, func(_ int32, file *fs.File, _ *vfs.FileDescription, _ FDFlags) {
- if e, ok := file.FileOperations.(*epoll.EventPoll); ok {
- e.UnregisterEpollWaiters()
- }
- })
- processed[t.fdTable] = struct{}{}
- }
-}
-
// Preconditions: The kernel must be paused.
func (k *Kernel) invalidateUnsavableMappings(ctx context.Context) error {
invalidated := make(map[*mm.MemoryManager]struct{})
diff --git a/pkg/sentry/kernel/kernel_state_autogen.go b/pkg/sentry/kernel/kernel_state_autogen.go
index d48c96425..ef8dd88f6 100644
--- a/pkg/sentry/kernel/kernel_state_autogen.go
+++ b/pkg/sentry/kernel/kernel_state_autogen.go
@@ -1318,6 +1318,7 @@ func (t *Task) StateFields() []string {
"haveSavedSignalMask",
"savedSignalMask",
"signalStack",
+ "signalQueue",
"groupStopPending",
"groupStopAcknowledged",
"trapStopPending",
@@ -1377,15 +1378,12 @@ func (t *Task) beforeSave() {}
// +checklocksignore
func (t *Task) StateSave(stateSinkObject state.Sink) {
t.beforeSave()
- if !state.IsZeroValue(&t.signalQueue) {
- state.Failf("signalQueue is %#v, expected zero", &t.signalQueue)
- }
var ptraceTracerValue *Task
ptraceTracerValue = t.savePtraceTracer()
- stateSinkObject.SaveValue(31, ptraceTracerValue)
+ stateSinkObject.SaveValue(32, ptraceTracerValue)
var syscallFiltersValue []bpf.Program
syscallFiltersValue = t.saveSyscallFilters()
- stateSinkObject.SaveValue(48, syscallFiltersValue)
+ stateSinkObject.SaveValue(49, syscallFiltersValue)
stateSinkObject.Save(0, &t.taskNode)
stateSinkObject.Save(1, &t.runState)
stateSinkObject.Save(2, &t.taskWorkCount)
@@ -1399,55 +1397,56 @@ func (t *Task) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(10, &t.haveSavedSignalMask)
stateSinkObject.Save(11, &t.savedSignalMask)
stateSinkObject.Save(12, &t.signalStack)
- stateSinkObject.Save(13, &t.groupStopPending)
- stateSinkObject.Save(14, &t.groupStopAcknowledged)
- stateSinkObject.Save(15, &t.trapStopPending)
- stateSinkObject.Save(16, &t.trapNotifyPending)
- stateSinkObject.Save(17, &t.stop)
- stateSinkObject.Save(18, &t.exitStatus)
- stateSinkObject.Save(19, &t.syscallRestartBlock)
- stateSinkObject.Save(20, &t.k)
- stateSinkObject.Save(21, &t.containerID)
- stateSinkObject.Save(22, &t.image)
- stateSinkObject.Save(23, &t.fsContext)
- stateSinkObject.Save(24, &t.fdTable)
- stateSinkObject.Save(25, &t.vforkParent)
- stateSinkObject.Save(26, &t.exitState)
- stateSinkObject.Save(27, &t.exitTracerNotified)
- stateSinkObject.Save(28, &t.exitTracerAcked)
- stateSinkObject.Save(29, &t.exitParentNotified)
- stateSinkObject.Save(30, &t.exitParentAcked)
- stateSinkObject.Save(32, &t.ptraceTracees)
- stateSinkObject.Save(33, &t.ptraceSeized)
- stateSinkObject.Save(34, &t.ptraceOpts)
- stateSinkObject.Save(35, &t.ptraceSyscallMode)
- stateSinkObject.Save(36, &t.ptraceSinglestep)
- stateSinkObject.Save(37, &t.ptraceCode)
- stateSinkObject.Save(38, &t.ptraceSiginfo)
- stateSinkObject.Save(39, &t.ptraceEventMsg)
- stateSinkObject.Save(40, &t.ptraceYAMAExceptionAdded)
- stateSinkObject.Save(41, &t.ioUsage)
- stateSinkObject.Save(42, &t.creds)
- stateSinkObject.Save(43, &t.utsns)
- stateSinkObject.Save(44, &t.ipcns)
- stateSinkObject.Save(45, &t.abstractSockets)
- stateSinkObject.Save(46, &t.mountNamespaceVFS2)
- stateSinkObject.Save(47, &t.parentDeathSignal)
- stateSinkObject.Save(49, &t.cleartid)
- stateSinkObject.Save(50, &t.allowedCPUMask)
- stateSinkObject.Save(51, &t.cpu)
- stateSinkObject.Save(52, &t.niceness)
- stateSinkObject.Save(53, &t.numaPolicy)
- stateSinkObject.Save(54, &t.numaNodeMask)
- stateSinkObject.Save(55, &t.netns)
- stateSinkObject.Save(56, &t.rseqCPU)
- stateSinkObject.Save(57, &t.oldRSeqCPUAddr)
- stateSinkObject.Save(58, &t.rseqAddr)
- stateSinkObject.Save(59, &t.rseqSignature)
- stateSinkObject.Save(60, &t.robustList)
- stateSinkObject.Save(61, &t.startTime)
- stateSinkObject.Save(62, &t.kcov)
- stateSinkObject.Save(63, &t.cgroups)
+ stateSinkObject.Save(13, &t.signalQueue)
+ stateSinkObject.Save(14, &t.groupStopPending)
+ stateSinkObject.Save(15, &t.groupStopAcknowledged)
+ stateSinkObject.Save(16, &t.trapStopPending)
+ stateSinkObject.Save(17, &t.trapNotifyPending)
+ stateSinkObject.Save(18, &t.stop)
+ stateSinkObject.Save(19, &t.exitStatus)
+ stateSinkObject.Save(20, &t.syscallRestartBlock)
+ stateSinkObject.Save(21, &t.k)
+ stateSinkObject.Save(22, &t.containerID)
+ stateSinkObject.Save(23, &t.image)
+ stateSinkObject.Save(24, &t.fsContext)
+ stateSinkObject.Save(25, &t.fdTable)
+ stateSinkObject.Save(26, &t.vforkParent)
+ stateSinkObject.Save(27, &t.exitState)
+ stateSinkObject.Save(28, &t.exitTracerNotified)
+ stateSinkObject.Save(29, &t.exitTracerAcked)
+ stateSinkObject.Save(30, &t.exitParentNotified)
+ stateSinkObject.Save(31, &t.exitParentAcked)
+ stateSinkObject.Save(33, &t.ptraceTracees)
+ stateSinkObject.Save(34, &t.ptraceSeized)
+ stateSinkObject.Save(35, &t.ptraceOpts)
+ stateSinkObject.Save(36, &t.ptraceSyscallMode)
+ stateSinkObject.Save(37, &t.ptraceSinglestep)
+ stateSinkObject.Save(38, &t.ptraceCode)
+ stateSinkObject.Save(39, &t.ptraceSiginfo)
+ stateSinkObject.Save(40, &t.ptraceEventMsg)
+ stateSinkObject.Save(41, &t.ptraceYAMAExceptionAdded)
+ stateSinkObject.Save(42, &t.ioUsage)
+ stateSinkObject.Save(43, &t.creds)
+ stateSinkObject.Save(44, &t.utsns)
+ stateSinkObject.Save(45, &t.ipcns)
+ stateSinkObject.Save(46, &t.abstractSockets)
+ stateSinkObject.Save(47, &t.mountNamespaceVFS2)
+ stateSinkObject.Save(48, &t.parentDeathSignal)
+ stateSinkObject.Save(50, &t.cleartid)
+ stateSinkObject.Save(51, &t.allowedCPUMask)
+ stateSinkObject.Save(52, &t.cpu)
+ stateSinkObject.Save(53, &t.niceness)
+ stateSinkObject.Save(54, &t.numaPolicy)
+ stateSinkObject.Save(55, &t.numaNodeMask)
+ stateSinkObject.Save(56, &t.netns)
+ stateSinkObject.Save(57, &t.rseqCPU)
+ stateSinkObject.Save(58, &t.oldRSeqCPUAddr)
+ stateSinkObject.Save(59, &t.rseqAddr)
+ stateSinkObject.Save(60, &t.rseqSignature)
+ stateSinkObject.Save(61, &t.robustList)
+ stateSinkObject.Save(62, &t.startTime)
+ stateSinkObject.Save(63, &t.kcov)
+ stateSinkObject.Save(64, &t.cgroups)
}
// +checklocksignore
@@ -1465,57 +1464,58 @@ func (t *Task) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(10, &t.haveSavedSignalMask)
stateSourceObject.Load(11, &t.savedSignalMask)
stateSourceObject.Load(12, &t.signalStack)
- stateSourceObject.Load(13, &t.groupStopPending)
- stateSourceObject.Load(14, &t.groupStopAcknowledged)
- stateSourceObject.Load(15, &t.trapStopPending)
- stateSourceObject.Load(16, &t.trapNotifyPending)
- stateSourceObject.Load(17, &t.stop)
- stateSourceObject.Load(18, &t.exitStatus)
- stateSourceObject.Load(19, &t.syscallRestartBlock)
- stateSourceObject.Load(20, &t.k)
- stateSourceObject.Load(21, &t.containerID)
- stateSourceObject.Load(22, &t.image)
- stateSourceObject.Load(23, &t.fsContext)
- stateSourceObject.Load(24, &t.fdTable)
- stateSourceObject.Load(25, &t.vforkParent)
- stateSourceObject.Load(26, &t.exitState)
- stateSourceObject.Load(27, &t.exitTracerNotified)
- stateSourceObject.Load(28, &t.exitTracerAcked)
- stateSourceObject.Load(29, &t.exitParentNotified)
- stateSourceObject.Load(30, &t.exitParentAcked)
- stateSourceObject.Load(32, &t.ptraceTracees)
- stateSourceObject.Load(33, &t.ptraceSeized)
- stateSourceObject.Load(34, &t.ptraceOpts)
- stateSourceObject.Load(35, &t.ptraceSyscallMode)
- stateSourceObject.Load(36, &t.ptraceSinglestep)
- stateSourceObject.Load(37, &t.ptraceCode)
- stateSourceObject.Load(38, &t.ptraceSiginfo)
- stateSourceObject.Load(39, &t.ptraceEventMsg)
- stateSourceObject.Load(40, &t.ptraceYAMAExceptionAdded)
- stateSourceObject.Load(41, &t.ioUsage)
- stateSourceObject.Load(42, &t.creds)
- stateSourceObject.Load(43, &t.utsns)
- stateSourceObject.Load(44, &t.ipcns)
- stateSourceObject.Load(45, &t.abstractSockets)
- stateSourceObject.Load(46, &t.mountNamespaceVFS2)
- stateSourceObject.Load(47, &t.parentDeathSignal)
- stateSourceObject.Load(49, &t.cleartid)
- stateSourceObject.Load(50, &t.allowedCPUMask)
- stateSourceObject.Load(51, &t.cpu)
- stateSourceObject.Load(52, &t.niceness)
- stateSourceObject.Load(53, &t.numaPolicy)
- stateSourceObject.Load(54, &t.numaNodeMask)
- stateSourceObject.Load(55, &t.netns)
- stateSourceObject.Load(56, &t.rseqCPU)
- stateSourceObject.Load(57, &t.oldRSeqCPUAddr)
- stateSourceObject.Load(58, &t.rseqAddr)
- stateSourceObject.Load(59, &t.rseqSignature)
- stateSourceObject.Load(60, &t.robustList)
- stateSourceObject.Load(61, &t.startTime)
- stateSourceObject.Load(62, &t.kcov)
- stateSourceObject.Load(63, &t.cgroups)
- stateSourceObject.LoadValue(31, new(*Task), func(y interface{}) { t.loadPtraceTracer(y.(*Task)) })
- stateSourceObject.LoadValue(48, new([]bpf.Program), func(y interface{}) { t.loadSyscallFilters(y.([]bpf.Program)) })
+ stateSourceObject.Load(13, &t.signalQueue)
+ stateSourceObject.Load(14, &t.groupStopPending)
+ stateSourceObject.Load(15, &t.groupStopAcknowledged)
+ stateSourceObject.Load(16, &t.trapStopPending)
+ stateSourceObject.Load(17, &t.trapNotifyPending)
+ stateSourceObject.Load(18, &t.stop)
+ stateSourceObject.Load(19, &t.exitStatus)
+ stateSourceObject.Load(20, &t.syscallRestartBlock)
+ stateSourceObject.Load(21, &t.k)
+ stateSourceObject.Load(22, &t.containerID)
+ stateSourceObject.Load(23, &t.image)
+ stateSourceObject.Load(24, &t.fsContext)
+ stateSourceObject.Load(25, &t.fdTable)
+ stateSourceObject.Load(26, &t.vforkParent)
+ stateSourceObject.Load(27, &t.exitState)
+ stateSourceObject.Load(28, &t.exitTracerNotified)
+ stateSourceObject.Load(29, &t.exitTracerAcked)
+ stateSourceObject.Load(30, &t.exitParentNotified)
+ stateSourceObject.Load(31, &t.exitParentAcked)
+ stateSourceObject.Load(33, &t.ptraceTracees)
+ stateSourceObject.Load(34, &t.ptraceSeized)
+ stateSourceObject.Load(35, &t.ptraceOpts)
+ stateSourceObject.Load(36, &t.ptraceSyscallMode)
+ stateSourceObject.Load(37, &t.ptraceSinglestep)
+ stateSourceObject.Load(38, &t.ptraceCode)
+ stateSourceObject.Load(39, &t.ptraceSiginfo)
+ stateSourceObject.Load(40, &t.ptraceEventMsg)
+ stateSourceObject.Load(41, &t.ptraceYAMAExceptionAdded)
+ stateSourceObject.Load(42, &t.ioUsage)
+ stateSourceObject.Load(43, &t.creds)
+ stateSourceObject.Load(44, &t.utsns)
+ stateSourceObject.Load(45, &t.ipcns)
+ stateSourceObject.Load(46, &t.abstractSockets)
+ stateSourceObject.Load(47, &t.mountNamespaceVFS2)
+ stateSourceObject.Load(48, &t.parentDeathSignal)
+ stateSourceObject.Load(50, &t.cleartid)
+ stateSourceObject.Load(51, &t.allowedCPUMask)
+ stateSourceObject.Load(52, &t.cpu)
+ stateSourceObject.Load(53, &t.niceness)
+ stateSourceObject.Load(54, &t.numaPolicy)
+ stateSourceObject.Load(55, &t.numaNodeMask)
+ stateSourceObject.Load(56, &t.netns)
+ stateSourceObject.Load(57, &t.rseqCPU)
+ stateSourceObject.Load(58, &t.oldRSeqCPUAddr)
+ stateSourceObject.Load(59, &t.rseqAddr)
+ stateSourceObject.Load(60, &t.rseqSignature)
+ stateSourceObject.Load(61, &t.robustList)
+ stateSourceObject.Load(62, &t.startTime)
+ stateSourceObject.Load(63, &t.kcov)
+ stateSourceObject.Load(64, &t.cgroups)
+ stateSourceObject.LoadValue(32, new(*Task), func(y interface{}) { t.loadPtraceTracer(y.(*Task)) })
+ stateSourceObject.LoadValue(49, new([]bpf.Program), func(y interface{}) { t.loadSyscallFilters(y.([]bpf.Program)) })
stateSourceObject.AfterLoad(t.afterLoad)
}
@@ -2296,6 +2296,7 @@ func (t *threadGroupNode) StateTypeName() string {
func (t *threadGroupNode) StateFields() []string {
return []string{
"pidns",
+ "eventQueue",
"leader",
"execing",
"tasks",
@@ -2311,12 +2312,13 @@ func (t *threadGroupNode) beforeSave() {}
func (t *threadGroupNode) StateSave(stateSinkObject state.Sink) {
t.beforeSave()
stateSinkObject.Save(0, &t.pidns)
- stateSinkObject.Save(1, &t.leader)
- stateSinkObject.Save(2, &t.execing)
- stateSinkObject.Save(3, &t.tasks)
- stateSinkObject.Save(4, &t.tasksCount)
- stateSinkObject.Save(5, &t.liveTasks)
- stateSinkObject.Save(6, &t.activeTasks)
+ stateSinkObject.Save(1, &t.eventQueue)
+ stateSinkObject.Save(2, &t.leader)
+ stateSinkObject.Save(3, &t.execing)
+ stateSinkObject.Save(4, &t.tasks)
+ stateSinkObject.Save(5, &t.tasksCount)
+ stateSinkObject.Save(6, &t.liveTasks)
+ stateSinkObject.Save(7, &t.activeTasks)
}
func (t *threadGroupNode) afterLoad() {}
@@ -2324,12 +2326,13 @@ func (t *threadGroupNode) afterLoad() {}
// +checklocksignore
func (t *threadGroupNode) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &t.pidns)
- stateSourceObject.Load(1, &t.leader)
- stateSourceObject.Load(2, &t.execing)
- stateSourceObject.Load(3, &t.tasks)
- stateSourceObject.Load(4, &t.tasksCount)
- stateSourceObject.Load(5, &t.liveTasks)
- stateSourceObject.Load(6, &t.activeTasks)
+ stateSourceObject.Load(1, &t.eventQueue)
+ stateSourceObject.Load(2, &t.leader)
+ stateSourceObject.Load(3, &t.execing)
+ stateSourceObject.Load(4, &t.tasks)
+ stateSourceObject.Load(5, &t.tasksCount)
+ stateSourceObject.Load(6, &t.liveTasks)
+ stateSourceObject.Load(7, &t.activeTasks)
}
func (t *taskNode) StateTypeName() string {
diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go
index 86beee6fe..8345473f3 100644
--- a/pkg/sentry/kernel/pipe/pipe.go
+++ b/pkg/sentry/kernel/pipe/pipe.go
@@ -55,7 +55,7 @@ const (
//
// +stateify savable
type Pipe struct {
- waiter.Queue `state:"nosave"`
+ waiter.Queue
// isNamed indicates whether this is a named pipe.
//
diff --git a/pkg/sentry/kernel/pipe/pipe_state_autogen.go b/pkg/sentry/kernel/pipe/pipe_state_autogen.go
index 57451e951..cbacc0dd1 100644
--- a/pkg/sentry/kernel/pipe/pipe_state_autogen.go
+++ b/pkg/sentry/kernel/pipe/pipe_state_autogen.go
@@ -40,6 +40,7 @@ func (p *Pipe) StateTypeName() string {
func (p *Pipe) StateFields() []string {
return []string{
+ "Queue",
"isNamed",
"readers",
"writers",
@@ -56,26 +57,28 @@ func (p *Pipe) beforeSave() {}
// +checklocksignore
func (p *Pipe) StateSave(stateSinkObject state.Sink) {
p.beforeSave()
- stateSinkObject.Save(0, &p.isNamed)
- stateSinkObject.Save(1, &p.readers)
- stateSinkObject.Save(2, &p.writers)
- stateSinkObject.Save(3, &p.buf)
- stateSinkObject.Save(4, &p.off)
- stateSinkObject.Save(5, &p.size)
- stateSinkObject.Save(6, &p.max)
- stateSinkObject.Save(7, &p.hadWriter)
+ stateSinkObject.Save(0, &p.Queue)
+ stateSinkObject.Save(1, &p.isNamed)
+ stateSinkObject.Save(2, &p.readers)
+ stateSinkObject.Save(3, &p.writers)
+ stateSinkObject.Save(4, &p.buf)
+ stateSinkObject.Save(5, &p.off)
+ stateSinkObject.Save(6, &p.size)
+ stateSinkObject.Save(7, &p.max)
+ stateSinkObject.Save(8, &p.hadWriter)
}
// +checklocksignore
func (p *Pipe) StateLoad(stateSourceObject state.Source) {
- stateSourceObject.Load(0, &p.isNamed)
- stateSourceObject.Load(1, &p.readers)
- stateSourceObject.Load(2, &p.writers)
- stateSourceObject.Load(3, &p.buf)
- stateSourceObject.Load(4, &p.off)
- stateSourceObject.Load(5, &p.size)
- stateSourceObject.Load(6, &p.max)
- stateSourceObject.Load(7, &p.hadWriter)
+ stateSourceObject.Load(0, &p.Queue)
+ stateSourceObject.Load(1, &p.isNamed)
+ stateSourceObject.Load(2, &p.readers)
+ stateSourceObject.Load(3, &p.writers)
+ stateSourceObject.Load(4, &p.buf)
+ stateSourceObject.Load(5, &p.off)
+ stateSourceObject.Load(6, &p.size)
+ stateSourceObject.Load(7, &p.max)
+ stateSourceObject.Load(8, &p.hadWriter)
stateSourceObject.AfterLoad(p.afterLoad)
}
diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go
index b0004482c..1ea3c1bf7 100644
--- a/pkg/sentry/kernel/task.go
+++ b/pkg/sentry/kernel/task.go
@@ -158,7 +158,7 @@ type Task struct {
// signalQueue is protected by the signalMutex. Note that the task does
// not implement all queue methods, specifically the readiness checks.
// The task only broadcast a notification on signal delivery.
- signalQueue waiter.Queue `state:"zerovalue"`
+ signalQueue waiter.Queue
// If groupStopPending is true, the task should participate in a group
// stop in the interrupt path.
diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go
index 77ad62445..e38b723ce 100644
--- a/pkg/sentry/kernel/threads.go
+++ b/pkg/sentry/kernel/threads.go
@@ -324,11 +324,7 @@ type threadGroupNode struct {
// eventQueue is notified whenever a event of interest to Task.Wait occurs
// in a child of this thread group, or a ptrace tracee of a task in this
// thread group. Events are defined in task_exit.go.
- //
- // Note that we cannot check and save this wait queue similarly to other
- // wait queues, as the queue will not be empty by the time of saving, due
- // to the wait sourced from Exec().
- eventQueue waiter.Queue `state:"nosave"`
+ eventQueue waiter.Queue
// leader is the thread group's leader, which is the oldest task in the
// thread group; usually the last task in the thread group to call