summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/kernel
diff options
context:
space:
mode:
authorZhaozhong Ni <nzz@google.com>2018-08-02 10:41:44 -0700
committerShentubot <shentubot@google.com>2018-08-02 10:42:48 -0700
commit57d0fcbdbf7e9d2d573ce8d4ca2f72b82f778d63 (patch)
tree7d09abd7209c47ea68471588531bc06ff4f8655c /pkg/sentry/kernel
parentcf44aff6e08b0e19935d5cd98455b4af98fd8794 (diff)
Automated rollback of changelist 207037226
PiperOrigin-RevId: 207125440 Change-Id: I6c572afb4d693ee72a0c458a988b0e96d191cd49
Diffstat (limited to 'pkg/sentry/kernel')
-rw-r--r--pkg/sentry/kernel/BUILD60
-rw-r--r--pkg/sentry/kernel/abstract_socket_namespace.go3
-rw-r--r--pkg/sentry/kernel/auth/BUILD17
-rw-r--r--pkg/sentry/kernel/auth/credentials.go2
-rw-r--r--pkg/sentry/kernel/auth/id_map.go2
-rw-r--r--pkg/sentry/kernel/auth/user_namespace.go2
-rw-r--r--pkg/sentry/kernel/epoll/BUILD15
-rw-r--r--pkg/sentry/kernel/epoll/epoll.go8
-rw-r--r--pkg/sentry/kernel/eventfd/BUILD18
-rw-r--r--pkg/sentry/kernel/eventfd/eventfd.go4
-rw-r--r--pkg/sentry/kernel/fd_map.go6
-rw-r--r--pkg/sentry/kernel/fs_context.go2
-rw-r--r--pkg/sentry/kernel/futex/BUILD18
-rw-r--r--pkg/sentry/kernel/futex/futex.go2
-rw-r--r--pkg/sentry/kernel/ipc_namespace.go2
-rw-r--r--pkg/sentry/kernel/kernel.go4
-rw-r--r--pkg/sentry/kernel/pending_signals.go5
-rw-r--r--pkg/sentry/kernel/pipe/BUILD20
-rw-r--r--pkg/sentry/kernel/pipe/buffers.go2
-rw-r--r--pkg/sentry/kernel/pipe/node.go2
-rw-r--r--pkg/sentry/kernel/pipe/pipe.go2
-rw-r--r--pkg/sentry/kernel/pipe/reader.go2
-rw-r--r--pkg/sentry/kernel/pipe/reader_writer.go2
-rw-r--r--pkg/sentry/kernel/pipe/writer.go2
-rw-r--r--pkg/sentry/kernel/ptrace.go4
-rw-r--r--pkg/sentry/kernel/rseq.go2
-rw-r--r--pkg/sentry/kernel/semaphore/BUILD15
-rw-r--r--pkg/sentry/kernel/semaphore/semaphore.go8
-rw-r--r--pkg/sentry/kernel/sessions.go4
-rw-r--r--pkg/sentry/kernel/shm/BUILD13
-rw-r--r--pkg/sentry/kernel/shm/shm.go4
-rw-r--r--pkg/sentry/kernel/signal_handlers.go2
-rw-r--r--pkg/sentry/kernel/syscalls.go2
-rw-r--r--pkg/sentry/kernel/syslog.go2
-rw-r--r--pkg/sentry/kernel/task.go2
-rw-r--r--pkg/sentry/kernel/task_clone.go4
-rw-r--r--pkg/sentry/kernel/task_context.go2
-rw-r--r--pkg/sentry/kernel/task_exec.go4
-rw-r--r--pkg/sentry/kernel/task_exit.go6
-rw-r--r--pkg/sentry/kernel/task_resources.go2
-rw-r--r--pkg/sentry/kernel/task_run.go2
-rw-r--r--pkg/sentry/kernel/task_sched.go2
-rw-r--r--pkg/sentry/kernel/task_signals.go5
-rw-r--r--pkg/sentry/kernel/task_syscall.go4
-rw-r--r--pkg/sentry/kernel/thread_group.go2
-rw-r--r--pkg/sentry/kernel/threads.go8
-rw-r--r--pkg/sentry/kernel/time/BUILD14
-rw-r--r--pkg/sentry/kernel/time/time.go6
-rw-r--r--pkg/sentry/kernel/timekeeper.go2
-rw-r--r--pkg/sentry/kernel/timer.go8
-rw-r--r--pkg/sentry/kernel/uts_namespace.go2
-rw-r--r--pkg/sentry/kernel/vdso.go2
52 files changed, 158 insertions, 177 deletions
diff --git a/pkg/sentry/kernel/BUILD b/pkg/sentry/kernel/BUILD
index 1c1633068..69a3fbc45 100644
--- a/pkg/sentry/kernel/BUILD
+++ b/pkg/sentry/kernel/BUILD
@@ -1,59 +1,7 @@
package(licenses = ["notice"]) # Apache 2.0
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test")
-
-go_stateify(
- name = "kernel_state",
- srcs = [
- "abstract_socket_namespace.go",
- "fd_map.go",
- "fs_context.go",
- "ipc_namespace.go",
- "kernel.go",
- "kernel_state.go",
- "pending_signals.go",
- "pending_signals_state.go",
- "process_group_list.go",
- "ptrace.go",
- "rseq.go",
- "session_list.go",
- "sessions.go",
- "signal.go",
- "signal_handlers.go",
- "syscalls.go",
- "syscalls_state.go",
- "syslog.go",
- "task.go",
- "task_clone.go",
- "task_context.go",
- "task_exec.go",
- "task_exit.go",
- "task_list.go",
- "task_resources.go",
- "task_run.go",
- "task_sched.go",
- "task_signals.go",
- "task_start.go",
- "task_syscall.go",
- "thread_group.go",
- "threads.go",
- "timekeeper.go",
- "timekeeper_state.go",
- "timer.go",
- "uts_namespace.go",
- "vdso.go",
- "version.go",
- ],
- out = "kernel_autogen_state.go",
- imports = [
- "gvisor.googlesource.com/gvisor/pkg/bpf",
- "gvisor.googlesource.com/gvisor/pkg/sentry/arch",
- "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/kdefs",
- "gvisor.googlesource.com/gvisor/pkg/tcpip",
- ],
- package = "kernel",
-)
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_template_instance(
name = "pending_signals_list",
@@ -119,7 +67,6 @@ go_library(
"fs_context.go",
"ipc_namespace.go",
"kernel.go",
- "kernel_autogen_state.go",
"kernel_state.go",
"pending_signals.go",
"pending_signals_list.go",
@@ -165,6 +112,11 @@ go_library(
"version.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel",
+ imports = [
+ "gvisor.googlesource.com/gvisor/pkg/bpf",
+ "gvisor.googlesource.com/gvisor/pkg/sentry/arch",
+ "gvisor.googlesource.com/gvisor/pkg/tcpip",
+ ],
visibility = ["//:sandbox"],
deps = [
"//pkg/abi",
diff --git a/pkg/sentry/kernel/abstract_socket_namespace.go b/pkg/sentry/kernel/abstract_socket_namespace.go
index 014c4a3bf..d6d1d341d 100644
--- a/pkg/sentry/kernel/abstract_socket_namespace.go
+++ b/pkg/sentry/kernel/abstract_socket_namespace.go
@@ -22,6 +22,7 @@ import (
"gvisor.googlesource.com/gvisor/pkg/tcpip/transport/unix"
)
+// +stateify savable
type abstractEndpoint struct {
ep unix.BoundEndpoint
wr *refs.WeakRef
@@ -39,6 +40,8 @@ func (e *abstractEndpoint) WeakRefGone() {
}
// AbstractSocketNamespace is used to implement the Linux abstract socket functionality.
+//
+// +stateify savable
type AbstractSocketNamespace struct {
mu sync.Mutex `state:"nosave"`
diff --git a/pkg/sentry/kernel/auth/BUILD b/pkg/sentry/kernel/auth/BUILD
index 5b7b30557..a81085372 100644
--- a/pkg/sentry/kernel/auth/BUILD
+++ b/pkg/sentry/kernel/auth/BUILD
@@ -1,20 +1,7 @@
package(licenses = ["notice"]) # Apache 2.0
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify")
-
-go_stateify(
- name = "auth_state",
- srcs = [
- "credentials.go",
- "id.go",
- "id_map_range.go",
- "id_map_set.go",
- "user_namespace.go",
- ],
- out = "auth_state.go",
- package = "auth",
-)
+load("//tools/go_stateify:defs.bzl", "go_library")
go_template_instance(
name = "id_map_range",
@@ -48,7 +35,6 @@ go_library(
name = "auth",
srcs = [
"auth.go",
- "auth_state.go",
"capability_set.go",
"context.go",
"credentials.go",
@@ -66,7 +52,6 @@ go_library(
"//pkg/bits",
"//pkg/log",
"//pkg/sentry/context",
- "//pkg/state",
"//pkg/syserror",
],
)
diff --git a/pkg/sentry/kernel/auth/credentials.go b/pkg/sentry/kernel/auth/credentials.go
index f6fb05285..f18f7dac9 100644
--- a/pkg/sentry/kernel/auth/credentials.go
+++ b/pkg/sentry/kernel/auth/credentials.go
@@ -21,6 +21,8 @@ import (
// Credentials contains information required to authorize privileged operations
// in a user namespace.
+//
+// +stateify savable
type Credentials struct {
// Real/effective/saved user/group IDs in the root user namespace. None of
// these should ever be NoID.
diff --git a/pkg/sentry/kernel/auth/id_map.go b/pkg/sentry/kernel/auth/id_map.go
index 6adb33530..bd0090e0f 100644
--- a/pkg/sentry/kernel/auth/id_map.go
+++ b/pkg/sentry/kernel/auth/id_map.go
@@ -77,6 +77,8 @@ func (ns *UserNamespace) allIDsMapped(m *idMapSet, start, end uint32) bool {
// An IDMapEntry represents a mapping from a range of contiguous IDs in a user
// namespace to an equally-sized range of contiguous IDs in the namespace's
// parent.
+//
+// +stateify savable
type IDMapEntry struct {
// FirstID is the first ID in the range in the namespace.
FirstID uint32
diff --git a/pkg/sentry/kernel/auth/user_namespace.go b/pkg/sentry/kernel/auth/user_namespace.go
index 0980aeadf..d359f3f31 100644
--- a/pkg/sentry/kernel/auth/user_namespace.go
+++ b/pkg/sentry/kernel/auth/user_namespace.go
@@ -23,6 +23,8 @@ import (
// A UserNamespace represents a user namespace. See user_namespaces(7) for
// details.
+//
+// +stateify savable
type UserNamespace struct {
// parent is this namespace's parent. If this is the root namespace, parent
// is nil. The parent pointer is immutable.
diff --git a/pkg/sentry/kernel/epoll/BUILD b/pkg/sentry/kernel/epoll/BUILD
index 7d491efbc..5e8b36ed6 100644
--- a/pkg/sentry/kernel/epoll/BUILD
+++ b/pkg/sentry/kernel/epoll/BUILD
@@ -1,22 +1,11 @@
package(licenses = ["notice"]) # Apache 2.0
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test")
-
-go_stateify(
- name = "epoll_autogen_state",
- srcs = [
- "epoll.go",
- "epoll_state.go",
- ],
- out = "epoll_autogen_state.go",
- package = "epoll",
-)
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_library(
name = "epoll",
srcs = [
"epoll.go",
- "epoll_autogen_state.go",
"epoll_state.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/epoll",
@@ -29,9 +18,7 @@ go_library(
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/kernel/kdefs",
- "//pkg/sentry/kernel/time",
"//pkg/sentry/usermem",
- "//pkg/state",
"//pkg/waiter",
],
)
diff --git a/pkg/sentry/kernel/epoll/epoll.go b/pkg/sentry/kernel/epoll/epoll.go
index b572fcd7e..d87e64a1c 100644
--- a/pkg/sentry/kernel/epoll/epoll.go
+++ b/pkg/sentry/kernel/epoll/epoll.go
@@ -58,6 +58,8 @@ const (
// potentially be reassigned. We also cannot use just the file pointer because
// it is possible to have multiple entries for the same file object as long as
// they are created with different FDs (i.e., the FDs point to the same file).
+//
+// +stateify savable
type FileIdentifier struct {
File *fs.File
Fd kdefs.FD
@@ -65,6 +67,8 @@ type FileIdentifier struct {
// pollEntry holds all the state associated with an event poll entry, that is,
// a file being observed by an event poll object.
+//
+// +stateify savable
type pollEntry struct {
ilist.Entry
file *refs.WeakRef `state:"manual"`
@@ -92,6 +96,8 @@ func (p *pollEntry) WeakRefGone() {
// EventPoll holds all the state associated with an event poll object, that is,
// collection of files to observe and their current state.
+//
+// +stateify savable
type EventPoll struct {
fsutil.PipeSeek `state:"zerovalue"`
fsutil.NotDirReaddir `state:"zerovalue"`
@@ -102,7 +108,7 @@ type EventPoll struct {
// Wait queue is used to notify interested parties when the event poll
// object itself becomes readable or writable.
- waiter.Queue
+ waiter.Queue `state:"zerovalue"`
// files is the map of all the files currently being observed, it is
// protected by mu.
diff --git a/pkg/sentry/kernel/eventfd/BUILD b/pkg/sentry/kernel/eventfd/BUILD
index 7ec179bd8..cc1120b4f 100644
--- a/pkg/sentry/kernel/eventfd/BUILD
+++ b/pkg/sentry/kernel/eventfd/BUILD
@@ -1,33 +1,19 @@
package(licenses = ["notice"]) # Apache 2.0
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test")
-
-go_stateify(
- name = "eventfd_state",
- srcs = [
- "eventfd.go",
- ],
- out = "eventfd_state.go",
- package = "eventfd",
-)
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_library(
name = "eventfd",
- srcs = [
- "eventfd.go",
- "eventfd_state.go",
- ],
+ srcs = ["eventfd.go"],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/eventfd",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/refs",
"//pkg/sentry/context",
"//pkg/sentry/fs",
"//pkg/sentry/fs/anon",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/usermem",
- "//pkg/state",
"//pkg/syserror",
"//pkg/waiter",
"//pkg/waiter/fdnotifier",
diff --git a/pkg/sentry/kernel/eventfd/eventfd.go b/pkg/sentry/kernel/eventfd/eventfd.go
index bd50bd9fe..a4ada0e78 100644
--- a/pkg/sentry/kernel/eventfd/eventfd.go
+++ b/pkg/sentry/kernel/eventfd/eventfd.go
@@ -35,6 +35,8 @@ import (
// EventOperations represents an event with the semantics of Linux's file-based event
// notification (eventfd). Eventfds are usually internal to the Sentry but in certain
// situations they may be converted into a host-backed eventfd.
+//
+// +stateify savable
type EventOperations struct {
fsutil.NoopRelease `state:"nosave"`
fsutil.PipeSeek `state:"nosave"`
@@ -49,7 +51,7 @@ type EventOperations struct {
// Queue is used to notify interested parties when the event object
// becomes readable or writable.
- wq waiter.Queue `state:"nosave"`
+ wq waiter.Queue `state:"zerovalue"`
// val is the current value of the event counter.
val uint64
diff --git a/pkg/sentry/kernel/fd_map.go b/pkg/sentry/kernel/fd_map.go
index 299506330..d5d4aaacb 100644
--- a/pkg/sentry/kernel/fd_map.go
+++ b/pkg/sentry/kernel/fd_map.go
@@ -46,6 +46,8 @@ func (f FDs) Less(i, j int) bool {
}
// FDFlags define flags for an individual descriptor.
+//
+// +stateify savable
type FDFlags struct {
// CloseOnExec indicates the descriptor should be closed on exec.
CloseOnExec bool
@@ -69,12 +71,16 @@ func (f FDFlags) ToLinuxFDFlags() (mask uint) {
// descriptor holds the details about a file descriptor, namely a pointer the
// file itself and the descriptor flags.
+//
+// +stateify savable
type descriptor struct {
file *fs.File
flags FDFlags
}
// FDMap is used to manage File references and flags.
+//
+// +stateify savable
type FDMap struct {
refs.AtomicRefCount
k *Kernel
diff --git a/pkg/sentry/kernel/fs_context.go b/pkg/sentry/kernel/fs_context.go
index dbc097696..f3f05e8f5 100644
--- a/pkg/sentry/kernel/fs_context.go
+++ b/pkg/sentry/kernel/fs_context.go
@@ -25,6 +25,8 @@ import (
// FSContext contains filesystem context.
//
// This includes umask and working directory.
+//
+// +stateify savable
type FSContext struct {
refs.AtomicRefCount
diff --git a/pkg/sentry/kernel/futex/BUILD b/pkg/sentry/kernel/futex/BUILD
index a97a43549..b44a26974 100644
--- a/pkg/sentry/kernel/futex/BUILD
+++ b/pkg/sentry/kernel/futex/BUILD
@@ -1,7 +1,7 @@
package(licenses = ["notice"]) # Apache 2.0
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test")
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_template_instance(
name = "waiter_list",
@@ -14,29 +14,15 @@ go_template_instance(
},
)
-go_stateify(
- name = "futex_state",
- srcs = [
- "futex.go",
- "waiter_list.go",
- ],
- out = "futex_state.go",
- package = "futex",
-)
-
go_library(
name = "futex",
srcs = [
"futex.go",
- "futex_state.go",
"waiter_list.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/futex",
visibility = ["//pkg/sentry:internal"],
- deps = [
- "//pkg/state",
- "//pkg/syserror",
- ],
+ deps = ["//pkg/syserror"],
)
go_test(
diff --git a/pkg/sentry/kernel/futex/futex.go b/pkg/sentry/kernel/futex/futex.go
index 15e3e5e2c..4a1f2a0ef 100644
--- a/pkg/sentry/kernel/futex/futex.go
+++ b/pkg/sentry/kernel/futex/futex.go
@@ -196,6 +196,8 @@ func bucketIndexForAddr(addr uintptr) uintptr {
}
// Manager holds futex state for a single virtual address space.
+//
+// +stateify savable
type Manager struct {
buckets [bucketCount]bucket `state:"zerovalue"`
}
diff --git a/pkg/sentry/kernel/ipc_namespace.go b/pkg/sentry/kernel/ipc_namespace.go
index a86bda77b..5eef49f59 100644
--- a/pkg/sentry/kernel/ipc_namespace.go
+++ b/pkg/sentry/kernel/ipc_namespace.go
@@ -21,6 +21,8 @@ import (
)
// IPCNamespace represents an IPC namespace.
+//
+// +stateify savable
type IPCNamespace struct {
// User namespace which owns this IPC namespace. Immutable.
userNS *auth.UserNamespace
diff --git a/pkg/sentry/kernel/kernel.go b/pkg/sentry/kernel/kernel.go
index 64439cd9d..419a1d473 100644
--- a/pkg/sentry/kernel/kernel.go
+++ b/pkg/sentry/kernel/kernel.go
@@ -62,6 +62,8 @@ import (
// Kernel represents an emulated Linux kernel. It must be initialized by calling
// Init() or LoadFrom().
+//
+// +stateify savable
type Kernel struct {
// extMu serializes external changes to the Kernel with calls to
// Kernel.SaveTo. (Kernel.SaveTo requires that the state of the Kernel
@@ -158,7 +160,7 @@ type Kernel struct {
// exitErr is the error causing the sandbox to exit, if any. It is
// protected by extMu.
- exitErr error
+ exitErr error `state:"nosave"`
// danglingEndpoints is used to save / restore tcpip.DanglingEndpoints.
danglingEndpoints struct{} `state:".([]tcpip.Endpoint)"`
diff --git a/pkg/sentry/kernel/pending_signals.go b/pkg/sentry/kernel/pending_signals.go
index 5dc0f266c..06be5a7e1 100644
--- a/pkg/sentry/kernel/pending_signals.go
+++ b/pkg/sentry/kernel/pending_signals.go
@@ -38,6 +38,8 @@ const (
// pendingSignals holds a collection of pending signals. The zero value of
// pendingSignals is a valid empty collection. pendingSignals is thread-unsafe;
// users must provide synchronization.
+//
+// +stateify savable
type pendingSignals struct {
// signals contains all pending signals.
//
@@ -52,11 +54,14 @@ type pendingSignals struct {
}
// pendingSignalQueue holds a pendingSignalList for a single signal number.
+//
+// +stateify savable
type pendingSignalQueue struct {
pendingSignalList
length int
}
+// +stateify savable
type pendingSignal struct {
// pendingSignalEntry links into a pendingSignalList.
pendingSignalEntry
diff --git a/pkg/sentry/kernel/pipe/BUILD b/pkg/sentry/kernel/pipe/BUILD
index 4600d19bd..19b23c6d2 100644
--- a/pkg/sentry/kernel/pipe/BUILD
+++ b/pkg/sentry/kernel/pipe/BUILD
@@ -1,20 +1,6 @@
package(licenses = ["notice"]) # Apache 2.0
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test")
-
-go_stateify(
- name = "pipe_state",
- srcs = [
- "buffers.go",
- "node.go",
- "pipe.go",
- "reader.go",
- "reader_writer.go",
- "writer.go",
- ],
- out = "pipe_state.go",
- package = "pipe",
-)
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_library(
name = "pipe",
@@ -23,7 +9,6 @@ go_library(
"device.go",
"node.go",
"pipe.go",
- "pipe_state.go",
"reader.go",
"reader_writer.go",
"writer.go",
@@ -34,15 +19,12 @@ go_library(
"//pkg/abi/linux",
"//pkg/amutex",
"//pkg/ilist",
- "//pkg/log",
- "//pkg/refs",
"//pkg/sentry/arch",
"//pkg/sentry/context",
"//pkg/sentry/device",
"//pkg/sentry/fs",
"//pkg/sentry/fs/fsutil",
"//pkg/sentry/usermem",
- "//pkg/state",
"//pkg/syserror",
"//pkg/waiter",
],
diff --git a/pkg/sentry/kernel/pipe/buffers.go b/pkg/sentry/kernel/pipe/buffers.go
index f300537c5..a82e45c3f 100644
--- a/pkg/sentry/kernel/pipe/buffers.go
+++ b/pkg/sentry/kernel/pipe/buffers.go
@@ -20,6 +20,8 @@ import (
// Buffer encapsulates a queueable byte buffer that can
// easily be truncated. It is designed only for use with pipes.
+//
+// +stateify savable
type Buffer struct {
ilist.Entry
data []byte
diff --git a/pkg/sentry/kernel/pipe/node.go b/pkg/sentry/kernel/pipe/node.go
index e418cf174..23d692da1 100644
--- a/pkg/sentry/kernel/pipe/node.go
+++ b/pkg/sentry/kernel/pipe/node.go
@@ -24,6 +24,8 @@ import (
)
// inodeOperations wraps fs.InodeOperations operations with common pipe opening semantics.
+//
+// +stateify savable
type inodeOperations struct {
fs.InodeOperations
diff --git a/pkg/sentry/kernel/pipe/pipe.go b/pkg/sentry/kernel/pipe/pipe.go
index 9a21df5b4..ced2559a7 100644
--- a/pkg/sentry/kernel/pipe/pipe.go
+++ b/pkg/sentry/kernel/pipe/pipe.go
@@ -41,6 +41,8 @@ const DefaultPipeSize = 65536
// Pipe is an encapsulation of a platform-independent pipe.
// It manages a buffered byte queue shared between a reader/writer
// pair.
+//
+// +stateify savable
type Pipe struct {
waiter.Queue `state:"nosave"`
diff --git a/pkg/sentry/kernel/pipe/reader.go b/pkg/sentry/kernel/pipe/reader.go
index 40d5e4943..1fa5e9a32 100644
--- a/pkg/sentry/kernel/pipe/reader.go
+++ b/pkg/sentry/kernel/pipe/reader.go
@@ -20,6 +20,8 @@ import (
// Reader satisfies the fs.FileOperations interface for read-only pipes.
// Reader should be used with !fs.FileFlags.Write to reject writes.
+//
+// +stateify savable
type Reader struct {
ReaderWriter
}
diff --git a/pkg/sentry/kernel/pipe/reader_writer.go b/pkg/sentry/kernel/pipe/reader_writer.go
index dc642a3a6..82607367b 100644
--- a/pkg/sentry/kernel/pipe/reader_writer.go
+++ b/pkg/sentry/kernel/pipe/reader_writer.go
@@ -31,6 +31,8 @@ import (
// read and write requests. This should only be used directly for named pipes.
// pipe(2) and pipe2(2) only support unidirectional pipes and should use
// either pipe.Reader or pipe.Writer.
+//
+// +stateify savable
type ReaderWriter struct {
fsutil.PipeSeek `state:"nosave"`
fsutil.NotDirReaddir `state:"nosave"`
diff --git a/pkg/sentry/kernel/pipe/writer.go b/pkg/sentry/kernel/pipe/writer.go
index fd13008ac..d93324b53 100644
--- a/pkg/sentry/kernel/pipe/writer.go
+++ b/pkg/sentry/kernel/pipe/writer.go
@@ -20,6 +20,8 @@ import (
// Writer satisfies the fs.FileOperations interface for write-only pipes.
// Writer should be used with !fs.FileFlags.Read to reject reads.
+//
+// +stateify savable
type Writer struct {
ReaderWriter
}
diff --git a/pkg/sentry/kernel/ptrace.go b/pkg/sentry/kernel/ptrace.go
index f1c2c4bf0..e9e69004d 100644
--- a/pkg/sentry/kernel/ptrace.go
+++ b/pkg/sentry/kernel/ptrace.go
@@ -25,6 +25,8 @@ import (
// ptraceOptions are the subset of options controlling a task's ptrace behavior
// that are set by ptrace(PTRACE_SETOPTIONS).
+//
+// +stateify savable
type ptraceOptions struct {
// ExitKill is true if the tracee should be sent SIGKILL when the tracer
// exits.
@@ -185,6 +187,8 @@ func (t *Task) hasTracer() bool {
}
// ptraceStop is a TaskStop placed on tasks in a ptrace-stop.
+//
+// +stateify savable
type ptraceStop struct {
// If frozen is true, the stopped task's tracer is currently operating on
// it, so Task.Kill should not remove the stop.
diff --git a/pkg/sentry/kernel/rseq.go b/pkg/sentry/kernel/rseq.go
index 635372993..1f3de58e3 100644
--- a/pkg/sentry/kernel/rseq.go
+++ b/pkg/sentry/kernel/rseq.go
@@ -23,6 +23,8 @@ import (
// Restartable sequences, as described in https://lwn.net/Articles/650333/.
// RSEQCriticalRegion describes a restartable sequence critical region.
+//
+// +stateify savable
type RSEQCriticalRegion struct {
// When a task in this thread group has its CPU preempted (as defined by
// platform.ErrContextCPUPreempted) or has a signal delivered to an
diff --git a/pkg/sentry/kernel/semaphore/BUILD b/pkg/sentry/kernel/semaphore/BUILD
index 969145fe1..e7fa44e2c 100644
--- a/pkg/sentry/kernel/semaphore/BUILD
+++ b/pkg/sentry/kernel/semaphore/BUILD
@@ -1,7 +1,7 @@
package(licenses = ["notice"]) # Apache 2.0
load("//tools/go_generics:defs.bzl", "go_template_instance")
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify", "go_test")
+load("//tools/go_stateify:defs.bzl", "go_library", "go_test")
go_template_instance(
name = "waiter_list",
@@ -14,21 +14,10 @@ go_template_instance(
},
)
-go_stateify(
- name = "semaphore_state",
- srcs = [
- "semaphore.go",
- "waiter_list.go",
- ],
- out = "semaphore_autogen_state.go",
- package = "semaphore",
-)
-
go_library(
name = "semaphore",
srcs = [
"semaphore.go",
- "semaphore_autogen_state.go",
"waiter_list.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/semaphore",
@@ -40,8 +29,6 @@ go_library(
"//pkg/sentry/fs",
"//pkg/sentry/kernel/auth",
"//pkg/sentry/kernel/time",
- "//pkg/state",
- "//pkg/state/statefile",
"//pkg/syserror",
],
)
diff --git a/pkg/sentry/kernel/semaphore/semaphore.go b/pkg/sentry/kernel/semaphore/semaphore.go
index a1ee83ce5..aa07946cf 100644
--- a/pkg/sentry/kernel/semaphore/semaphore.go
+++ b/pkg/sentry/kernel/semaphore/semaphore.go
@@ -42,6 +42,8 @@ const (
)
// Registry maintains a set of semaphores that can be found by key or ID.
+//
+// +stateify savable
type Registry struct {
// userNS owning the ipc name this registry belongs to. Immutable.
userNS *auth.UserNamespace
@@ -52,6 +54,8 @@ type Registry struct {
}
// Set represents a set of semaphores that can be operated atomically.
+//
+// +stateify savable
type Set struct {
// registry owning this sem set. Immutable.
registry *Registry
@@ -79,6 +83,8 @@ type Set struct {
}
// sem represents a single semanphore from a set.
+//
+// +stateify savable
type sem struct {
value int16
waiters waiterList `state:"zerovalue"`
@@ -86,6 +92,8 @@ type sem struct {
// waiter represents a caller that is waiting for the semaphore value to
// become positive or zero.
+//
+// +stateify savable
type waiter struct {
waiterEntry
diff --git a/pkg/sentry/kernel/sessions.go b/pkg/sentry/kernel/sessions.go
index fa4c7b8f6..cf4e18805 100644
--- a/pkg/sentry/kernel/sessions.go
+++ b/pkg/sentry/kernel/sessions.go
@@ -27,6 +27,8 @@ type SessionID ThreadID
type ProcessGroupID ThreadID
// Session contains a leader threadgroup and a list of ProcessGroups.
+//
+// +stateify savable
type Session struct {
refs refs.AtomicRefCount
@@ -76,6 +78,8 @@ func (s *Session) decRef() {
}
// ProcessGroup contains an originator threadgroup and a parent Session.
+//
+// +stateify savable
type ProcessGroup struct {
refs refs.AtomicRefCount // not exported.
diff --git a/pkg/sentry/kernel/shm/BUILD b/pkg/sentry/kernel/shm/BUILD
index 0f88eb0ac..40e641355 100644
--- a/pkg/sentry/kernel/shm/BUILD
+++ b/pkg/sentry/kernel/shm/BUILD
@@ -1,22 +1,12 @@
package(licenses = ["notice"]) # Apache 2.0
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify")
-
-go_stateify(
- name = "shm_state",
- srcs = [
- "shm.go",
- ],
- out = "shm_autogen_state.go",
- package = "shm",
-)
+load("//tools/go_stateify:defs.bzl", "go_library")
go_library(
name = "shm",
srcs = [
"device.go",
"shm.go",
- "shm_autogen_state.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/shm",
visibility = ["//pkg/sentry:internal"],
@@ -33,7 +23,6 @@ go_library(
"//pkg/sentry/platform",
"//pkg/sentry/usage",
"//pkg/sentry/usermem",
- "//pkg/state",
"//pkg/syserror",
],
)
diff --git a/pkg/sentry/kernel/shm/shm.go b/pkg/sentry/kernel/shm/shm.go
index 7217e8103..1ac444094 100644
--- a/pkg/sentry/kernel/shm/shm.go
+++ b/pkg/sentry/kernel/shm/shm.go
@@ -72,6 +72,8 @@ const (
// Registry tracks all shared memory segments in an IPC namespace. The registry
// provides the mechanisms for creating and finding segments, and reporting
// global shm parameters.
+//
+// +stateify savable
type Registry struct {
// userNS owns the IPC namespace this registry belong to. Immutable.
userNS *auth.UserNamespace
@@ -288,6 +290,8 @@ func (r *Registry) remove(s *Shm) {
// shmctl(SHM_RMID).
//
// Shm implements memmap.Mappable and memmap.MappingIdentity.
+//
+// +stateify savable
type Shm struct {
// AtomicRefCount tracks the number of references to this segment from
// maps. A segment always holds a reference to itself, until it's marked for
diff --git a/pkg/sentry/kernel/signal_handlers.go b/pkg/sentry/kernel/signal_handlers.go
index 21ba4ee70..3649f5e4d 100644
--- a/pkg/sentry/kernel/signal_handlers.go
+++ b/pkg/sentry/kernel/signal_handlers.go
@@ -22,6 +22,8 @@ import (
)
// SignalHandlers holds information about signal actions.
+//
+// +stateify savable
type SignalHandlers struct {
// mu protects actions, as well as the signal state of all tasks and thread
// groups using this SignalHandlers object. (See comment on
diff --git a/pkg/sentry/kernel/syscalls.go b/pkg/sentry/kernel/syscalls.go
index e20fa3eb6..4c7811b6c 100644
--- a/pkg/sentry/kernel/syscalls.go
+++ b/pkg/sentry/kernel/syscalls.go
@@ -176,6 +176,8 @@ type Stracer interface {
// SyscallTable is a lookup table of system calls. Critically, a SyscallTable
// is *immutable*. In order to make supporting suspend and resume sane, they
// must be uniquely registered and may not change during operation.
+//
+// +stateify savable
type SyscallTable struct {
// OS is the operating system that this syscall table implements.
OS abi.OS `state:"wait"`
diff --git a/pkg/sentry/kernel/syslog.go b/pkg/sentry/kernel/syslog.go
index 31541749e..125312b6a 100644
--- a/pkg/sentry/kernel/syslog.go
+++ b/pkg/sentry/kernel/syslog.go
@@ -23,6 +23,8 @@ import (
// syslog represents a sentry-global kernel log.
//
// Currently, it contains only fun messages for a dmesg easter egg.
+//
+// +stateify savable
type syslog struct {
// mu protects the below.
mu sync.Mutex `state:"nosave"`
diff --git a/pkg/sentry/kernel/task.go b/pkg/sentry/kernel/task.go
index e705260da..19029adb1 100644
--- a/pkg/sentry/kernel/task.go
+++ b/pkg/sentry/kernel/task.go
@@ -52,6 +52,8 @@ import (
// All fields that are "exclusive to the task goroutine" can only be accessed
// by the task goroutine while it is running. The task goroutine does not
// require synchronization to read or write these fields.
+//
+// +stateify savable
type Task struct {
taskNode
diff --git a/pkg/sentry/kernel/task_clone.go b/pkg/sentry/kernel/task_clone.go
index 3b77a4965..526165af0 100644
--- a/pkg/sentry/kernel/task_clone.go
+++ b/pkg/sentry/kernel/task_clone.go
@@ -352,6 +352,7 @@ func (t *Task) unstopVforkParent() {
}
}
+// +stateify savable
type runSyscallAfterPtraceEventClone struct {
vforkChild *Task
@@ -369,6 +370,7 @@ func (r *runSyscallAfterPtraceEventClone) execute(t *Task) taskRunState {
return (*runSyscallExit)(nil)
}
+// +stateify savable
type runSyscallAfterVforkStop struct {
// childTID has the same meaning as
// runSyscallAfterPtraceEventClone.vforkChildTID.
@@ -474,6 +476,8 @@ func (t *Task) Unshare(opts *SharingOptions) error {
// current MM. (Normally, CLONE_VFORK is used in conjunction with CLONE_VM, so
// that the child and parent share mappings until the child execve()s into a
// new process image or exits.)
+//
+// +stateify savable
type vforkStop struct{}
// StopIgnoresKill implements TaskStop.Killable.
diff --git a/pkg/sentry/kernel/task_context.go b/pkg/sentry/kernel/task_context.go
index 5c563ba08..9a59cbd33 100644
--- a/pkg/sentry/kernel/task_context.go
+++ b/pkg/sentry/kernel/task_context.go
@@ -35,6 +35,8 @@ var ErrNoSyscalls = errors.New("no syscall table found")
type Auxmap map[string]interface{}
// TaskContext is the subset of a task's data that is provided by the loader.
+//
+// +stateify savable
type TaskContext struct {
// Name is the thread name set by the prctl(PR_SET_NAME) system call.
Name string
diff --git a/pkg/sentry/kernel/task_exec.go b/pkg/sentry/kernel/task_exec.go
index 2285847a2..385299b24 100644
--- a/pkg/sentry/kernel/task_exec.go
+++ b/pkg/sentry/kernel/task_exec.go
@@ -73,6 +73,8 @@ import (
// execStop is a TaskStop that a task sets on itself when it wants to execve
// and is waiting for the other tasks in its thread group to exit first.
+//
+// +stateify savable
type execStop struct{}
// Killable implements TaskStop.Killable.
@@ -119,6 +121,8 @@ func (t *Task) Execve(newTC *TaskContext) (*SyscallControl, error) {
// The runSyscallAfterExecStop state continues execve(2) after all siblings of
// a thread in the execve syscall have exited.
+//
+// +stateify savable
type runSyscallAfterExecStop struct {
tc *TaskContext
}
diff --git a/pkg/sentry/kernel/task_exit.go b/pkg/sentry/kernel/task_exit.go
index d6604f37b..b16844e91 100644
--- a/pkg/sentry/kernel/task_exit.go
+++ b/pkg/sentry/kernel/task_exit.go
@@ -38,6 +38,8 @@ import (
// An ExitStatus is a value communicated from an exiting task or thread group
// to the party that reaps it.
+//
+// +stateify savable
type ExitStatus struct {
// Code is the numeric value passed to the call to exit or exit_group that
// caused the exit. If the exit was not caused by such a call, Code is 0.
@@ -222,6 +224,8 @@ func (t *Task) advanceExitStateLocked(oldExit, newExit TaskExitState) {
}
// runExit is the entry point into the task exit path.
+//
+// +stateify savable
type runExit struct{}
func (*runExit) execute(t *Task) taskRunState {
@@ -229,6 +233,7 @@ func (*runExit) execute(t *Task) taskRunState {
return (*runExitMain)(nil)
}
+// +stateify savable
type runExitMain struct{}
func (*runExitMain) execute(t *Task) taskRunState {
@@ -531,6 +536,7 @@ func (t *Task) reparentLocked(parent *Task) {
// tracer (if one exists) and reaps the leader immediately. In Linux, this is
// in fs/exec.c:de_thread(); in the sentry, this is in Task.promoteLocked().
+// +stateify savable
type runExitNotify struct{}
func (*runExitNotify) execute(t *Task) taskRunState {
diff --git a/pkg/sentry/kernel/task_resources.go b/pkg/sentry/kernel/task_resources.go
index 4ca25664a..0832bf989 100644
--- a/pkg/sentry/kernel/task_resources.go
+++ b/pkg/sentry/kernel/task_resources.go
@@ -21,6 +21,8 @@ import (
// TaskResources is the subset of a task's data provided by its creator that is
// not provided by the loader.
+//
+// +stateify savable
type TaskResources struct {
// SignalMask is the set of signals whose delivery is currently blocked.
//
diff --git a/pkg/sentry/kernel/task_run.go b/pkg/sentry/kernel/task_run.go
index a03fa6ac0..8dd0ef6ea 100644
--- a/pkg/sentry/kernel/task_run.go
+++ b/pkg/sentry/kernel/task_run.go
@@ -131,6 +131,8 @@ func (t *Task) doStop() {
// The runApp state checks for interrupts before executing untrusted
// application code.
+//
+// +stateify savable
type runApp struct{}
func (*runApp) execute(t *Task) taskRunState {
diff --git a/pkg/sentry/kernel/task_sched.go b/pkg/sentry/kernel/task_sched.go
index b50139077..49141ab74 100644
--- a/pkg/sentry/kernel/task_sched.go
+++ b/pkg/sentry/kernel/task_sched.go
@@ -65,6 +65,8 @@ const (
// TaskGoroutineSchedInfo contains task goroutine scheduling state which must
// be read and updated atomically.
+//
+// +stateify savable
type TaskGoroutineSchedInfo struct {
// Timestamp was the value of Kernel.cpuClock when this
// TaskGoroutineSchedInfo was last updated.
diff --git a/pkg/sentry/kernel/task_signals.go b/pkg/sentry/kernel/task_signals.go
index 91f6c0874..62ec530be 100644
--- a/pkg/sentry/kernel/task_signals.go
+++ b/pkg/sentry/kernel/task_signals.go
@@ -748,6 +748,8 @@ func (t *Task) CopyInSignalStack(addr usermem.Addr) (arch.SignalStack, error) {
// groupStop is a TaskStop placed on tasks that have received a stop signal
// (SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU). (The term "group-stop" originates from
// the ptrace man page.)
+//
+// +stateify savable
type groupStop struct{}
// Killable implements TaskStop.Killable.
@@ -881,6 +883,8 @@ func (t *Task) signalStop(target *Task, code int32, status int32) {
}
// The runInterrupt state handles conditions indicated by interrupts.
+//
+// +stateify savable
type runInterrupt struct{}
func (*runInterrupt) execute(t *Task) taskRunState {
@@ -1020,6 +1024,7 @@ func (*runInterrupt) execute(t *Task) taskRunState {
return (*runApp)(nil)
}
+// +stateify savable
type runInterruptAfterSignalDeliveryStop struct{}
func (*runInterruptAfterSignalDeliveryStop) execute(t *Task) taskRunState {
diff --git a/pkg/sentry/kernel/task_syscall.go b/pkg/sentry/kernel/task_syscall.go
index 92ca0acd9..f0373c375 100644
--- a/pkg/sentry/kernel/task_syscall.go
+++ b/pkg/sentry/kernel/task_syscall.go
@@ -241,6 +241,7 @@ func (t *Task) doSyscallEnter(sysno uintptr, args arch.SyscallArguments) taskRun
return t.doSyscallInvoke(sysno, args)
}
+// +stateify savable
type runSyscallAfterSyscallEnterStop struct{}
func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState {
@@ -260,6 +261,7 @@ func (*runSyscallAfterSyscallEnterStop) execute(t *Task) taskRunState {
return t.doSyscallInvoke(sysno, args)
}
+// +stateify savable
type runSyscallAfterSysemuStop struct{}
func (*runSyscallAfterSysemuStop) execute(t *Task) taskRunState {
@@ -294,6 +296,7 @@ func (t *Task) doSyscallInvoke(sysno uintptr, args arch.SyscallArguments) taskRu
return (*runSyscallExit)(nil).execute(t)
}
+// +stateify savable
type runSyscallReinvoke struct{}
func (*runSyscallReinvoke) execute(t *Task) taskRunState {
@@ -310,6 +313,7 @@ func (*runSyscallReinvoke) execute(t *Task) taskRunState {
return t.doSyscallInvoke(sysno, args)
}
+// +stateify savable
type runSyscallExit struct{}
func (*runSyscallExit) execute(t *Task) taskRunState {
diff --git a/pkg/sentry/kernel/thread_group.go b/pkg/sentry/kernel/thread_group.go
index 8fffd3446..441b8a822 100644
--- a/pkg/sentry/kernel/thread_group.go
+++ b/pkg/sentry/kernel/thread_group.go
@@ -28,6 +28,8 @@ import (
// groups" are usually called "processes" in userspace documentation.)
//
// ThreadGroup is a superset of Linux's struct signal_struct.
+//
+// +stateify savable
type ThreadGroup struct {
threadGroupNode
diff --git a/pkg/sentry/kernel/threads.go b/pkg/sentry/kernel/threads.go
index 440da9dad..844213c35 100644
--- a/pkg/sentry/kernel/threads.go
+++ b/pkg/sentry/kernel/threads.go
@@ -50,6 +50,8 @@ func (tid ThreadID) String() string {
const InitTID ThreadID = 1
// A TaskSet comprises all tasks in a system.
+//
+// +stateify savable
type TaskSet struct {
// mu protects all relationships betweens tasks and thread groups in the
// TaskSet. (mu is approximately equivalent to Linux's tasklist_lock.)
@@ -110,6 +112,8 @@ func (ts *TaskSet) forEachThreadGroupLocked(f func(tg *ThreadGroup)) {
//
// N.B. A task is said to be visible in a PID namespace if the PID namespace
// contains a thread ID that maps to that task.
+//
+// +stateify savable
type PIDNamespace struct {
// owner is the TaskSet that this PID namespace belongs to. The owner
// pointer is immutable.
@@ -263,6 +267,8 @@ func (ns *PIDNamespace) UserNamespace() *auth.UserNamespace {
// (threadGroupNode is an anonymous field in ThreadGroup; this is to expose
// threadGroupEntry's methods on ThreadGroup to make it implement
// threadGroupLinker.)
+//
+// +stateify savable
type threadGroupNode struct {
// pidns is the PID namespace containing the thread group and all of its
// member tasks. The pidns pointer is immutable.
@@ -382,6 +388,8 @@ func (tg *ThreadGroup) ID() ThreadID {
// A taskNode defines the relationship between a task and the rest of the
// system. The comments on threadGroupNode also apply to taskNode.
+//
+// +stateify savable
type taskNode struct {
// tg is the thread group that this task belongs to. The tg pointer is
// immutable.
diff --git a/pkg/sentry/kernel/time/BUILD b/pkg/sentry/kernel/time/BUILD
index b3ed42aa4..5d8db2273 100644
--- a/pkg/sentry/kernel/time/BUILD
+++ b/pkg/sentry/kernel/time/BUILD
@@ -1,30 +1,18 @@
package(licenses = ["notice"]) # Apache 2.0
-load("//tools/go_stateify:defs.bzl", "go_library", "go_stateify")
-
-go_stateify(
- name = "time_state",
- srcs = [
- "time.go",
- ],
- out = "time_state.go",
- package = "time",
-)
+load("//tools/go_stateify:defs.bzl", "go_library")
go_library(
name = "time",
srcs = [
"context.go",
"time.go",
- "time_state.go",
],
importpath = "gvisor.googlesource.com/gvisor/pkg/sentry/kernel/time",
visibility = ["//pkg/sentry:internal"],
deps = [
"//pkg/abi/linux",
- "//pkg/log",
"//pkg/sentry/context",
- "//pkg/state",
"//pkg/syserror",
"//pkg/waiter",
],
diff --git a/pkg/sentry/kernel/time/time.go b/pkg/sentry/kernel/time/time.go
index c223c2f19..6eadd2878 100644
--- a/pkg/sentry/kernel/time/time.go
+++ b/pkg/sentry/kernel/time/time.go
@@ -42,6 +42,8 @@ const (
//
// Time may represent time with respect to any clock and may not have any
// meaning in the real world.
+//
+// +stateify savable
type Time struct {
ns int64
}
@@ -286,6 +288,8 @@ type TimerListener interface {
}
// Setting contains user-controlled mutable Timer properties.
+//
+// +stateify savable
type Setting struct {
// Enabled is true if the timer is running.
Enabled bool
@@ -371,6 +375,8 @@ func (s Setting) advancedTo(now Time) (Setting, uint64) {
//
// Timers should be created using NewTimer and must be cleaned up by calling
// Timer.Destroy when no longer used.
+//
+// +stateify savable
type Timer struct {
// clock is the time source. clock is immutable.
clock Clock
diff --git a/pkg/sentry/kernel/timekeeper.go b/pkg/sentry/kernel/timekeeper.go
index 4de8ac13b..df5dbe128 100644
--- a/pkg/sentry/kernel/timekeeper.go
+++ b/pkg/sentry/kernel/timekeeper.go
@@ -25,6 +25,8 @@ import (
)
// Timekeeper manages all of the kernel clocks.
+//
+// +stateify savable
type Timekeeper struct {
// clocks are the clock sources.
//
diff --git a/pkg/sentry/kernel/timer.go b/pkg/sentry/kernel/timer.go
index 03a3310be..534d03d0f 100644
--- a/pkg/sentry/kernel/timer.go
+++ b/pkg/sentry/kernel/timer.go
@@ -26,6 +26,8 @@ import (
// timekeeperClock is a ktime.Clock that reads time from a
// kernel.Timekeeper-managed clock.
+//
+// +stateify savable
type timekeeperClock struct {
tk *Timekeeper
c sentrytime.ClockID
@@ -49,6 +51,8 @@ func (tc *timekeeperClock) Now() ktime.Time {
// tgClock is a ktime.Clock that measures the time a thread group has spent
// executing.
+//
+// +stateify savable
type tgClock struct {
tg *ThreadGroup
@@ -155,6 +159,8 @@ func (tc *taskClock) Now() ktime.Time {
}
// signalNotifier is a ktime.Listener that sends signals to a ThreadGroup.
+//
+// +stateify savable
type signalNotifier struct {
tg *ThreadGroup
signal linux.Signal
@@ -179,6 +185,8 @@ func (s *signalNotifier) Notify(exp uint64) {
func (s *signalNotifier) Destroy() {}
// TimerManager is a collection of supported process cpu timers.
+//
+// +stateify savable
type TimerManager struct {
// Clocks used to drive thread group execution time timers.
virtClock *tgClock
diff --git a/pkg/sentry/kernel/uts_namespace.go b/pkg/sentry/kernel/uts_namespace.go
index 58e9b4d1b..7e0fe0d21 100644
--- a/pkg/sentry/kernel/uts_namespace.go
+++ b/pkg/sentry/kernel/uts_namespace.go
@@ -22,6 +22,8 @@ import (
// UTSNamespace represents a UTS namespace, a holder of two system identifiers:
// the hostname and domain name.
+//
+// +stateify savable
type UTSNamespace struct {
// mu protects all fields below.
mu sync.Mutex `state:"nosave"`
diff --git a/pkg/sentry/kernel/vdso.go b/pkg/sentry/kernel/vdso.go
index 0bacbea49..971e8bc59 100644
--- a/pkg/sentry/kernel/vdso.go
+++ b/pkg/sentry/kernel/vdso.go
@@ -52,6 +52,8 @@ type vdsoParams struct {
// Everything in the struct is 8 bytes for easy alignment.
//
// It must be kept in sync with params in vdso/vdso_time.cc.
+//
+// +stateify savable
type VDSOParamPage struct {
// The parameter page is fr, allocated from platform.Memory().
platform platform.Platform