summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-09-24 17:19:53 +0000
committergVisor bot <gvisor-bot@google.com>2020-09-24 17:19:53 +0000
commit61cc049caaa2317eda73e66f65f82b5099dd2bc2 (patch)
tree352bfc9c114c181e052a9656be9f3b2acd5f7b33 /pkg/sentry/fsimpl
parent3102024707dc370e025f1b46fa2be12eade2f9cb (diff)
parent0a7075f38a4870ded687e117a299ac4996c0673e (diff)
Merge release-20200914.0-152-g0a7075f38 (automated)
Diffstat (limited to 'pkg/sentry/fsimpl')
-rw-r--r--pkg/sentry/fsimpl/devpts/devpts.go8
-rw-r--r--pkg/sentry/fsimpl/devpts/devpts_state_autogen.go289
-rw-r--r--pkg/sentry/fsimpl/devpts/master.go3
-rw-r--r--pkg/sentry/fsimpl/devpts/replica.go3
-rw-r--r--pkg/sentry/fsimpl/devtmpfs/devtmpfs.go4
-rw-r--r--pkg/sentry/fsimpl/devtmpfs/devtmpfs_state_autogen.go37
-rw-r--r--pkg/sentry/fsimpl/eventfd/eventfd.go2
-rw-r--r--pkg/sentry/fsimpl/eventfd/eventfd_state_autogen.go52
-rw-r--r--pkg/sentry/fsimpl/fuse/connection.go25
-rw-r--r--pkg/sentry/fsimpl/fuse/dev.go16
-rw-r--r--pkg/sentry/fsimpl/fuse/fuse_state_autogen.go333
-rw-r--r--pkg/sentry/fsimpl/fuse/fusefs.go7
-rw-r--r--pkg/sentry/fsimpl/gofer/directory.go3
-rw-r--r--pkg/sentry/fsimpl/gofer/gofer.go39
-rw-r--r--pkg/sentry/fsimpl/gofer/gofer_state_autogen.go488
-rw-r--r--pkg/sentry/fsimpl/gofer/handle.go2
-rw-r--r--pkg/sentry/fsimpl/gofer/regular_file.go7
-rw-r--r--pkg/sentry/fsimpl/gofer/socket.go4
-rw-r--r--pkg/sentry/fsimpl/gofer/special_file.go6
-rw-r--r--pkg/sentry/fsimpl/host/host.go12
-rw-r--r--pkg/sentry/fsimpl/host/host_state_autogen.go209
-rw-r--r--pkg/sentry/fsimpl/host/mmap.go6
-rw-r--r--pkg/sentry/fsimpl/host/tty.go2
-rw-r--r--pkg/sentry/fsimpl/kernfs/fd_impl_util.go8
-rw-r--r--pkg/sentry/fsimpl/kernfs/inode_impl_util.go26
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs.go10
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go493
-rw-r--r--pkg/sentry/fsimpl/kernfs/symlink.go2
-rw-r--r--pkg/sentry/fsimpl/overlay/directory.go3
-rw-r--r--pkg/sentry/fsimpl/overlay/non_directory.go3
-rw-r--r--pkg/sentry/fsimpl/overlay/overlay.go16
-rw-r--r--pkg/sentry/fsimpl/overlay/overlay_state_autogen.go282
-rw-r--r--pkg/sentry/fsimpl/pipefs/pipefs.go4
-rw-r--r--pkg/sentry/fsimpl/pipefs/pipefs_state_autogen.go102
-rw-r--r--pkg/sentry/fsimpl/proc/filesystem.go7
-rw-r--r--pkg/sentry/fsimpl/proc/proc_state_autogen.go494
-rw-r--r--pkg/sentry/fsimpl/proc/subtasks.go1
-rw-r--r--pkg/sentry/fsimpl/proc/task.go2
-rw-r--r--pkg/sentry/fsimpl/proc/task_fds.go1
-rw-r--r--pkg/sentry/fsimpl/proc/task_files.go5
-rw-r--r--pkg/sentry/fsimpl/proc/task_net.go1
-rw-r--r--pkg/sentry/fsimpl/proc/tasks.go2
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_files.go6
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_sys.go1
-rw-r--r--pkg/sentry/fsimpl/signalfd/signalfd.go4
-rw-r--r--pkg/sentry/fsimpl/signalfd/signalfd_state_autogen.go46
-rw-r--r--pkg/sentry/fsimpl/sockfs/sockfs.go5
-rw-r--r--pkg/sentry/fsimpl/sockfs/sockfs_state_autogen.go87
-rw-r--r--pkg/sentry/fsimpl/sys/kcov.go3
-rw-r--r--pkg/sentry/fsimpl/sys/sys.go9
-rw-r--r--pkg/sentry/fsimpl/sys/sys_state_autogen.go214
-rw-r--r--pkg/sentry/fsimpl/timerfd/timerfd.go2
-rw-r--r--pkg/sentry/fsimpl/timerfd/timerfd_state_autogen.go49
-rw-r--r--pkg/sentry/fsimpl/tmpfs/device_file.go1
-rw-r--r--pkg/sentry/fsimpl/tmpfs/directory.go4
-rw-r--r--pkg/sentry/fsimpl/tmpfs/named_pipe.go1
-rw-r--r--pkg/sentry/fsimpl/tmpfs/regular_file.go7
-rw-r--r--pkg/sentry/fsimpl/tmpfs/socket_file.go2
-rw-r--r--pkg/sentry/fsimpl/tmpfs/symlink.go1
-rw-r--r--pkg/sentry/fsimpl/tmpfs/tmpfs.go26
-rw-r--r--pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go470
61 files changed, 3907 insertions, 50 deletions
diff --git a/pkg/sentry/fsimpl/devpts/devpts.go b/pkg/sentry/fsimpl/devpts/devpts.go
index 77d1f493d..903135fae 100644
--- a/pkg/sentry/fsimpl/devpts/devpts.go
+++ b/pkg/sentry/fsimpl/devpts/devpts.go
@@ -35,6 +35,8 @@ import (
const Name = "devpts"
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
// Name implements vfs.FilesystemType.Name.
@@ -58,6 +60,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
return fs.Filesystem.VFSFilesystem(), root.VFSDentry(), nil
}
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
@@ -110,6 +113,8 @@ func (fs *filesystem) Release(ctx context.Context) {
}
// rootInode is the root directory inode for the devpts mounts.
+//
+// +stateify savable
type rootInode struct {
implStatFS
kernfs.AlwaysValid
@@ -131,7 +136,7 @@ type rootInode struct {
root *rootInode
// mu protects the fields below.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
// replicas maps pty ids to replica inodes.
replicas map[uint32]*replicaInode
@@ -242,6 +247,7 @@ func (i *rootInode) DecRef(context.Context) {
i.rootInodeRefs.DecRef(i.Destroy)
}
+// +stateify savable
type implStatFS struct{}
// StatFS implements kernfs.Inode.StatFS.
diff --git a/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go b/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go
index 5e9f200c8..61e4f6fdf 100644
--- a/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go
+++ b/pkg/sentry/fsimpl/devpts/devpts_state_autogen.go
@@ -6,6 +6,129 @@ import (
"gvisor.dev/gvisor/pkg/state"
)
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *rootInode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.rootInode"
+}
+
+func (x *rootInode) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "AlwaysValid",
+ "InodeAttrs",
+ "InodeDirectoryNoNewChildren",
+ "InodeNotSymlink",
+ "OrderedChildren",
+ "rootInodeRefs",
+ "locks",
+ "dentry",
+ "master",
+ "root",
+ "replicas",
+ "nextIdx",
+ }
+}
+
+func (x *rootInode) beforeSave() {}
+
+func (x *rootInode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.AlwaysValid)
+ m.Save(2, &x.InodeAttrs)
+ m.Save(3, &x.InodeDirectoryNoNewChildren)
+ m.Save(4, &x.InodeNotSymlink)
+ m.Save(5, &x.OrderedChildren)
+ m.Save(6, &x.rootInodeRefs)
+ m.Save(7, &x.locks)
+ m.Save(8, &x.dentry)
+ m.Save(9, &x.master)
+ m.Save(10, &x.root)
+ m.Save(11, &x.replicas)
+ m.Save(12, &x.nextIdx)
+}
+
+func (x *rootInode) afterLoad() {}
+
+func (x *rootInode) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.AlwaysValid)
+ m.Load(2, &x.InodeAttrs)
+ m.Load(3, &x.InodeDirectoryNoNewChildren)
+ m.Load(4, &x.InodeNotSymlink)
+ m.Load(5, &x.OrderedChildren)
+ m.Load(6, &x.rootInodeRefs)
+ m.Load(7, &x.locks)
+ m.Load(8, &x.dentry)
+ m.Load(9, &x.master)
+ m.Load(10, &x.root)
+ m.Load(11, &x.replicas)
+ m.Load(12, &x.nextIdx)
+}
+
+func (x *implStatFS) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.implStatFS"
+}
+
+func (x *implStatFS) StateFields() []string {
+ return []string{}
+}
+
+func (x *implStatFS) beforeSave() {}
+
+func (x *implStatFS) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *implStatFS) afterLoad() {}
+
+func (x *implStatFS) StateLoad(m state.Source) {
+}
+
func (x *lineDiscipline) StateTypeName() string {
return "pkg/sentry/fsimpl/devpts.lineDiscipline"
}
@@ -85,6 +208,85 @@ func (x *inputQueueTransformer) afterLoad() {}
func (x *inputQueueTransformer) StateLoad(m state.Source) {
}
+func (x *masterInode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.masterInode"
+}
+
+func (x *masterInode) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ "locks",
+ "dentry",
+ "root",
+ }
+}
+
+func (x *masterInode) beforeSave() {}
+
+func (x *masterInode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.InodeNotDirectory)
+ m.Save(4, &x.InodeNotSymlink)
+ m.Save(5, &x.locks)
+ m.Save(6, &x.dentry)
+ m.Save(7, &x.root)
+}
+
+func (x *masterInode) afterLoad() {}
+
+func (x *masterInode) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.InodeNotDirectory)
+ m.Load(4, &x.InodeNotSymlink)
+ m.Load(5, &x.locks)
+ m.Load(6, &x.dentry)
+ m.Load(7, &x.root)
+}
+
+func (x *masterFileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.masterFileDescription"
+}
+
+func (x *masterFileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ "inode",
+ "t",
+ }
+}
+
+func (x *masterFileDescription) beforeSave() {}
+
+func (x *masterFileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+ m.Save(3, &x.inode)
+ m.Save(4, &x.t)
+}
+
+func (x *masterFileDescription) afterLoad() {}
+
+func (x *masterFileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+ m.Load(3, &x.inode)
+ m.Load(4, &x.t)
+}
+
func (x *queue) StateTypeName() string {
return "pkg/sentry/fsimpl/devpts.queue"
}
@@ -120,6 +322,85 @@ func (x *queue) StateLoad(m state.Source) {
m.Load(4, &x.transformer)
}
+func (x *replicaInode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.replicaInode"
+}
+
+func (x *replicaInode) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ "locks",
+ "dentry",
+ "root",
+ "t",
+ }
+}
+
+func (x *replicaInode) beforeSave() {}
+
+func (x *replicaInode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.InodeNotDirectory)
+ m.Save(4, &x.InodeNotSymlink)
+ m.Save(5, &x.locks)
+ m.Save(6, &x.dentry)
+ m.Save(7, &x.root)
+ m.Save(8, &x.t)
+}
+
+func (x *replicaInode) afterLoad() {}
+
+func (x *replicaInode) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.InodeNotDirectory)
+ m.Load(4, &x.InodeNotSymlink)
+ m.Load(5, &x.locks)
+ m.Load(6, &x.dentry)
+ m.Load(7, &x.root)
+ m.Load(8, &x.t)
+}
+
+func (x *replicaFileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devpts.replicaFileDescription"
+}
+
+func (x *replicaFileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ "inode",
+ }
+}
+
+func (x *replicaFileDescription) beforeSave() {}
+
+func (x *replicaFileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+ m.Save(3, &x.inode)
+}
+
+func (x *replicaFileDescription) afterLoad() {}
+
+func (x *replicaFileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+ m.Load(3, &x.inode)
+}
+
func (x *rootInodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/devpts.rootInodeRefs"
}
@@ -176,10 +457,18 @@ func (x *Terminal) StateLoad(m state.Source) {
}
func init() {
+ state.Register((*FilesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*rootInode)(nil))
+ state.Register((*implStatFS)(nil))
state.Register((*lineDiscipline)(nil))
state.Register((*outputQueueTransformer)(nil))
state.Register((*inputQueueTransformer)(nil))
+ state.Register((*masterInode)(nil))
+ state.Register((*masterFileDescription)(nil))
state.Register((*queue)(nil))
+ state.Register((*replicaInode)(nil))
+ state.Register((*replicaFileDescription)(nil))
state.Register((*rootInodeRefs)(nil))
state.Register((*Terminal)(nil))
}
diff --git a/pkg/sentry/fsimpl/devpts/master.go b/pkg/sentry/fsimpl/devpts/master.go
index 98d4ffb22..bfcaf60bd 100644
--- a/pkg/sentry/fsimpl/devpts/master.go
+++ b/pkg/sentry/fsimpl/devpts/master.go
@@ -31,6 +31,8 @@ import (
)
// masterInode is the inode for the master end of the Terminal.
+//
+// +stateify savable
type masterInode struct {
implStatFS
kernfs.InodeAttrs
@@ -89,6 +91,7 @@ func (mi *masterInode) SetStat(ctx context.Context, vfsfs *vfs.Filesystem, creds
return mi.InodeAttrs.SetStat(ctx, vfsfs, creds, opts)
}
+// +stateify savable
type masterFileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/devpts/replica.go b/pkg/sentry/fsimpl/devpts/replica.go
index 816bac80c..9638eb6c5 100644
--- a/pkg/sentry/fsimpl/devpts/replica.go
+++ b/pkg/sentry/fsimpl/devpts/replica.go
@@ -30,6 +30,8 @@ import (
)
// replicaInode is the inode for the replica end of the Terminal.
+//
+// +stateify savable
type replicaInode struct {
implStatFS
kernfs.InodeAttrs
@@ -95,6 +97,7 @@ func (si *replicaInode) SetStat(ctx context.Context, vfsfs *vfs.Filesystem, cred
return si.InodeAttrs.SetStat(ctx, vfsfs, creds, opts)
}
+// +stateify savable
type replicaFileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go b/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go
index a23094e54..6d1753080 100644
--- a/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go
+++ b/pkg/sentry/fsimpl/devtmpfs/devtmpfs.go
@@ -33,8 +33,10 @@ import (
const Name = "devtmpfs"
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct {
- initOnce sync.Once
+ initOnce sync.Once `state:"nosave"` // FIXME(gvisor.dev/issue/1664): not yet supported.
initErr error
// fs is the tmpfs filesystem that backs all mounts of this FilesystemType.
diff --git a/pkg/sentry/fsimpl/devtmpfs/devtmpfs_state_autogen.go b/pkg/sentry/fsimpl/devtmpfs/devtmpfs_state_autogen.go
index ac054eb77..1253bed4e 100644
--- a/pkg/sentry/fsimpl/devtmpfs/devtmpfs_state_autogen.go
+++ b/pkg/sentry/fsimpl/devtmpfs/devtmpfs_state_autogen.go
@@ -1,3 +1,40 @@
// automatically generated by stateify.
package devtmpfs
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/devtmpfs.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{
+ "initErr",
+ "fs",
+ "root",
+ }
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.initErr)
+ m.Save(1, &x.fs)
+ m.Save(2, &x.root)
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+ m.Load(0, &x.initErr)
+ m.Load(1, &x.fs)
+ m.Load(2, &x.root)
+}
+
+func init() {
+ state.Register((*FilesystemType)(nil))
+}
diff --git a/pkg/sentry/fsimpl/eventfd/eventfd.go b/pkg/sentry/fsimpl/eventfd/eventfd.go
index bb0bf3a07..1c27ad700 100644
--- a/pkg/sentry/fsimpl/eventfd/eventfd.go
+++ b/pkg/sentry/fsimpl/eventfd/eventfd.go
@@ -33,6 +33,8 @@ import (
// EventFileDescription implements vfs.FileDescriptionImpl for 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 EventFileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/eventfd/eventfd_state_autogen.go b/pkg/sentry/fsimpl/eventfd/eventfd_state_autogen.go
index e83f6aed8..0507be064 100644
--- a/pkg/sentry/fsimpl/eventfd/eventfd_state_autogen.go
+++ b/pkg/sentry/fsimpl/eventfd/eventfd_state_autogen.go
@@ -1,3 +1,55 @@
// automatically generated by stateify.
package eventfd
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *EventFileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/eventfd.EventFileDescription"
+}
+
+func (x *EventFileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "DentryMetadataFileDescriptionImpl",
+ "NoLockFD",
+ "val",
+ "semMode",
+ "hostfd",
+ }
+}
+
+func (x *EventFileDescription) beforeSave() {}
+
+func (x *EventFileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ if !state.IsZeroValue(&x.queue) {
+ state.Failf("queue is %#v, expected zero", &x.queue)
+ }
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Save(3, &x.NoLockFD)
+ m.Save(4, &x.val)
+ m.Save(5, &x.semMode)
+ m.Save(6, &x.hostfd)
+}
+
+func (x *EventFileDescription) afterLoad() {}
+
+func (x *EventFileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Load(3, &x.NoLockFD)
+ m.Load(4, &x.val)
+ m.Load(5, &x.semMode)
+ m.Load(6, &x.hostfd)
+}
+
+func init() {
+ state.Register((*EventFileDescription)(nil))
+}
diff --git a/pkg/sentry/fsimpl/fuse/connection.go b/pkg/sentry/fsimpl/fuse/connection.go
index dbc5e1954..8ccda1264 100644
--- a/pkg/sentry/fsimpl/fuse/connection.go
+++ b/pkg/sentry/fsimpl/fuse/connection.go
@@ -39,15 +39,18 @@ const (
)
// connection is the struct by which the sentry communicates with the FUSE server daemon.
+//
// Lock order:
// - conn.fd.mu
// - conn.mu
// - conn.asyncMu
+//
+// +stateify savable
type connection struct {
fd *DeviceFD
// mu protects access to struct memebers.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
// attributeVersion is the version of connection's attributes.
attributeVersion uint64
@@ -75,7 +78,7 @@ type connection struct {
initialized int32
// initializedChan is used to block requests before initialization.
- initializedChan chan struct{}
+ initializedChan chan struct{} `state:".(bool)"`
// connected (connection established) when a new FUSE file system is created.
// Set to false when:
@@ -113,7 +116,7 @@ type connection struct {
// i.e. `!request.noReply`
// asyncMu protects the async request fields.
- asyncMu sync.Mutex
+ asyncMu sync.Mutex `state:"nosave"`
// asyncNum is the number of async requests.
// Protected by asyncMu.
@@ -174,6 +177,22 @@ type connection struct {
noOpen bool
}
+func (conn *connection) saveInitializedChan() bool {
+ select {
+ case <-conn.initializedChan:
+ return true // Closed.
+ default:
+ return false // Not closed.
+ }
+}
+
+func (conn *connection) loadInitializedChan(closed bool) {
+ conn.initializedChan = make(chan struct{}, 1)
+ if closed {
+ close(conn.initializedChan)
+ }
+}
+
// newFUSEConnection creates a FUSE connection to fd.
func newFUSEConnection(_ context.Context, fd *vfs.FileDescription, opts *filesystemOptions) (*connection, error) {
// Mark the device as ready so it can be used. /dev/fuse can only be used if the FD was used to
diff --git a/pkg/sentry/fsimpl/fuse/dev.go b/pkg/sentry/fsimpl/fuse/dev.go
index f690ef5ad..1b86a4b4c 100644
--- a/pkg/sentry/fsimpl/fuse/dev.go
+++ b/pkg/sentry/fsimpl/fuse/dev.go
@@ -31,6 +31,8 @@ import (
const fuseDevMinor = 229
// fuseDevice implements vfs.Device for /dev/fuse.
+//
+// +stateify savable
type fuseDevice struct{}
// Open implements vfs.Device.Open.
@@ -49,6 +51,8 @@ func (fuseDevice) Open(ctx context.Context, mnt *vfs.Mount, vfsd *vfs.Dentry, op
}
// DeviceFD implements vfs.FileDescriptionImpl for /dev/fuse.
+//
+// +stateify savable
type DeviceFD struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
@@ -79,7 +83,7 @@ type DeviceFD struct {
writeCursorFR *futureResponse
// mu protects all the queues, maps, buffers and cursors and nextOpID.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
// waitQueue is used to notify interested parties when the device becomes
// readable or writable.
@@ -88,12 +92,20 @@ type DeviceFD struct {
// fullQueueCh is a channel used to synchronize the readers with the writers.
// Writers (inbound requests to the filesystem) block if there are too many
// unprocessed in-flight requests.
- fullQueueCh chan struct{}
+ fullQueueCh chan struct{} `state:".(int)"`
// fs is the FUSE filesystem that this FD is being used for.
fs *filesystem
}
+func (fd *DeviceFD) saveFullQueueCh() int {
+ return cap(fd.fullQueueCh)
+}
+
+func (fd *DeviceFD) loadFullQueueCh(capacity int) {
+ fd.fullQueueCh = make(chan struct{}, capacity)
+}
+
// Release implements vfs.FileDescriptionImpl.Release.
func (fd *DeviceFD) Release(ctx context.Context) {
if fd.fs != nil {
diff --git a/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go b/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go
index 6c82dce30..b127b2015 100644
--- a/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go
+++ b/pkg/sentry/fsimpl/fuse/fuse_state_autogen.go
@@ -6,6 +6,332 @@ import (
"gvisor.dev/gvisor/pkg/state"
)
+func (x *connection) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.connection"
+}
+
+func (x *connection) StateFields() []string {
+ return []string{
+ "fd",
+ "attributeVersion",
+ "initialized",
+ "initializedChan",
+ "connected",
+ "connInitError",
+ "connInitSuccess",
+ "aborted",
+ "numWaiting",
+ "asyncNum",
+ "asyncCongestionThreshold",
+ "asyncNumMax",
+ "maxRead",
+ "maxWrite",
+ "maxPages",
+ "minor",
+ "atomicOTrunc",
+ "asyncRead",
+ "writebackCache",
+ "bigWrites",
+ "dontMask",
+ "noOpen",
+ }
+}
+
+func (x *connection) beforeSave() {}
+
+func (x *connection) StateSave(m state.Sink) {
+ x.beforeSave()
+ var initializedChan bool = x.saveInitializedChan()
+ m.SaveValue(3, initializedChan)
+ m.Save(0, &x.fd)
+ m.Save(1, &x.attributeVersion)
+ m.Save(2, &x.initialized)
+ m.Save(4, &x.connected)
+ m.Save(5, &x.connInitError)
+ m.Save(6, &x.connInitSuccess)
+ m.Save(7, &x.aborted)
+ m.Save(8, &x.numWaiting)
+ m.Save(9, &x.asyncNum)
+ m.Save(10, &x.asyncCongestionThreshold)
+ m.Save(11, &x.asyncNumMax)
+ m.Save(12, &x.maxRead)
+ m.Save(13, &x.maxWrite)
+ m.Save(14, &x.maxPages)
+ m.Save(15, &x.minor)
+ m.Save(16, &x.atomicOTrunc)
+ m.Save(17, &x.asyncRead)
+ m.Save(18, &x.writebackCache)
+ m.Save(19, &x.bigWrites)
+ m.Save(20, &x.dontMask)
+ m.Save(21, &x.noOpen)
+}
+
+func (x *connection) afterLoad() {}
+
+func (x *connection) StateLoad(m state.Source) {
+ m.Load(0, &x.fd)
+ m.Load(1, &x.attributeVersion)
+ m.Load(2, &x.initialized)
+ m.Load(4, &x.connected)
+ m.Load(5, &x.connInitError)
+ m.Load(6, &x.connInitSuccess)
+ m.Load(7, &x.aborted)
+ m.Load(8, &x.numWaiting)
+ m.Load(9, &x.asyncNum)
+ m.Load(10, &x.asyncCongestionThreshold)
+ m.Load(11, &x.asyncNumMax)
+ m.Load(12, &x.maxRead)
+ m.Load(13, &x.maxWrite)
+ m.Load(14, &x.maxPages)
+ m.Load(15, &x.minor)
+ m.Load(16, &x.atomicOTrunc)
+ m.Load(17, &x.asyncRead)
+ m.Load(18, &x.writebackCache)
+ m.Load(19, &x.bigWrites)
+ m.Load(20, &x.dontMask)
+ m.Load(21, &x.noOpen)
+ m.LoadValue(3, new(bool), func(y interface{}) { x.loadInitializedChan(y.(bool)) })
+}
+
+func (x *fuseDevice) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.fuseDevice"
+}
+
+func (x *fuseDevice) StateFields() []string {
+ return []string{}
+}
+
+func (x *fuseDevice) beforeSave() {}
+
+func (x *fuseDevice) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *fuseDevice) afterLoad() {}
+
+func (x *fuseDevice) StateLoad(m state.Source) {
+}
+
+func (x *DeviceFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.DeviceFD"
+}
+
+func (x *DeviceFD) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "DentryMetadataFileDescriptionImpl",
+ "NoLockFD",
+ "nextOpID",
+ "queue",
+ "numActiveRequests",
+ "completions",
+ "writeCursor",
+ "writeBuf",
+ "writeCursorFR",
+ "waitQueue",
+ "fullQueueCh",
+ "fs",
+ }
+}
+
+func (x *DeviceFD) beforeSave() {}
+
+func (x *DeviceFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ var fullQueueCh int = x.saveFullQueueCh()
+ m.SaveValue(12, fullQueueCh)
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Save(3, &x.NoLockFD)
+ m.Save(4, &x.nextOpID)
+ m.Save(5, &x.queue)
+ m.Save(6, &x.numActiveRequests)
+ m.Save(7, &x.completions)
+ m.Save(8, &x.writeCursor)
+ m.Save(9, &x.writeBuf)
+ m.Save(10, &x.writeCursorFR)
+ m.Save(11, &x.waitQueue)
+ m.Save(13, &x.fs)
+}
+
+func (x *DeviceFD) afterLoad() {}
+
+func (x *DeviceFD) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Load(3, &x.NoLockFD)
+ m.Load(4, &x.nextOpID)
+ m.Load(5, &x.queue)
+ m.Load(6, &x.numActiveRequests)
+ m.Load(7, &x.completions)
+ m.Load(8, &x.writeCursor)
+ m.Load(9, &x.writeBuf)
+ m.Load(10, &x.writeCursorFR)
+ m.Load(11, &x.waitQueue)
+ m.Load(13, &x.fs)
+ m.LoadValue(12, new(int), func(y interface{}) { x.loadFullQueueCh(y.(int)) })
+}
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystemOptions) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.filesystemOptions"
+}
+
+func (x *filesystemOptions) StateFields() []string {
+ return []string{
+ "userID",
+ "groupID",
+ "rootMode",
+ "maxActiveRequests",
+ "maxRead",
+ }
+}
+
+func (x *filesystemOptions) beforeSave() {}
+
+func (x *filesystemOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.userID)
+ m.Save(1, &x.groupID)
+ m.Save(2, &x.rootMode)
+ m.Save(3, &x.maxActiveRequests)
+ m.Save(4, &x.maxRead)
+}
+
+func (x *filesystemOptions) afterLoad() {}
+
+func (x *filesystemOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.userID)
+ m.Load(1, &x.groupID)
+ m.Load(2, &x.rootMode)
+ m.Load(3, &x.maxActiveRequests)
+ m.Load(4, &x.maxRead)
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ "conn",
+ "opts",
+ "umounted",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+ m.Save(2, &x.conn)
+ m.Save(3, &x.opts)
+ m.Save(4, &x.umounted)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+ m.Load(2, &x.conn)
+ m.Load(3, &x.opts)
+ m.Load(4, &x.umounted)
+}
+
+func (x *inode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/fuse.inode"
+}
+
+func (x *inode) StateFields() []string {
+ return []string{
+ "inodeRefs",
+ "InodeAttrs",
+ "InodeDirectoryNoNewChildren",
+ "InodeNoDynamicLookup",
+ "InodeNotSymlink",
+ "OrderedChildren",
+ "dentry",
+ "fs",
+ "metadataMu",
+ "nodeID",
+ "locks",
+ "size",
+ "attributeVersion",
+ "attributeTime",
+ "version",
+ "link",
+ }
+}
+
+func (x *inode) beforeSave() {}
+
+func (x *inode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inodeRefs)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeDirectoryNoNewChildren)
+ m.Save(3, &x.InodeNoDynamicLookup)
+ m.Save(4, &x.InodeNotSymlink)
+ m.Save(5, &x.OrderedChildren)
+ m.Save(6, &x.dentry)
+ m.Save(7, &x.fs)
+ m.Save(8, &x.metadataMu)
+ m.Save(9, &x.nodeID)
+ m.Save(10, &x.locks)
+ m.Save(11, &x.size)
+ m.Save(12, &x.attributeVersion)
+ m.Save(13, &x.attributeTime)
+ m.Save(14, &x.version)
+ m.Save(15, &x.link)
+}
+
+func (x *inode) afterLoad() {}
+
+func (x *inode) StateLoad(m state.Source) {
+ m.Load(0, &x.inodeRefs)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeDirectoryNoNewChildren)
+ m.Load(3, &x.InodeNoDynamicLookup)
+ m.Load(4, &x.InodeNotSymlink)
+ m.Load(5, &x.OrderedChildren)
+ m.Load(6, &x.dentry)
+ m.Load(7, &x.fs)
+ m.Load(8, &x.metadataMu)
+ m.Load(9, &x.nodeID)
+ m.Load(10, &x.locks)
+ m.Load(11, &x.size)
+ m.Load(12, &x.attributeVersion)
+ m.Load(13, &x.attributeTime)
+ m.Load(14, &x.version)
+ m.Load(15, &x.link)
+}
+
func (x *inodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/fuse.inodeRefs"
}
@@ -187,6 +513,13 @@ func (x *Response) StateLoad(m state.Source) {
}
func init() {
+ state.Register((*connection)(nil))
+ state.Register((*fuseDevice)(nil))
+ state.Register((*DeviceFD)(nil))
+ state.Register((*FilesystemType)(nil))
+ state.Register((*filesystemOptions)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*inode)(nil))
state.Register((*inodeRefs)(nil))
state.Register((*requestList)(nil))
state.Register((*requestEntry)(nil))
diff --git a/pkg/sentry/fsimpl/fuse/fusefs.go b/pkg/sentry/fsimpl/fuse/fusefs.go
index 5ccfc43e7..2f7cd8b8a 100644
--- a/pkg/sentry/fsimpl/fuse/fusefs.go
+++ b/pkg/sentry/fsimpl/fuse/fusefs.go
@@ -41,8 +41,11 @@ const Name = "fuse"
const maxActiveRequestsDefault = 10000
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
+// +stateify savable
type filesystemOptions struct {
// userID specifies the numeric uid of the mount owner.
// This option should not be specified by the filesystem owner.
@@ -73,6 +76,8 @@ type filesystemOptions struct {
}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
devMinor uint32
@@ -240,6 +245,8 @@ func (fs *filesystem) Release(ctx context.Context) {
}
// inode implements kernfs.Inode.
+//
+// +stateify savable
type inode struct {
inodeRefs
kernfs.InodeAttrs
diff --git a/pkg/sentry/fsimpl/gofer/directory.go b/pkg/sentry/fsimpl/gofer/directory.go
index 91d2ae199..18c884b59 100644
--- a/pkg/sentry/fsimpl/gofer/directory.go
+++ b/pkg/sentry/fsimpl/gofer/directory.go
@@ -117,11 +117,12 @@ func (d *dentry) createSyntheticChildLocked(opts *createSyntheticOpts) {
d.syntheticChildren++
}
+// +stateify savable
type directoryFD struct {
fileDescription
vfs.DirectoryFileDescriptionDefaultImpl
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
off int64
dirents []vfs.Dirent
}
diff --git a/pkg/sentry/fsimpl/gofer/gofer.go b/pkg/sentry/fsimpl/gofer/gofer.go
index aaad9c0d9..8608471f8 100644
--- a/pkg/sentry/fsimpl/gofer/gofer.go
+++ b/pkg/sentry/fsimpl/gofer/gofer.go
@@ -62,9 +62,13 @@ import (
const Name = "9p"
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
vfsfs vfs.Filesystem
@@ -77,7 +81,7 @@ type filesystem struct {
iopts InternalFilesystemOptions
// client is the client used by this filesystem. client is immutable.
- client *p9.Client
+ client *p9.Client `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
// clock is a realtime clock used to set timestamps in file operations.
clock ktime.Clock
@@ -95,7 +99,7 @@ type filesystem struct {
// reference count (such that it is usable as vfs.ResolvingPath.Start() or
// is reachable from its children), or if it is a child dentry (such that
// it is reachable from its parent).
- renameMu sync.RWMutex
+ renameMu sync.RWMutex `state:"nosave"`
// cachedDentries contains all dentries with 0 references. (Due to race
// conditions, it may also contain dentries with non-zero references.)
@@ -107,7 +111,7 @@ type filesystem struct {
// syncableDentries contains all dentries in this filesystem for which
// !dentry.file.isNil(). specialFileFDs contains all open specialFileFDs.
// These fields are protected by syncMu.
- syncMu sync.Mutex
+ syncMu sync.Mutex `state:"nosave"`
syncableDentries map[*dentry]struct{}
specialFileFDs map[*specialFileFD]struct{}
@@ -120,6 +124,8 @@ type filesystem struct {
// dentries, it comes from QID.Path from the 9P server. Synthetic dentries
// have have their inodeNumber generated sequentially, with the MSB reserved to
// prevent conflicts with regular dentries.
+//
+// +stateify savable
type inodeNumber uint64
// Reserve MSB for synthetic mounts.
@@ -132,6 +138,7 @@ func inoFromPath(path uint64) inodeNumber {
return inodeNumber(path &^ syntheticInoMask)
}
+// +stateify savable
type filesystemOptions struct {
// "Standard" 9P options.
fd int
@@ -177,6 +184,8 @@ type filesystemOptions struct {
// InteropMode controls the client's interaction with other remote filesystem
// users.
+//
+// +stateify savable
type InteropMode uint32
const (
@@ -235,6 +244,8 @@ const (
// InternalFilesystemOptions may be passed as
// vfs.GetFilesystemOptions.InternalData to FilesystemType.GetFilesystem.
+//
+// +stateify savable
type InternalFilesystemOptions struct {
// If LeakConnection is true, do not close the connection to the server
// when the Filesystem is released. This is necessary for deployments in
@@ -534,6 +545,8 @@ func (fs *filesystem) Release(ctx context.Context) {
}
// dentry implements vfs.DentryImpl.
+//
+// +stateify savable
type dentry struct {
vfsd vfs.Dentry
@@ -563,7 +576,7 @@ type dentry struct {
// If file.isNil(), this dentry represents a synthetic file, i.e. a file
// that does not exist on the remote filesystem. As of this writing, the
// only files that can be synthetic are sockets, pipes, and directories.
- file p9file
+ file p9file `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
// If deleted is non-zero, the file represented by this dentry has been
// deleted. deleted is accessed using atomic memory operations.
@@ -575,7 +588,7 @@ type dentry struct {
cached bool
dentryEntry
- dirMu sync.Mutex
+ dirMu sync.Mutex `state:"nosave"`
// If this dentry represents a directory, children contains:
//
@@ -607,7 +620,7 @@ type dentry struct {
// To mutate:
// - Lock metadataMu and use atomic operations to update because we might
// have atomic readers that don't hold the lock.
- metadataMu sync.Mutex
+ metadataMu sync.Mutex `state:"nosave"`
ino inodeNumber // immutable
mode uint32 // type is immutable, perms are mutable
uid uint32 // auth.KUID, but stored as raw uint32 for sync/atomic
@@ -638,7 +651,7 @@ type dentry struct {
// other metadata fields.
nlink uint32
- mapsMu sync.Mutex
+ mapsMu sync.Mutex `state:"nosave"`
// If this dentry represents a regular file, mappings tracks mappings of
// the file into memmap.MappingSpaces. mappings is protected by mapsMu.
@@ -662,12 +675,12 @@ type dentry struct {
// either p9.File transitions from closed (isNil() == true) to open
// (isNil() == false), it may be mutated with handleMu locked, but cannot
// be closed until the dentry is destroyed.
- handleMu sync.RWMutex
- readFile p9file
- writeFile p9file
+ handleMu sync.RWMutex `state:"nosave"`
+ readFile p9file `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
+ writeFile p9file `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
hostFD int32
- dataMu sync.RWMutex
+ dataMu sync.RWMutex `state:"nosave"`
// If this dentry represents a regular file that is client-cached, cache
// maps offsets into the cached file to offsets into
@@ -1627,12 +1640,14 @@ func (d *dentry) decLinks() {
// fileDescription is embedded by gofer implementations of
// vfs.FileDescriptionImpl.
+//
+// +stateify savable
type fileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
vfs.LockFD
- lockLogging sync.Once
+ lockLogging sync.Once `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
}
func (fd *fileDescription) filesystem() *filesystem {
diff --git a/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go b/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go
index 19b1eef9e..7831e1830 100644
--- a/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go
+++ b/pkg/sentry/fsimpl/gofer/gofer_state_autogen.go
@@ -58,7 +58,495 @@ func (x *dentryEntry) StateLoad(m state.Source) {
m.Load(1, &x.prev)
}
+func (x *directoryFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.directoryFD"
+}
+
+func (x *directoryFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "DirectoryFileDescriptionDefaultImpl",
+ "off",
+ "dirents",
+ }
+}
+
+func (x *directoryFD) beforeSave() {}
+
+func (x *directoryFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Save(2, &x.off)
+ m.Save(3, &x.dirents)
+}
+
+func (x *directoryFD) afterLoad() {}
+
+func (x *directoryFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Load(2, &x.off)
+ m.Load(3, &x.dirents)
+}
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "vfsfs",
+ "mfp",
+ "opts",
+ "iopts",
+ "clock",
+ "devMinor",
+ "cachedDentries",
+ "cachedDentriesLen",
+ "syncableDentries",
+ "specialFileFDs",
+ "syntheticSeq",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfs)
+ m.Save(1, &x.mfp)
+ m.Save(2, &x.opts)
+ m.Save(3, &x.iopts)
+ m.Save(4, &x.clock)
+ m.Save(5, &x.devMinor)
+ m.Save(6, &x.cachedDentries)
+ m.Save(7, &x.cachedDentriesLen)
+ m.Save(8, &x.syncableDentries)
+ m.Save(9, &x.specialFileFDs)
+ m.Save(10, &x.syntheticSeq)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfs)
+ m.Load(1, &x.mfp)
+ m.Load(2, &x.opts)
+ m.Load(3, &x.iopts)
+ m.Load(4, &x.clock)
+ m.Load(5, &x.devMinor)
+ m.Load(6, &x.cachedDentries)
+ m.Load(7, &x.cachedDentriesLen)
+ m.Load(8, &x.syncableDentries)
+ m.Load(9, &x.specialFileFDs)
+ m.Load(10, &x.syntheticSeq)
+}
+
+func (x *inodeNumber) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.inodeNumber"
+}
+
+func (x *inodeNumber) StateFields() []string {
+ return nil
+}
+
+func (x *filesystemOptions) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.filesystemOptions"
+}
+
+func (x *filesystemOptions) StateFields() []string {
+ return []string{
+ "fd",
+ "aname",
+ "interop",
+ "dfltuid",
+ "dfltgid",
+ "msize",
+ "version",
+ "maxCachedDentries",
+ "forcePageCache",
+ "limitHostFDTranslation",
+ "overlayfsStaleRead",
+ "regularFilesUseSpecialFileFD",
+ }
+}
+
+func (x *filesystemOptions) beforeSave() {}
+
+func (x *filesystemOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fd)
+ m.Save(1, &x.aname)
+ m.Save(2, &x.interop)
+ m.Save(3, &x.dfltuid)
+ m.Save(4, &x.dfltgid)
+ m.Save(5, &x.msize)
+ m.Save(6, &x.version)
+ m.Save(7, &x.maxCachedDentries)
+ m.Save(8, &x.forcePageCache)
+ m.Save(9, &x.limitHostFDTranslation)
+ m.Save(10, &x.overlayfsStaleRead)
+ m.Save(11, &x.regularFilesUseSpecialFileFD)
+}
+
+func (x *filesystemOptions) afterLoad() {}
+
+func (x *filesystemOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.fd)
+ m.Load(1, &x.aname)
+ m.Load(2, &x.interop)
+ m.Load(3, &x.dfltuid)
+ m.Load(4, &x.dfltgid)
+ m.Load(5, &x.msize)
+ m.Load(6, &x.version)
+ m.Load(7, &x.maxCachedDentries)
+ m.Load(8, &x.forcePageCache)
+ m.Load(9, &x.limitHostFDTranslation)
+ m.Load(10, &x.overlayfsStaleRead)
+ m.Load(11, &x.regularFilesUseSpecialFileFD)
+}
+
+func (x *InteropMode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.InteropMode"
+}
+
+func (x *InteropMode) StateFields() []string {
+ return nil
+}
+
+func (x *InternalFilesystemOptions) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.InternalFilesystemOptions"
+}
+
+func (x *InternalFilesystemOptions) StateFields() []string {
+ return []string{
+ "LeakConnection",
+ "OpenSocketsByConnecting",
+ }
+}
+
+func (x *InternalFilesystemOptions) beforeSave() {}
+
+func (x *InternalFilesystemOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.LeakConnection)
+ m.Save(1, &x.OpenSocketsByConnecting)
+}
+
+func (x *InternalFilesystemOptions) afterLoad() {}
+
+func (x *InternalFilesystemOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.LeakConnection)
+ m.Load(1, &x.OpenSocketsByConnecting)
+}
+
+func (x *dentry) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.dentry"
+}
+
+func (x *dentry) StateFields() []string {
+ return []string{
+ "vfsd",
+ "refs",
+ "fs",
+ "parent",
+ "name",
+ "deleted",
+ "cached",
+ "dentryEntry",
+ "children",
+ "syntheticChildren",
+ "dirents",
+ "ino",
+ "mode",
+ "uid",
+ "gid",
+ "blockSize",
+ "atime",
+ "mtime",
+ "ctime",
+ "btime",
+ "size",
+ "atimeDirty",
+ "mtimeDirty",
+ "nlink",
+ "mappings",
+ "hostFD",
+ "cache",
+ "dirty",
+ "pf",
+ "haveTarget",
+ "target",
+ "endpoint",
+ "pipe",
+ "locks",
+ "watches",
+ }
+}
+
+func (x *dentry) beforeSave() {}
+
+func (x *dentry) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsd)
+ m.Save(1, &x.refs)
+ m.Save(2, &x.fs)
+ m.Save(3, &x.parent)
+ m.Save(4, &x.name)
+ m.Save(5, &x.deleted)
+ m.Save(6, &x.cached)
+ m.Save(7, &x.dentryEntry)
+ m.Save(8, &x.children)
+ m.Save(9, &x.syntheticChildren)
+ m.Save(10, &x.dirents)
+ m.Save(11, &x.ino)
+ m.Save(12, &x.mode)
+ m.Save(13, &x.uid)
+ m.Save(14, &x.gid)
+ m.Save(15, &x.blockSize)
+ m.Save(16, &x.atime)
+ m.Save(17, &x.mtime)
+ m.Save(18, &x.ctime)
+ m.Save(19, &x.btime)
+ m.Save(20, &x.size)
+ m.Save(21, &x.atimeDirty)
+ m.Save(22, &x.mtimeDirty)
+ m.Save(23, &x.nlink)
+ m.Save(24, &x.mappings)
+ m.Save(25, &x.hostFD)
+ m.Save(26, &x.cache)
+ m.Save(27, &x.dirty)
+ m.Save(28, &x.pf)
+ m.Save(29, &x.haveTarget)
+ m.Save(30, &x.target)
+ m.Save(31, &x.endpoint)
+ m.Save(32, &x.pipe)
+ m.Save(33, &x.locks)
+ m.Save(34, &x.watches)
+}
+
+func (x *dentry) afterLoad() {}
+
+func (x *dentry) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsd)
+ m.Load(1, &x.refs)
+ m.Load(2, &x.fs)
+ m.Load(3, &x.parent)
+ m.Load(4, &x.name)
+ m.Load(5, &x.deleted)
+ m.Load(6, &x.cached)
+ m.Load(7, &x.dentryEntry)
+ m.Load(8, &x.children)
+ m.Load(9, &x.syntheticChildren)
+ m.Load(10, &x.dirents)
+ m.Load(11, &x.ino)
+ m.Load(12, &x.mode)
+ m.Load(13, &x.uid)
+ m.Load(14, &x.gid)
+ m.Load(15, &x.blockSize)
+ m.Load(16, &x.atime)
+ m.Load(17, &x.mtime)
+ m.Load(18, &x.ctime)
+ m.Load(19, &x.btime)
+ m.Load(20, &x.size)
+ m.Load(21, &x.atimeDirty)
+ m.Load(22, &x.mtimeDirty)
+ m.Load(23, &x.nlink)
+ m.Load(24, &x.mappings)
+ m.Load(25, &x.hostFD)
+ m.Load(26, &x.cache)
+ m.Load(27, &x.dirty)
+ m.Load(28, &x.pf)
+ m.Load(29, &x.haveTarget)
+ m.Load(30, &x.target)
+ m.Load(31, &x.endpoint)
+ m.Load(32, &x.pipe)
+ m.Load(33, &x.locks)
+ m.Load(34, &x.watches)
+}
+
+func (x *fileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.fileDescription"
+}
+
+func (x *fileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ }
+}
+
+func (x *fileDescription) beforeSave() {}
+
+func (x *fileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+}
+
+func (x *fileDescription) afterLoad() {}
+
+func (x *fileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+}
+
+func (x *regularFileFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.regularFileFD"
+}
+
+func (x *regularFileFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "off",
+ }
+}
+
+func (x *regularFileFD) beforeSave() {}
+
+func (x *regularFileFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.off)
+}
+
+func (x *regularFileFD) afterLoad() {}
+
+func (x *regularFileFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.off)
+}
+
+func (x *dentryPlatformFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.dentryPlatformFile"
+}
+
+func (x *dentryPlatformFile) StateFields() []string {
+ return []string{
+ "dentry",
+ "fdRefs",
+ "hostFileMapper",
+ }
+}
+
+func (x *dentryPlatformFile) beforeSave() {}
+
+func (x *dentryPlatformFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.dentry)
+ m.Save(1, &x.fdRefs)
+ m.Save(2, &x.hostFileMapper)
+}
+
+func (x *dentryPlatformFile) afterLoad() {}
+
+func (x *dentryPlatformFile) StateLoad(m state.Source) {
+ m.Load(0, &x.dentry)
+ m.Load(1, &x.fdRefs)
+ m.Load(2, &x.hostFileMapper)
+}
+
+func (x *endpoint) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.endpoint"
+}
+
+func (x *endpoint) StateFields() []string {
+ return []string{
+ "dentry",
+ "path",
+ }
+}
+
+func (x *endpoint) beforeSave() {}
+
+func (x *endpoint) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.dentry)
+ m.Save(1, &x.path)
+}
+
+func (x *endpoint) afterLoad() {}
+
+func (x *endpoint) StateLoad(m state.Source) {
+ m.Load(0, &x.dentry)
+ m.Load(1, &x.path)
+}
+
+func (x *specialFileFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/gofer.specialFileFD"
+}
+
+func (x *specialFileFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "isRegularFile",
+ "seekable",
+ "haveQueue",
+ "queue",
+ "off",
+ }
+}
+
+func (x *specialFileFD) beforeSave() {}
+
+func (x *specialFileFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.isRegularFile)
+ m.Save(2, &x.seekable)
+ m.Save(3, &x.haveQueue)
+ m.Save(4, &x.queue)
+ m.Save(5, &x.off)
+}
+
+func (x *specialFileFD) afterLoad() {}
+
+func (x *specialFileFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.isRegularFile)
+ m.Load(2, &x.seekable)
+ m.Load(3, &x.haveQueue)
+ m.Load(4, &x.queue)
+ m.Load(5, &x.off)
+}
+
func init() {
state.Register((*dentryList)(nil))
state.Register((*dentryEntry)(nil))
+ state.Register((*directoryFD)(nil))
+ state.Register((*FilesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*inodeNumber)(nil))
+ state.Register((*filesystemOptions)(nil))
+ state.Register((*InteropMode)(nil))
+ state.Register((*InternalFilesystemOptions)(nil))
+ state.Register((*dentry)(nil))
+ state.Register((*fileDescription)(nil))
+ state.Register((*regularFileFD)(nil))
+ state.Register((*dentryPlatformFile)(nil))
+ state.Register((*endpoint)(nil))
+ state.Register((*specialFileFD)(nil))
}
diff --git a/pkg/sentry/fsimpl/gofer/handle.go b/pkg/sentry/fsimpl/gofer/handle.go
index 104157512..a9ebe1206 100644
--- a/pkg/sentry/fsimpl/gofer/handle.go
+++ b/pkg/sentry/fsimpl/gofer/handle.go
@@ -25,6 +25,8 @@ import (
// handle represents a remote "open file descriptor", consisting of an opened
// fid (p9.File) and optionally a host file descriptor.
+//
+// These are explicitly not savable.
type handle struct {
file p9file
fd int32 // -1 if unavailable
diff --git a/pkg/sentry/fsimpl/gofer/regular_file.go b/pkg/sentry/fsimpl/gofer/regular_file.go
index 24f03ee94..eeaf6e444 100644
--- a/pkg/sentry/fsimpl/gofer/regular_file.go
+++ b/pkg/sentry/fsimpl/gofer/regular_file.go
@@ -39,11 +39,12 @@ func (d *dentry) isRegularFile() bool {
return d.fileType() == linux.S_IFREG
}
+// +stateify savable
type regularFileFD struct {
fileDescription
// off is the file offset. off is protected by mu.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
off int64
}
@@ -898,6 +899,8 @@ func (d *dentry) Evict(ctx context.Context, er pgalloc.EvictableRange) {
// dentryPlatformFile is only used when a host FD representing the remote file
// is available (i.e. dentry.hostFD >= 0), and that FD is used for application
// memory mappings (i.e. !filesystem.opts.forcePageCache).
+//
+// +stateify savable
type dentryPlatformFile struct {
*dentry
@@ -910,7 +913,7 @@ type dentryPlatformFile struct {
hostFileMapper fsutil.HostFileMapper
// hostFileMapperInitOnce is used to lazily initialize hostFileMapper.
- hostFileMapperInitOnce sync.Once
+ hostFileMapperInitOnce sync.Once `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
}
// IncRef implements memmap.File.IncRef.
diff --git a/pkg/sentry/fsimpl/gofer/socket.go b/pkg/sentry/fsimpl/gofer/socket.go
index 85d2bee72..326b940a7 100644
--- a/pkg/sentry/fsimpl/gofer/socket.go
+++ b/pkg/sentry/fsimpl/gofer/socket.go
@@ -36,12 +36,14 @@ func (d *dentry) isSocket() bool {
// An endpoint's lifetime is the time between when filesystem.BoundEndpointAt()
// is called and either BoundEndpoint.BidirectionalConnect or
// BoundEndpoint.UnidirectionalConnect is called.
+//
+// +stateify savable
type endpoint struct {
// dentry is the filesystem dentry which produced this endpoint.
dentry *dentry
// file is the p9 file that contains a single unopened fid.
- file p9.File
+ file p9.File `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
// path is the sentry path where this endpoint is bound.
path string
diff --git a/pkg/sentry/fsimpl/gofer/special_file.go b/pkg/sentry/fsimpl/gofer/special_file.go
index 576c57491..71581736c 100644
--- a/pkg/sentry/fsimpl/gofer/special_file.go
+++ b/pkg/sentry/fsimpl/gofer/special_file.go
@@ -34,11 +34,13 @@ import (
// special files, and (when filesystemOptions.regularFilesUseSpecialFileFD is
// in effect) regular files. specialFileFD differs from regularFileFD by using
// per-FD handles instead of shared per-dentry handles, and never buffering I/O.
+//
+// +stateify savable
type specialFileFD struct {
fileDescription
// handle is used for file I/O. handle is immutable.
- handle handle
+ handle handle `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
// isRegularFile is true if this FD represents a regular file which is only
// possible when filesystemOptions.regularFilesUseSpecialFileFD is in
@@ -56,7 +58,7 @@ type specialFileFD struct {
queue waiter.Queue
// If seekable is true, off is the file offset. off is protected by mu.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
off int64
}
diff --git a/pkg/sentry/fsimpl/host/host.go b/pkg/sentry/fsimpl/host/host.go
index c0cef3453..ffe4ddb32 100644
--- a/pkg/sentry/fsimpl/host/host.go
+++ b/pkg/sentry/fsimpl/host/host.go
@@ -137,6 +137,8 @@ func ImportFD(ctx context.Context, mnt *vfs.Mount, hostFD int, isTTY bool) (*vfs
}
// filesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type filesystemType struct{}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
@@ -166,6 +168,8 @@ func NewFilesystem(vfsObj *vfs.VirtualFilesystem) (*vfs.Filesystem, error) {
}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
@@ -185,6 +189,8 @@ func (fs *filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDe
}
// inode implements kernfs.Inode.
+//
+// +stateify savable
type inode struct {
kernfs.InodeNoStatFS
kernfs.InodeNotDirectory
@@ -233,7 +239,7 @@ type inode struct {
canMap bool
// mapsMu protects mappings.
- mapsMu sync.Mutex
+ mapsMu sync.Mutex `state:"nosave"`
// If canMap is true, mappings tracks mappings of hostFD into
// memmap.MappingSpaces.
@@ -511,6 +517,8 @@ func (i *inode) open(ctx context.Context, d *kernfs.Dentry, mnt *vfs.Mount, flag
}
// fileDescription is embedded by host fd implementations of FileDescriptionImpl.
+//
+// +stateify savable
type fileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
@@ -525,7 +533,7 @@ type fileDescription struct {
inode *inode
// offsetMu protects offset.
- offsetMu sync.Mutex
+ offsetMu sync.Mutex `state:"nosave"`
// offset specifies the current file offset. It is only meaningful when
// inode.seekable is true.
diff --git a/pkg/sentry/fsimpl/host/host_state_autogen.go b/pkg/sentry/fsimpl/host/host_state_autogen.go
index 400320c78..c97fa7212 100644
--- a/pkg/sentry/fsimpl/host/host_state_autogen.go
+++ b/pkg/sentry/fsimpl/host/host_state_autogen.go
@@ -29,6 +29,148 @@ func (x *ConnectedEndpointRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *filesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/host.filesystemType"
+}
+
+func (x *filesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *filesystemType) beforeSave() {}
+
+func (x *filesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *filesystemType) afterLoad() {}
+
+func (x *filesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/host.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *inode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/host.inode"
+}
+
+func (x *inode) StateFields() []string {
+ return []string{
+ "InodeNoStatFS",
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ "locks",
+ "inodeRefs",
+ "hostFD",
+ "ino",
+ "isTTY",
+ "seekable",
+ "wouldBlock",
+ "queue",
+ "canMap",
+ "mappings",
+ "pf",
+ }
+}
+
+func (x *inode) beforeSave() {}
+
+func (x *inode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeNoStatFS)
+ m.Save(1, &x.InodeNotDirectory)
+ m.Save(2, &x.InodeNotSymlink)
+ m.Save(3, &x.locks)
+ m.Save(4, &x.inodeRefs)
+ m.Save(5, &x.hostFD)
+ m.Save(6, &x.ino)
+ m.Save(7, &x.isTTY)
+ m.Save(8, &x.seekable)
+ m.Save(9, &x.wouldBlock)
+ m.Save(10, &x.queue)
+ m.Save(11, &x.canMap)
+ m.Save(12, &x.mappings)
+ m.Save(13, &x.pf)
+}
+
+func (x *inode) afterLoad() {}
+
+func (x *inode) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeNoStatFS)
+ m.Load(1, &x.InodeNotDirectory)
+ m.Load(2, &x.InodeNotSymlink)
+ m.Load(3, &x.locks)
+ m.Load(4, &x.inodeRefs)
+ m.Load(5, &x.hostFD)
+ m.Load(6, &x.ino)
+ m.Load(7, &x.isTTY)
+ m.Load(8, &x.seekable)
+ m.Load(9, &x.wouldBlock)
+ m.Load(10, &x.queue)
+ m.Load(11, &x.canMap)
+ m.Load(12, &x.mappings)
+ m.Load(13, &x.pf)
+}
+
+func (x *fileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/host.fileDescription"
+}
+
+func (x *fileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ "inode",
+ "offset",
+ }
+}
+
+func (x *fileDescription) beforeSave() {}
+
+func (x *fileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+ m.Save(3, &x.inode)
+ m.Save(4, &x.offset)
+}
+
+func (x *fileDescription) afterLoad() {}
+
+func (x *fileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+ m.Load(3, &x.inode)
+ m.Load(4, &x.offset)
+}
+
func (x *inodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/host.inodeRefs"
}
@@ -52,6 +194,35 @@ func (x *inodeRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *inodePlatformFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/host.inodePlatformFile"
+}
+
+func (x *inodePlatformFile) StateFields() []string {
+ return []string{
+ "inode",
+ "fdRefs",
+ "fileMapper",
+ }
+}
+
+func (x *inodePlatformFile) beforeSave() {}
+
+func (x *inodePlatformFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.fdRefs)
+ m.Save(2, &x.fileMapper)
+}
+
+func (x *inodePlatformFile) afterLoad() {}
+
+func (x *inodePlatformFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.fdRefs)
+ m.Load(2, &x.fileMapper)
+}
+
func (x *ConnectedEndpoint) StateTypeName() string {
return "pkg/sentry/fsimpl/host.ConnectedEndpoint"
}
@@ -84,8 +255,46 @@ func (x *ConnectedEndpoint) StateLoad(m state.Source) {
m.Load(3, &x.stype)
}
+func (x *TTYFileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/host.TTYFileDescription"
+}
+
+func (x *TTYFileDescription) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "session",
+ "fgProcessGroup",
+ "termios",
+ }
+}
+
+func (x *TTYFileDescription) beforeSave() {}
+
+func (x *TTYFileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.session)
+ m.Save(2, &x.fgProcessGroup)
+ m.Save(3, &x.termios)
+}
+
+func (x *TTYFileDescription) afterLoad() {}
+
+func (x *TTYFileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.session)
+ m.Load(2, &x.fgProcessGroup)
+ m.Load(3, &x.termios)
+}
+
func init() {
state.Register((*ConnectedEndpointRefs)(nil))
+ state.Register((*filesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*inode)(nil))
+ state.Register((*fileDescription)(nil))
state.Register((*inodeRefs)(nil))
+ state.Register((*inodePlatformFile)(nil))
state.Register((*ConnectedEndpoint)(nil))
+ state.Register((*TTYFileDescription)(nil))
}
diff --git a/pkg/sentry/fsimpl/host/mmap.go b/pkg/sentry/fsimpl/host/mmap.go
index 65d3af38c..b51a17bed 100644
--- a/pkg/sentry/fsimpl/host/mmap.go
+++ b/pkg/sentry/fsimpl/host/mmap.go
@@ -27,11 +27,13 @@ import (
// cannot implement both kernfs.Inode.IncRef and memmap.File.IncRef.
//
// inodePlatformFile should only be used if inode.canMap is true.
+//
+// +stateify savable
type inodePlatformFile struct {
*inode
// fdRefsMu protects fdRefs.
- fdRefsMu sync.Mutex
+ fdRefsMu sync.Mutex `state:"nosave"`
// fdRefs counts references on memmap.File offsets. It is used solely for
// memory accounting.
@@ -41,7 +43,7 @@ type inodePlatformFile struct {
fileMapper fsutil.HostFileMapper
// fileMapperInitOnce is used to lazily initialize fileMapper.
- fileMapperInitOnce sync.Once
+ fileMapperInitOnce sync.Once `state:"nosave"` // FIXME(gvisor.dev/issue/1663): not yet supported.
}
// IncRef implements memmap.File.IncRef.
diff --git a/pkg/sentry/fsimpl/host/tty.go b/pkg/sentry/fsimpl/host/tty.go
index e02b9b8f6..f5c596fec 100644
--- a/pkg/sentry/fsimpl/host/tty.go
+++ b/pkg/sentry/fsimpl/host/tty.go
@@ -30,6 +30,8 @@ import (
// TTYFileDescription implements vfs.FileDescriptionImpl for a host file
// descriptor that wraps a TTY FD.
+//
+// +stateify savable
type TTYFileDescription struct {
fileDescription
diff --git a/pkg/sentry/fsimpl/kernfs/fd_impl_util.go b/pkg/sentry/fsimpl/kernfs/fd_impl_util.go
index 2b4294228..c7bd3baae 100644
--- a/pkg/sentry/fsimpl/kernfs/fd_impl_util.go
+++ b/pkg/sentry/fsimpl/kernfs/fd_impl_util.go
@@ -29,6 +29,8 @@ import (
)
// SeekEndConfig describes the SEEK_END behaviour for FDs.
+//
+// +stateify savable
type SeekEndConfig int
// Constants related to SEEK_END behaviour for FDs.
@@ -41,6 +43,8 @@ const (
)
// GenericDirectoryFDOptions contains configuration for a GenericDirectoryFD.
+//
+// +stateify savable
type GenericDirectoryFDOptions struct {
SeekEnd SeekEndConfig
}
@@ -56,6 +60,8 @@ type GenericDirectoryFDOptions struct {
// Must be initialize with Init before first use.
//
// Lock ordering: mu => children.mu.
+//
+// +stateify savable
type GenericDirectoryFD struct {
vfs.FileDescriptionDefaultImpl
vfs.DirectoryFileDescriptionDefaultImpl
@@ -68,7 +74,7 @@ type GenericDirectoryFD struct {
children *OrderedChildren
// mu protects the fields below.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
// off is the current directory offset. Protected by "mu".
off int64
diff --git a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go
index 5cc196980..d8e321acb 100644
--- a/pkg/sentry/fsimpl/kernfs/inode_impl_util.go
+++ b/pkg/sentry/fsimpl/kernfs/inode_impl_util.go
@@ -31,6 +31,8 @@ import (
// count for inodes, performing no extra actions when references are obtained or
// released. This is suitable for simple file inodes that don't reference any
// resources.
+//
+// +stateify savable
type InodeNoopRefCount struct {
}
@@ -50,6 +52,8 @@ func (InodeNoopRefCount) TryIncRef() bool {
// InodeDirectoryNoNewChildren partially implements the Inode interface.
// InodeDirectoryNoNewChildren represents a directory inode which does not
// support creation of new children.
+//
+// +stateify savable
type InodeDirectoryNoNewChildren struct{}
// NewFile implements Inode.NewFile.
@@ -81,6 +85,8 @@ func (InodeDirectoryNoNewChildren) NewNode(context.Context, string, vfs.MknodOpt
// inodeDirectory and inodeDynamicDirectory sub interfaces. Inodes that do not
// represent directories can embed this to provide no-op implementations for
// directory-related functions.
+//
+// +stateify savable
type InodeNotDirectory struct {
}
@@ -149,6 +155,8 @@ func (InodeNotDirectory) Valid(context.Context) bool {
// dymanic entries (i.e. entries that are not "hashed" into the
// vfs.Dentry.children) can embed this to provide no-op implementations for
// functions related to dynamic entries.
+//
+// +stateify savable
type InodeNoDynamicLookup struct{}
// Lookup implements Inode.Lookup.
@@ -169,6 +177,8 @@ func (InodeNoDynamicLookup) Valid(ctx context.Context) bool {
// InodeNotSymlink partially implements the Inode interface, specifically the
// inodeSymlink sub interface. All inodes that are not symlinks may embed this
// to return the appropriate errors from symlink-related functions.
+//
+// +stateify savable
type InodeNotSymlink struct{}
// Readlink implements Inode.Readlink.
@@ -186,6 +196,8 @@ func (InodeNotSymlink) Getlink(context.Context, *vfs.Mount) (vfs.VirtualDentry,
// inode attributes.
//
// Must be initialized by Init prior to first use.
+//
+// +stateify savable
type InodeAttrs struct {
devMajor uint32
devMinor uint32
@@ -330,6 +342,7 @@ func (a *InodeAttrs) DecLinks() {
}
}
+// +stateify savable
type slot struct {
Name string
Dentry *vfs.Dentry
@@ -337,6 +350,8 @@ type slot struct {
}
// OrderedChildrenOptions contains initialization options for OrderedChildren.
+//
+// +stateify savable
type OrderedChildrenOptions struct {
// Writable indicates whether vfs.FilesystemImpl methods implemented by
// OrderedChildren may modify the tracked children. This applies to
@@ -352,12 +367,14 @@ type OrderedChildrenOptions struct {
// directories.
//
// Must be initialize with Init before first use.
+//
+// +stateify savable
type OrderedChildren struct {
// Can children be modified by user syscalls? It set to false, interface
// methods that would modify the children return EPERM. Immutable.
writable bool
- mu sync.RWMutex
+ mu sync.RWMutex `state:"nosave"`
order slotList
set map[string]*slot
}
@@ -484,6 +501,7 @@ func (o *OrderedChildren) RmDir(ctx context.Context, name string, child *vfs.Den
return o.Unlink(ctx, name, child)
}
+// +stateify savable
type renameAcrossDifferentImplementationsError struct{}
func (renameAcrossDifferentImplementationsError) Error() string {
@@ -542,6 +560,8 @@ func (o *OrderedChildren) nthLocked(i int64) *slot {
}
// InodeSymlink partially implements Inode interface for symlinks.
+//
+// +stateify savable
type InodeSymlink struct {
InodeNotDirectory
}
@@ -615,6 +635,8 @@ func (s *StaticDirectory) DecRef(context.Context) {
}
// AlwaysValid partially implements kernfs.inodeDynamicLookup.
+//
+// +stateify savable
type AlwaysValid struct{}
// Valid implements kernfs.inodeDynamicLookup.Valid.
@@ -624,6 +646,8 @@ func (*AlwaysValid) Valid(context.Context) bool {
// InodeNoStatFS partially implements the Inode interface, where the client
// filesystem doesn't support statfs(2).
+//
+// +stateify savable
type InodeNoStatFS struct{}
// StatFS implements Inode.StatFS.
diff --git a/pkg/sentry/fsimpl/kernfs/kernfs.go b/pkg/sentry/fsimpl/kernfs/kernfs.go
index 14bf43ede..96dfb03c7 100644
--- a/pkg/sentry/fsimpl/kernfs/kernfs.go
+++ b/pkg/sentry/fsimpl/kernfs/kernfs.go
@@ -66,10 +66,12 @@ import (
// Filesystem mostly implements vfs.FilesystemImpl for a generic in-memory
// filesystem. Concrete implementations are expected to embed this in their own
// Filesystem type.
+//
+// +stateify savable
type Filesystem struct {
vfsfs vfs.Filesystem
- droppedDentriesMu sync.Mutex
+ droppedDentriesMu sync.Mutex `state:"nosave"`
// droppedDentries is a list of dentries waiting to be DecRef()ed. This is
// used to defer dentry destruction until mu can be acquired for
@@ -97,7 +99,7 @@ type Filesystem struct {
// defer fs.mu.RUnlock()
// ...
// fs.deferDecRef(dentry)
- mu sync.RWMutex
+ mu sync.RWMutex `state:"nosave"`
// nextInoMinusOne is used to to allocate inode numbers on this
// filesystem. Must be accessed by atomic operations.
@@ -160,6 +162,8 @@ const (
// to, and child dentries hold a reference on their parent.
//
// Must be initialized by Init prior to first use.
+//
+// +stateify savable
type Dentry struct {
DentryRefs
@@ -173,7 +177,7 @@ type Dentry struct {
name string
// dirMu protects children and the names of child Dentries.
- dirMu sync.Mutex
+ dirMu sync.Mutex `state:"nosave"`
children map[string]*Dentry
inode Inode
diff --git a/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go b/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go
index 31cf0f33c..f42662d2d 100644
--- a/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go
+++ b/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go
@@ -105,6 +105,337 @@ func (x *DynamicBytesFD) StateLoad(m state.Source) {
m.Load(4, &x.inode)
}
+func (x *SeekEndConfig) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.SeekEndConfig"
+}
+
+func (x *SeekEndConfig) StateFields() []string {
+ return nil
+}
+
+func (x *GenericDirectoryFDOptions) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.GenericDirectoryFDOptions"
+}
+
+func (x *GenericDirectoryFDOptions) StateFields() []string {
+ return []string{
+ "SeekEnd",
+ }
+}
+
+func (x *GenericDirectoryFDOptions) beforeSave() {}
+
+func (x *GenericDirectoryFDOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.SeekEnd)
+}
+
+func (x *GenericDirectoryFDOptions) afterLoad() {}
+
+func (x *GenericDirectoryFDOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.SeekEnd)
+}
+
+func (x *GenericDirectoryFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.GenericDirectoryFD"
+}
+
+func (x *GenericDirectoryFD) StateFields() []string {
+ return []string{
+ "FileDescriptionDefaultImpl",
+ "DirectoryFileDescriptionDefaultImpl",
+ "LockFD",
+ "seekEnd",
+ "vfsfd",
+ "children",
+ "off",
+ }
+}
+
+func (x *GenericDirectoryFD) beforeSave() {}
+
+func (x *GenericDirectoryFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.FileDescriptionDefaultImpl)
+ m.Save(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+ m.Save(3, &x.seekEnd)
+ m.Save(4, &x.vfsfd)
+ m.Save(5, &x.children)
+ m.Save(6, &x.off)
+}
+
+func (x *GenericDirectoryFD) afterLoad() {}
+
+func (x *GenericDirectoryFD) StateLoad(m state.Source) {
+ m.Load(0, &x.FileDescriptionDefaultImpl)
+ m.Load(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+ m.Load(3, &x.seekEnd)
+ m.Load(4, &x.vfsfd)
+ m.Load(5, &x.children)
+ m.Load(6, &x.off)
+}
+
+func (x *InodeNoopRefCount) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeNoopRefCount"
+}
+
+func (x *InodeNoopRefCount) StateFields() []string {
+ return []string{}
+}
+
+func (x *InodeNoopRefCount) beforeSave() {}
+
+func (x *InodeNoopRefCount) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *InodeNoopRefCount) afterLoad() {}
+
+func (x *InodeNoopRefCount) StateLoad(m state.Source) {
+}
+
+func (x *InodeDirectoryNoNewChildren) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeDirectoryNoNewChildren"
+}
+
+func (x *InodeDirectoryNoNewChildren) StateFields() []string {
+ return []string{}
+}
+
+func (x *InodeDirectoryNoNewChildren) beforeSave() {}
+
+func (x *InodeDirectoryNoNewChildren) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *InodeDirectoryNoNewChildren) afterLoad() {}
+
+func (x *InodeDirectoryNoNewChildren) StateLoad(m state.Source) {
+}
+
+func (x *InodeNotDirectory) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeNotDirectory"
+}
+
+func (x *InodeNotDirectory) StateFields() []string {
+ return []string{}
+}
+
+func (x *InodeNotDirectory) beforeSave() {}
+
+func (x *InodeNotDirectory) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *InodeNotDirectory) afterLoad() {}
+
+func (x *InodeNotDirectory) StateLoad(m state.Source) {
+}
+
+func (x *InodeNoDynamicLookup) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeNoDynamicLookup"
+}
+
+func (x *InodeNoDynamicLookup) StateFields() []string {
+ return []string{}
+}
+
+func (x *InodeNoDynamicLookup) beforeSave() {}
+
+func (x *InodeNoDynamicLookup) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *InodeNoDynamicLookup) afterLoad() {}
+
+func (x *InodeNoDynamicLookup) StateLoad(m state.Source) {
+}
+
+func (x *InodeNotSymlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeNotSymlink"
+}
+
+func (x *InodeNotSymlink) StateFields() []string {
+ return []string{}
+}
+
+func (x *InodeNotSymlink) beforeSave() {}
+
+func (x *InodeNotSymlink) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *InodeNotSymlink) afterLoad() {}
+
+func (x *InodeNotSymlink) StateLoad(m state.Source) {
+}
+
+func (x *InodeAttrs) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeAttrs"
+}
+
+func (x *InodeAttrs) StateFields() []string {
+ return []string{
+ "devMajor",
+ "devMinor",
+ "ino",
+ "mode",
+ "uid",
+ "gid",
+ "nlink",
+ }
+}
+
+func (x *InodeAttrs) beforeSave() {}
+
+func (x *InodeAttrs) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.devMajor)
+ m.Save(1, &x.devMinor)
+ m.Save(2, &x.ino)
+ m.Save(3, &x.mode)
+ m.Save(4, &x.uid)
+ m.Save(5, &x.gid)
+ m.Save(6, &x.nlink)
+}
+
+func (x *InodeAttrs) afterLoad() {}
+
+func (x *InodeAttrs) StateLoad(m state.Source) {
+ m.Load(0, &x.devMajor)
+ m.Load(1, &x.devMinor)
+ m.Load(2, &x.ino)
+ m.Load(3, &x.mode)
+ m.Load(4, &x.uid)
+ m.Load(5, &x.gid)
+ m.Load(6, &x.nlink)
+}
+
+func (x *slot) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.slot"
+}
+
+func (x *slot) StateFields() []string {
+ return []string{
+ "Name",
+ "Dentry",
+ "slotEntry",
+ }
+}
+
+func (x *slot) beforeSave() {}
+
+func (x *slot) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Name)
+ m.Save(1, &x.Dentry)
+ m.Save(2, &x.slotEntry)
+}
+
+func (x *slot) afterLoad() {}
+
+func (x *slot) StateLoad(m state.Source) {
+ m.Load(0, &x.Name)
+ m.Load(1, &x.Dentry)
+ m.Load(2, &x.slotEntry)
+}
+
+func (x *OrderedChildrenOptions) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.OrderedChildrenOptions"
+}
+
+func (x *OrderedChildrenOptions) StateFields() []string {
+ return []string{
+ "Writable",
+ }
+}
+
+func (x *OrderedChildrenOptions) beforeSave() {}
+
+func (x *OrderedChildrenOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Writable)
+}
+
+func (x *OrderedChildrenOptions) afterLoad() {}
+
+func (x *OrderedChildrenOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Writable)
+}
+
+func (x *OrderedChildren) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.OrderedChildren"
+}
+
+func (x *OrderedChildren) StateFields() []string {
+ return []string{
+ "writable",
+ "order",
+ "set",
+ }
+}
+
+func (x *OrderedChildren) beforeSave() {}
+
+func (x *OrderedChildren) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.writable)
+ m.Save(1, &x.order)
+ m.Save(2, &x.set)
+}
+
+func (x *OrderedChildren) afterLoad() {}
+
+func (x *OrderedChildren) StateLoad(m state.Source) {
+ m.Load(0, &x.writable)
+ m.Load(1, &x.order)
+ m.Load(2, &x.set)
+}
+
+func (x *renameAcrossDifferentImplementationsError) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.renameAcrossDifferentImplementationsError"
+}
+
+func (x *renameAcrossDifferentImplementationsError) StateFields() []string {
+ return []string{}
+}
+
+func (x *renameAcrossDifferentImplementationsError) beforeSave() {}
+
+func (x *renameAcrossDifferentImplementationsError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *renameAcrossDifferentImplementationsError) afterLoad() {}
+
+func (x *renameAcrossDifferentImplementationsError) StateLoad(m state.Source) {
+}
+
+func (x *InodeSymlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeSymlink"
+}
+
+func (x *InodeSymlink) StateFields() []string {
+ return []string{
+ "InodeNotDirectory",
+ }
+}
+
+func (x *InodeSymlink) beforeSave() {}
+
+func (x *InodeSymlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeNotDirectory)
+}
+
+func (x *InodeSymlink) afterLoad() {}
+
+func (x *InodeSymlink) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeNotDirectory)
+}
+
func (x *StaticDirectory) StateTypeName() string {
return "pkg/sentry/fsimpl/kernfs.StaticDirectory"
}
@@ -152,6 +483,114 @@ func (x *StaticDirectory) StateLoad(m state.Source) {
m.Load(8, &x.fdOpts)
}
+func (x *AlwaysValid) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.AlwaysValid"
+}
+
+func (x *AlwaysValid) StateFields() []string {
+ return []string{}
+}
+
+func (x *AlwaysValid) beforeSave() {}
+
+func (x *AlwaysValid) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *AlwaysValid) afterLoad() {}
+
+func (x *AlwaysValid) StateLoad(m state.Source) {
+}
+
+func (x *InodeNoStatFS) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.InodeNoStatFS"
+}
+
+func (x *InodeNoStatFS) StateFields() []string {
+ return []string{}
+}
+
+func (x *InodeNoStatFS) beforeSave() {}
+
+func (x *InodeNoStatFS) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *InodeNoStatFS) afterLoad() {}
+
+func (x *InodeNoStatFS) StateLoad(m state.Source) {
+}
+
+func (x *Filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.Filesystem"
+}
+
+func (x *Filesystem) StateFields() []string {
+ return []string{
+ "vfsfs",
+ "droppedDentries",
+ "nextInoMinusOne",
+ }
+}
+
+func (x *Filesystem) beforeSave() {}
+
+func (x *Filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfs)
+ m.Save(1, &x.droppedDentries)
+ m.Save(2, &x.nextInoMinusOne)
+}
+
+func (x *Filesystem) afterLoad() {}
+
+func (x *Filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfs)
+ m.Load(1, &x.droppedDentries)
+ m.Load(2, &x.nextInoMinusOne)
+}
+
+func (x *Dentry) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.Dentry"
+}
+
+func (x *Dentry) StateFields() []string {
+ return []string{
+ "DentryRefs",
+ "vfsd",
+ "flags",
+ "parent",
+ "name",
+ "children",
+ "inode",
+ }
+}
+
+func (x *Dentry) beforeSave() {}
+
+func (x *Dentry) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.DentryRefs)
+ m.Save(1, &x.vfsd)
+ m.Save(2, &x.flags)
+ m.Save(3, &x.parent)
+ m.Save(4, &x.name)
+ m.Save(5, &x.children)
+ m.Save(6, &x.inode)
+}
+
+func (x *Dentry) afterLoad() {}
+
+func (x *Dentry) StateLoad(m state.Source) {
+ m.Load(0, &x.DentryRefs)
+ m.Load(1, &x.vfsd)
+ m.Load(2, &x.flags)
+ m.Load(3, &x.parent)
+ m.Load(4, &x.name)
+ m.Load(5, &x.children)
+ m.Load(6, &x.inode)
+}
+
func (x *slotList) StateTypeName() string {
return "pkg/sentry/fsimpl/kernfs.slotList"
}
@@ -227,6 +666,41 @@ func (x *StaticDirectoryRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *StaticSymlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.StaticSymlink"
+}
+
+func (x *StaticSymlink) StateFields() []string {
+ return []string{
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeSymlink",
+ "InodeNoStatFS",
+ "target",
+ }
+}
+
+func (x *StaticSymlink) beforeSave() {}
+
+func (x *StaticSymlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeAttrs)
+ m.Save(1, &x.InodeNoopRefCount)
+ m.Save(2, &x.InodeSymlink)
+ m.Save(3, &x.InodeNoStatFS)
+ m.Save(4, &x.target)
+}
+
+func (x *StaticSymlink) afterLoad() {}
+
+func (x *StaticSymlink) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeAttrs)
+ m.Load(1, &x.InodeNoopRefCount)
+ m.Load(2, &x.InodeSymlink)
+ m.Load(3, &x.InodeNoStatFS)
+ m.Load(4, &x.target)
+}
+
func (x *syntheticDirectory) StateTypeName() string {
return "pkg/sentry/fsimpl/kernfs.syntheticDirectory"
}
@@ -272,9 +746,28 @@ func init() {
state.Register((*DentryRefs)(nil))
state.Register((*DynamicBytesFile)(nil))
state.Register((*DynamicBytesFD)(nil))
+ state.Register((*SeekEndConfig)(nil))
+ state.Register((*GenericDirectoryFDOptions)(nil))
+ state.Register((*GenericDirectoryFD)(nil))
+ state.Register((*InodeNoopRefCount)(nil))
+ state.Register((*InodeDirectoryNoNewChildren)(nil))
+ state.Register((*InodeNotDirectory)(nil))
+ state.Register((*InodeNoDynamicLookup)(nil))
+ state.Register((*InodeNotSymlink)(nil))
+ state.Register((*InodeAttrs)(nil))
+ state.Register((*slot)(nil))
+ state.Register((*OrderedChildrenOptions)(nil))
+ state.Register((*OrderedChildren)(nil))
+ state.Register((*renameAcrossDifferentImplementationsError)(nil))
+ state.Register((*InodeSymlink)(nil))
state.Register((*StaticDirectory)(nil))
+ state.Register((*AlwaysValid)(nil))
+ state.Register((*InodeNoStatFS)(nil))
+ state.Register((*Filesystem)(nil))
+ state.Register((*Dentry)(nil))
state.Register((*slotList)(nil))
state.Register((*slotEntry)(nil))
state.Register((*StaticDirectoryRefs)(nil))
+ state.Register((*StaticSymlink)(nil))
state.Register((*syntheticDirectory)(nil))
}
diff --git a/pkg/sentry/fsimpl/kernfs/symlink.go b/pkg/sentry/fsimpl/kernfs/symlink.go
index 443121c99..58a93eaac 100644
--- a/pkg/sentry/fsimpl/kernfs/symlink.go
+++ b/pkg/sentry/fsimpl/kernfs/symlink.go
@@ -24,6 +24,8 @@ import (
// StaticSymlink provides an Inode implementation for symlinks that point to
// a immutable target.
+//
+// +stateify savable
type StaticSymlink struct {
InodeAttrs
InodeNoopRefCount
diff --git a/pkg/sentry/fsimpl/overlay/directory.go b/pkg/sentry/fsimpl/overlay/directory.go
index 7ab42e71e..aea599460 100644
--- a/pkg/sentry/fsimpl/overlay/directory.go
+++ b/pkg/sentry/fsimpl/overlay/directory.go
@@ -100,12 +100,13 @@ func (d *dentry) collectWhiteoutsForRmdirLocked(ctx context.Context) (map[string
return whiteouts, readdirErr
}
+// +stateify savable
type directoryFD struct {
fileDescription
vfs.DirectoryFileDescriptionDefaultImpl
vfs.DentryMetadataFileDescriptionImpl
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
off int64
dirents []vfs.Dirent
}
diff --git a/pkg/sentry/fsimpl/overlay/non_directory.go b/pkg/sentry/fsimpl/overlay/non_directory.go
index 6e04705c7..50b4a50f1 100644
--- a/pkg/sentry/fsimpl/overlay/non_directory.go
+++ b/pkg/sentry/fsimpl/overlay/non_directory.go
@@ -39,6 +39,7 @@ func (d *dentry) readlink(ctx context.Context) (string, error) {
})
}
+// +stateify savable
type nonDirectoryFD struct {
fileDescription
@@ -47,7 +48,7 @@ type nonDirectoryFD struct {
// fileDescription.dentry().upperVD. cachedFlags is the last known value of
// cachedFD.StatusFlags(). copiedUp, cachedFD, and cachedFlags are
// protected by mu.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
copiedUp bool
cachedFD *vfs.FileDescription
cachedFlags uint32
diff --git a/pkg/sentry/fsimpl/overlay/overlay.go b/pkg/sentry/fsimpl/overlay/overlay.go
index d0d26185e..b03fa9121 100644
--- a/pkg/sentry/fsimpl/overlay/overlay.go
+++ b/pkg/sentry/fsimpl/overlay/overlay.go
@@ -51,6 +51,8 @@ import (
const Name = "overlay"
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
// Name implements vfs.FilesystemType.Name.
@@ -60,6 +62,8 @@ func (FilesystemType) Name() string {
// FilesystemOptions may be passed as vfs.GetFilesystemOptions.InternalData to
// FilesystemType.GetFilesystem.
+//
+// +stateify savable
type FilesystemOptions struct {
// Callers passing FilesystemOptions to
// overlay.FilesystemType.GetFilesystem() are responsible for ensuring that
@@ -76,6 +80,8 @@ type FilesystemOptions struct {
}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
vfsfs vfs.Filesystem
@@ -98,7 +104,7 @@ type filesystem struct {
// renameMu synchronizes renaming with non-renaming operations in order to
// ensure consistent lock ordering between dentry.dirMu in different
// dentries.
- renameMu sync.RWMutex
+ renameMu sync.RWMutex `state:"nosave"`
// lastDirIno is the last inode number assigned to a directory. lastDirIno
// is accessed using atomic memory operations.
@@ -367,6 +373,8 @@ func (fs *filesystem) newDirIno() uint64 {
}
// dentry implements vfs.DentryImpl.
+//
+// +stateify savable
type dentry struct {
vfsd vfs.Dentry
@@ -399,7 +407,7 @@ type dentry struct {
// and dirents (if not nil) is a cache of dirents as returned by
// directoryFDs representing this directory. children is protected by
// dirMu.
- dirMu sync.Mutex
+ dirMu sync.Mutex `state:"nosave"`
children map[string]*dentry
dirents []vfs.Dirent
@@ -409,7 +417,7 @@ type dentry struct {
// If !upperVD.Ok(), it can transition to a valid vfs.VirtualDentry (i.e.
// be copied up) with copyMu locked for writing; otherwise, it is
// immutable. lowerVDs is always immutable.
- copyMu sync.RWMutex
+ copyMu sync.RWMutex `state:"nosave"`
upperVD vfs.VirtualDentry
lowerVDs []vfs.VirtualDentry
@@ -652,6 +660,8 @@ func (d *dentry) updateAfterSetStatLocked(opts *vfs.SetStatOptions) {
// fileDescription is embedded by overlay implementations of
// vfs.FileDescriptionImpl.
+//
+// +stateify savable
type fileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/overlay/overlay_state_autogen.go b/pkg/sentry/fsimpl/overlay/overlay_state_autogen.go
index 0c184964f..5fd2dc37e 100644
--- a/pkg/sentry/fsimpl/overlay/overlay_state_autogen.go
+++ b/pkg/sentry/fsimpl/overlay/overlay_state_autogen.go
@@ -1,3 +1,285 @@
// automatically generated by stateify.
package overlay
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *directoryFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.directoryFD"
+}
+
+func (x *directoryFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "DirectoryFileDescriptionDefaultImpl",
+ "DentryMetadataFileDescriptionImpl",
+ "off",
+ "dirents",
+ }
+}
+
+func (x *directoryFD) beforeSave() {}
+
+func (x *directoryFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Save(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Save(3, &x.off)
+ m.Save(4, &x.dirents)
+}
+
+func (x *directoryFD) afterLoad() {}
+
+func (x *directoryFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Load(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Load(3, &x.off)
+ m.Load(4, &x.dirents)
+}
+
+func (x *nonDirectoryFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.nonDirectoryFD"
+}
+
+func (x *nonDirectoryFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "copiedUp",
+ "cachedFD",
+ "cachedFlags",
+ }
+}
+
+func (x *nonDirectoryFD) beforeSave() {}
+
+func (x *nonDirectoryFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.copiedUp)
+ m.Save(2, &x.cachedFD)
+ m.Save(3, &x.cachedFlags)
+}
+
+func (x *nonDirectoryFD) afterLoad() {}
+
+func (x *nonDirectoryFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.copiedUp)
+ m.Load(2, &x.cachedFD)
+ m.Load(3, &x.cachedFlags)
+}
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *FilesystemOptions) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.FilesystemOptions"
+}
+
+func (x *FilesystemOptions) StateFields() []string {
+ return []string{
+ "UpperRoot",
+ "LowerRoots",
+ }
+}
+
+func (x *FilesystemOptions) beforeSave() {}
+
+func (x *FilesystemOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.UpperRoot)
+ m.Save(1, &x.LowerRoots)
+}
+
+func (x *FilesystemOptions) afterLoad() {}
+
+func (x *FilesystemOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.UpperRoot)
+ m.Load(1, &x.LowerRoots)
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "vfsfs",
+ "opts",
+ "creds",
+ "dirDevMinor",
+ "lowerDevMinors",
+ "lastDirIno",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfs)
+ m.Save(1, &x.opts)
+ m.Save(2, &x.creds)
+ m.Save(3, &x.dirDevMinor)
+ m.Save(4, &x.lowerDevMinors)
+ m.Save(5, &x.lastDirIno)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfs)
+ m.Load(1, &x.opts)
+ m.Load(2, &x.creds)
+ m.Load(3, &x.dirDevMinor)
+ m.Load(4, &x.lowerDevMinors)
+ m.Load(5, &x.lastDirIno)
+}
+
+func (x *dentry) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.dentry"
+}
+
+func (x *dentry) StateFields() []string {
+ return []string{
+ "vfsd",
+ "refs",
+ "fs",
+ "mode",
+ "uid",
+ "gid",
+ "copiedUp",
+ "parent",
+ "name",
+ "children",
+ "dirents",
+ "upperVD",
+ "lowerVDs",
+ "inlineLowerVDs",
+ "devMajor",
+ "devMinor",
+ "ino",
+ "mapsMu",
+ "lowerMappings",
+ "dataMu",
+ "wrappedMappable",
+ "isMappable",
+ "locks",
+ }
+}
+
+func (x *dentry) beforeSave() {}
+
+func (x *dentry) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsd)
+ m.Save(1, &x.refs)
+ m.Save(2, &x.fs)
+ m.Save(3, &x.mode)
+ m.Save(4, &x.uid)
+ m.Save(5, &x.gid)
+ m.Save(6, &x.copiedUp)
+ m.Save(7, &x.parent)
+ m.Save(8, &x.name)
+ m.Save(9, &x.children)
+ m.Save(10, &x.dirents)
+ m.Save(11, &x.upperVD)
+ m.Save(12, &x.lowerVDs)
+ m.Save(13, &x.inlineLowerVDs)
+ m.Save(14, &x.devMajor)
+ m.Save(15, &x.devMinor)
+ m.Save(16, &x.ino)
+ m.Save(17, &x.mapsMu)
+ m.Save(18, &x.lowerMappings)
+ m.Save(19, &x.dataMu)
+ m.Save(20, &x.wrappedMappable)
+ m.Save(21, &x.isMappable)
+ m.Save(22, &x.locks)
+}
+
+func (x *dentry) afterLoad() {}
+
+func (x *dentry) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsd)
+ m.Load(1, &x.refs)
+ m.Load(2, &x.fs)
+ m.Load(3, &x.mode)
+ m.Load(4, &x.uid)
+ m.Load(5, &x.gid)
+ m.Load(6, &x.copiedUp)
+ m.Load(7, &x.parent)
+ m.Load(8, &x.name)
+ m.Load(9, &x.children)
+ m.Load(10, &x.dirents)
+ m.Load(11, &x.upperVD)
+ m.Load(12, &x.lowerVDs)
+ m.Load(13, &x.inlineLowerVDs)
+ m.Load(14, &x.devMajor)
+ m.Load(15, &x.devMinor)
+ m.Load(16, &x.ino)
+ m.Load(17, &x.mapsMu)
+ m.Load(18, &x.lowerMappings)
+ m.Load(19, &x.dataMu)
+ m.Load(20, &x.wrappedMappable)
+ m.Load(21, &x.isMappable)
+ m.Load(22, &x.locks)
+}
+
+func (x *fileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/overlay.fileDescription"
+}
+
+func (x *fileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ }
+}
+
+func (x *fileDescription) beforeSave() {}
+
+func (x *fileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+}
+
+func (x *fileDescription) afterLoad() {}
+
+func (x *fileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+}
+
+func init() {
+ state.Register((*directoryFD)(nil))
+ state.Register((*nonDirectoryFD)(nil))
+ state.Register((*FilesystemType)(nil))
+ state.Register((*FilesystemOptions)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*dentry)(nil))
+ state.Register((*fileDescription)(nil))
+}
diff --git a/pkg/sentry/fsimpl/pipefs/pipefs.go b/pkg/sentry/fsimpl/pipefs/pipefs.go
index 33e247578..4e2da4810 100644
--- a/pkg/sentry/fsimpl/pipefs/pipefs.go
+++ b/pkg/sentry/fsimpl/pipefs/pipefs.go
@@ -31,6 +31,7 @@ import (
"gvisor.dev/gvisor/pkg/usermem"
)
+// +stateify savable
type filesystemType struct{}
// Name implements vfs.FilesystemType.Name.
@@ -43,6 +44,7 @@ func (filesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.VirtualFile
panic("pipefs.filesystemType.GetFilesystem should never be called")
}
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
@@ -76,6 +78,8 @@ func (fs *filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDe
}
// inode implements kernfs.Inode.
+//
+// +stateify savable
type inode struct {
kernfs.InodeNotDirectory
kernfs.InodeNotSymlink
diff --git a/pkg/sentry/fsimpl/pipefs/pipefs_state_autogen.go b/pkg/sentry/fsimpl/pipefs/pipefs_state_autogen.go
index e3e3887cd..bdb899396 100644
--- a/pkg/sentry/fsimpl/pipefs/pipefs_state_autogen.go
+++ b/pkg/sentry/fsimpl/pipefs/pipefs_state_autogen.go
@@ -1,3 +1,105 @@
// automatically generated by stateify.
package pipefs
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *filesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/pipefs.filesystemType"
+}
+
+func (x *filesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *filesystemType) beforeSave() {}
+
+func (x *filesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *filesystemType) afterLoad() {}
+
+func (x *filesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/pipefs.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *inode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/pipefs.inode"
+}
+
+func (x *inode) StateFields() []string {
+ return []string{
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ "InodeNoopRefCount",
+ "locks",
+ "pipe",
+ "ino",
+ "uid",
+ "gid",
+ "ctime",
+ }
+}
+
+func (x *inode) beforeSave() {}
+
+func (x *inode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeNotDirectory)
+ m.Save(1, &x.InodeNotSymlink)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.locks)
+ m.Save(4, &x.pipe)
+ m.Save(5, &x.ino)
+ m.Save(6, &x.uid)
+ m.Save(7, &x.gid)
+ m.Save(8, &x.ctime)
+}
+
+func (x *inode) afterLoad() {}
+
+func (x *inode) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeNotDirectory)
+ m.Load(1, &x.InodeNotSymlink)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.locks)
+ m.Load(4, &x.pipe)
+ m.Load(5, &x.ino)
+ m.Load(6, &x.uid)
+ m.Load(7, &x.gid)
+ m.Load(8, &x.ctime)
+}
+
+func init() {
+ state.Register((*filesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*inode)(nil))
+}
diff --git a/pkg/sentry/fsimpl/proc/filesystem.go b/pkg/sentry/fsimpl/proc/filesystem.go
index 03b5941b9..05d7948ea 100644
--- a/pkg/sentry/fsimpl/proc/filesystem.go
+++ b/pkg/sentry/fsimpl/proc/filesystem.go
@@ -41,6 +41,7 @@ func (FilesystemType) Name() string {
return Name
}
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
@@ -84,6 +85,8 @@ func (fs *filesystem) Release(ctx context.Context) {
// dynamicInode is an overfitted interface for common Inodes with
// dynamicByteSource types used in procfs.
+//
+// +stateify savable
type dynamicInode interface {
kernfs.Inode
vfs.DynamicBytesSource
@@ -99,6 +102,7 @@ func (fs *filesystem) newDentry(creds *auth.Credentials, ino uint64, perm linux.
return d
}
+// +stateify savable
type staticFile struct {
kernfs.DynamicBytesFile
vfs.StaticData
@@ -118,10 +122,13 @@ func newStaticDir(creds *auth.Credentials, devMajor, devMinor uint32, ino uint64
// InternalData contains internal data passed in to the procfs mount via
// vfs.GetFilesystemOptions.InternalData.
+//
+// +stateify savable
type InternalData struct {
Cgroups map[string]string
}
+// +stateify savable
type implStatFS struct{}
// StatFS implements kernfs.Inode.StatFS.
diff --git a/pkg/sentry/fsimpl/proc/proc_state_autogen.go b/pkg/sentry/fsimpl/proc/proc_state_autogen.go
index 60a5644f3..3eea5708c 100644
--- a/pkg/sentry/fsimpl/proc/proc_state_autogen.go
+++ b/pkg/sentry/fsimpl/proc/proc_state_autogen.go
@@ -71,6 +71,100 @@ func (x *FilesystemType) afterLoad() {}
func (x *FilesystemType) StateLoad(m state.Source) {
}
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *staticFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.staticFile"
+}
+
+func (x *staticFile) StateFields() []string {
+ return []string{
+ "DynamicBytesFile",
+ "StaticData",
+ }
+}
+
+func (x *staticFile) beforeSave() {}
+
+func (x *staticFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.DynamicBytesFile)
+ m.Save(1, &x.StaticData)
+}
+
+func (x *staticFile) afterLoad() {}
+
+func (x *staticFile) StateLoad(m state.Source) {
+ m.Load(0, &x.DynamicBytesFile)
+ m.Load(1, &x.StaticData)
+}
+
+func (x *InternalData) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.InternalData"
+}
+
+func (x *InternalData) StateFields() []string {
+ return []string{
+ "Cgroups",
+ }
+}
+
+func (x *InternalData) beforeSave() {}
+
+func (x *InternalData) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Cgroups)
+}
+
+func (x *InternalData) afterLoad() {}
+
+func (x *InternalData) StateLoad(m state.Source) {
+ m.Load(0, &x.Cgroups)
+}
+
+func (x *implStatFS) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.implStatFS"
+}
+
+func (x *implStatFS) StateFields() []string {
+ return []string{}
+}
+
+func (x *implStatFS) beforeSave() {}
+
+func (x *implStatFS) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *implStatFS) afterLoad() {}
+
+func (x *implStatFS) StateLoad(m state.Source) {
+}
+
func (x *subtasksInode) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.subtasksInode"
}
@@ -127,6 +221,32 @@ func (x *subtasksInode) StateLoad(m state.Source) {
m.Load(11, &x.cgroupControllers)
}
+func (x *subtasksFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.subtasksFD"
+}
+
+func (x *subtasksFD) StateFields() []string {
+ return []string{
+ "GenericDirectoryFD",
+ "task",
+ }
+}
+
+func (x *subtasksFD) beforeSave() {}
+
+func (x *subtasksFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.GenericDirectoryFD)
+ m.Save(1, &x.task)
+}
+
+func (x *subtasksFD) afterLoad() {}
+
+func (x *subtasksFD) StateLoad(m state.Source) {
+ m.Load(0, &x.GenericDirectoryFD)
+ m.Load(1, &x.task)
+}
+
func (x *subtasksInodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.subtasksInodeRefs"
}
@@ -197,6 +317,64 @@ func (x *taskInode) StateLoad(m state.Source) {
m.Load(8, &x.task)
}
+func (x *taskOwnedInode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.taskOwnedInode"
+}
+
+func (x *taskOwnedInode) StateFields() []string {
+ return []string{
+ "Inode",
+ "owner",
+ }
+}
+
+func (x *taskOwnedInode) beforeSave() {}
+
+func (x *taskOwnedInode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Inode)
+ m.Save(1, &x.owner)
+}
+
+func (x *taskOwnedInode) afterLoad() {}
+
+func (x *taskOwnedInode) StateLoad(m state.Source) {
+ m.Load(0, &x.Inode)
+ m.Load(1, &x.owner)
+}
+
+func (x *fdDir) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.fdDir"
+}
+
+func (x *fdDir) StateFields() []string {
+ return []string{
+ "locks",
+ "fs",
+ "task",
+ "produceSymlink",
+ }
+}
+
+func (x *fdDir) beforeSave() {}
+
+func (x *fdDir) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.locks)
+ m.Save(1, &x.fs)
+ m.Save(2, &x.task)
+ m.Save(3, &x.produceSymlink)
+}
+
+func (x *fdDir) afterLoad() {}
+
+func (x *fdDir) StateLoad(m state.Source) {
+ m.Load(0, &x.locks)
+ m.Load(1, &x.fs)
+ m.Load(2, &x.task)
+ m.Load(3, &x.produceSymlink)
+}
+
func (x *fdDirInode) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.fdDirInode"
}
@@ -766,6 +944,102 @@ func (x *mountsData) StateLoad(m state.Source) {
m.Load(1, &x.task)
}
+func (x *namespaceSymlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.namespaceSymlink"
+}
+
+func (x *namespaceSymlink) StateFields() []string {
+ return []string{
+ "StaticSymlink",
+ "task",
+ }
+}
+
+func (x *namespaceSymlink) beforeSave() {}
+
+func (x *namespaceSymlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.StaticSymlink)
+ m.Save(1, &x.task)
+}
+
+func (x *namespaceSymlink) afterLoad() {}
+
+func (x *namespaceSymlink) StateLoad(m state.Source) {
+ m.Load(0, &x.StaticSymlink)
+ m.Load(1, &x.task)
+}
+
+func (x *namespaceInode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.namespaceInode"
+}
+
+func (x *namespaceInode) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ "locks",
+ }
+}
+
+func (x *namespaceInode) beforeSave() {}
+
+func (x *namespaceInode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.InodeNotDirectory)
+ m.Save(4, &x.InodeNotSymlink)
+ m.Save(5, &x.locks)
+}
+
+func (x *namespaceInode) afterLoad() {}
+
+func (x *namespaceInode) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.InodeNotDirectory)
+ m.Load(4, &x.InodeNotSymlink)
+ m.Load(5, &x.locks)
+}
+
+func (x *namespaceFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.namespaceFD"
+}
+
+func (x *namespaceFD) StateFields() []string {
+ return []string{
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ "vfsfd",
+ "inode",
+ }
+}
+
+func (x *namespaceFD) beforeSave() {}
+
+func (x *namespaceFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.FileDescriptionDefaultImpl)
+ m.Save(1, &x.LockFD)
+ m.Save(2, &x.vfsfd)
+ m.Save(3, &x.inode)
+}
+
+func (x *namespaceFD) afterLoad() {}
+
+func (x *namespaceFD) StateLoad(m state.Source) {
+ m.Load(0, &x.FileDescriptionDefaultImpl)
+ m.Load(1, &x.LockFD)
+ m.Load(2, &x.vfsfd)
+ m.Load(3, &x.inode)
+}
+
func (x *taskInodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.taskInodeRefs"
}
@@ -971,6 +1245,32 @@ func (x *netSnmpData) StateLoad(m state.Source) {
m.Load(1, &x.stack)
}
+func (x *snmpLine) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.snmpLine"
+}
+
+func (x *snmpLine) StateFields() []string {
+ return []string{
+ "prefix",
+ "header",
+ }
+}
+
+func (x *snmpLine) beforeSave() {}
+
+func (x *snmpLine) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.prefix)
+ m.Save(1, &x.header)
+}
+
+func (x *snmpLine) afterLoad() {}
+
+func (x *snmpLine) StateLoad(m state.Source) {
+ m.Load(0, &x.prefix)
+ m.Load(1, &x.header)
+}
+
func (x *netRouteData) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.netRouteData"
}
@@ -1082,6 +1382,175 @@ func (x *tasksInode) StateLoad(m state.Source) {
m.Load(12, &x.cgroupControllers)
}
+func (x *staticFileSetStat) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.staticFileSetStat"
+}
+
+func (x *staticFileSetStat) StateFields() []string {
+ return []string{
+ "dynamicBytesFileSetAttr",
+ "StaticData",
+ }
+}
+
+func (x *staticFileSetStat) beforeSave() {}
+
+func (x *staticFileSetStat) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.dynamicBytesFileSetAttr)
+ m.Save(1, &x.StaticData)
+}
+
+func (x *staticFileSetStat) afterLoad() {}
+
+func (x *staticFileSetStat) StateLoad(m state.Source) {
+ m.Load(0, &x.dynamicBytesFileSetAttr)
+ m.Load(1, &x.StaticData)
+}
+
+func (x *selfSymlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.selfSymlink"
+}
+
+func (x *selfSymlink) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeSymlink",
+ "pidns",
+ }
+}
+
+func (x *selfSymlink) beforeSave() {}
+
+func (x *selfSymlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.InodeSymlink)
+ m.Save(4, &x.pidns)
+}
+
+func (x *selfSymlink) afterLoad() {}
+
+func (x *selfSymlink) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.InodeSymlink)
+ m.Load(4, &x.pidns)
+}
+
+func (x *threadSelfSymlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.threadSelfSymlink"
+}
+
+func (x *threadSelfSymlink) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeSymlink",
+ "pidns",
+ }
+}
+
+func (x *threadSelfSymlink) beforeSave() {}
+
+func (x *threadSelfSymlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.InodeSymlink)
+ m.Save(4, &x.pidns)
+}
+
+func (x *threadSelfSymlink) afterLoad() {}
+
+func (x *threadSelfSymlink) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.InodeSymlink)
+ m.Load(4, &x.pidns)
+}
+
+func (x *dynamicBytesFileSetAttr) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.dynamicBytesFileSetAttr"
+}
+
+func (x *dynamicBytesFileSetAttr) StateFields() []string {
+ return []string{
+ "DynamicBytesFile",
+ }
+}
+
+func (x *dynamicBytesFileSetAttr) beforeSave() {}
+
+func (x *dynamicBytesFileSetAttr) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.DynamicBytesFile)
+}
+
+func (x *dynamicBytesFileSetAttr) afterLoad() {}
+
+func (x *dynamicBytesFileSetAttr) StateLoad(m state.Source) {
+ m.Load(0, &x.DynamicBytesFile)
+}
+
+func (x *cpuStats) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.cpuStats"
+}
+
+func (x *cpuStats) StateFields() []string {
+ return []string{
+ "user",
+ "nice",
+ "system",
+ "idle",
+ "ioWait",
+ "irq",
+ "softirq",
+ "steal",
+ "guest",
+ "guestNice",
+ }
+}
+
+func (x *cpuStats) beforeSave() {}
+
+func (x *cpuStats) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.user)
+ m.Save(1, &x.nice)
+ m.Save(2, &x.system)
+ m.Save(3, &x.idle)
+ m.Save(4, &x.ioWait)
+ m.Save(5, &x.irq)
+ m.Save(6, &x.softirq)
+ m.Save(7, &x.steal)
+ m.Save(8, &x.guest)
+ m.Save(9, &x.guestNice)
+}
+
+func (x *cpuStats) afterLoad() {}
+
+func (x *cpuStats) StateLoad(m state.Source) {
+ m.Load(0, &x.user)
+ m.Load(1, &x.nice)
+ m.Load(2, &x.system)
+ m.Load(3, &x.idle)
+ m.Load(4, &x.ioWait)
+ m.Load(5, &x.irq)
+ m.Load(6, &x.softirq)
+ m.Load(7, &x.steal)
+ m.Load(8, &x.guest)
+ m.Load(9, &x.guestNice)
+}
+
func (x *statData) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.statData"
}
@@ -1243,6 +1712,14 @@ func (x *tasksInodeRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *tcpMemDir) StateTypeName() string {
+ return "pkg/sentry/fsimpl/proc.tcpMemDir"
+}
+
+func (x *tcpMemDir) StateFields() []string {
+ return nil
+}
+
func (x *mmapMinAddrData) StateTypeName() string {
return "pkg/sentry/fsimpl/proc.mmapMinAddrData"
}
@@ -1409,9 +1886,16 @@ func init() {
state.Register((*fdDirInodeRefs)(nil))
state.Register((*fdInfoDirInodeRefs)(nil))
state.Register((*FilesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*staticFile)(nil))
+ state.Register((*InternalData)(nil))
+ state.Register((*implStatFS)(nil))
state.Register((*subtasksInode)(nil))
+ state.Register((*subtasksFD)(nil))
state.Register((*subtasksInodeRefs)(nil))
state.Register((*taskInode)(nil))
+ state.Register((*taskOwnedInode)(nil))
+ state.Register((*fdDir)(nil))
state.Register((*fdDirInode)(nil))
state.Register((*fdSymlink)(nil))
state.Register((*fdInfoDirInode)(nil))
@@ -1431,6 +1915,9 @@ func init() {
state.Register((*exeSymlink)(nil))
state.Register((*mountInfoData)(nil))
state.Register((*mountsData)(nil))
+ state.Register((*namespaceSymlink)(nil))
+ state.Register((*namespaceInode)(nil))
+ state.Register((*namespaceFD)(nil))
state.Register((*taskInodeRefs)(nil))
state.Register((*ifinet6)(nil))
state.Register((*netDevData)(nil))
@@ -1439,9 +1926,15 @@ func init() {
state.Register((*netTCP6Data)(nil))
state.Register((*netUDPData)(nil))
state.Register((*netSnmpData)(nil))
+ state.Register((*snmpLine)(nil))
state.Register((*netRouteData)(nil))
state.Register((*netStatData)(nil))
state.Register((*tasksInode)(nil))
+ state.Register((*staticFileSetStat)(nil))
+ state.Register((*selfSymlink)(nil))
+ state.Register((*threadSelfSymlink)(nil))
+ state.Register((*dynamicBytesFileSetAttr)(nil))
+ state.Register((*cpuStats)(nil))
state.Register((*statData)(nil))
state.Register((*loadavgData)(nil))
state.Register((*meminfoData)(nil))
@@ -1449,6 +1942,7 @@ func init() {
state.Register((*versionData)(nil))
state.Register((*filesystemsData)(nil))
state.Register((*tasksInodeRefs)(nil))
+ state.Register((*tcpMemDir)(nil))
state.Register((*mmapMinAddrData)(nil))
state.Register((*hostnameData)(nil))
state.Register((*tcpSackData)(nil))
diff --git a/pkg/sentry/fsimpl/proc/subtasks.go b/pkg/sentry/fsimpl/proc/subtasks.go
index 47dc0ac9a..47ecd941c 100644
--- a/pkg/sentry/fsimpl/proc/subtasks.go
+++ b/pkg/sentry/fsimpl/proc/subtasks.go
@@ -116,6 +116,7 @@ func (i *subtasksInode) IterDirents(ctx context.Context, cb vfs.IterDirentsCallb
return offset, nil
}
+// +stateify savable
type subtasksFD struct {
kernfs.GenericDirectoryFD
diff --git a/pkg/sentry/fsimpl/proc/task.go b/pkg/sentry/fsimpl/proc/task.go
index ae461bb48..1f99183eb 100644
--- a/pkg/sentry/fsimpl/proc/task.go
+++ b/pkg/sentry/fsimpl/proc/task.go
@@ -129,6 +129,8 @@ func (i *taskInode) DecRef(context.Context) {
// taskOwnedInode implements kernfs.Inode and overrides inode owner with task
// effective user and group.
+//
+// +stateify savable
type taskOwnedInode struct {
kernfs.Inode
diff --git a/pkg/sentry/fsimpl/proc/task_fds.go b/pkg/sentry/fsimpl/proc/task_fds.go
index c7104458f..0866cea2b 100644
--- a/pkg/sentry/fsimpl/proc/task_fds.go
+++ b/pkg/sentry/fsimpl/proc/task_fds.go
@@ -51,6 +51,7 @@ func taskFDExists(ctx context.Context, t *kernel.Task, fd int32) bool {
return true
}
+// +stateify savable
type fdDir struct {
locks vfs.FileLocks
diff --git a/pkg/sentry/fsimpl/proc/task_files.go b/pkg/sentry/fsimpl/proc/task_files.go
index feed5bc3f..b81c8279e 100644
--- a/pkg/sentry/fsimpl/proc/task_files.go
+++ b/pkg/sentry/fsimpl/proc/task_files.go
@@ -785,6 +785,7 @@ func (i *mountsData) Generate(ctx context.Context, buf *bytes.Buffer) error {
return nil
}
+// +stateify savable
type namespaceSymlink struct {
kernfs.StaticSymlink
@@ -832,6 +833,8 @@ func (s *namespaceSymlink) Getlink(ctx context.Context, mnt *vfs.Mount) (vfs.Vir
// namespaceInode is a synthetic inode created to represent a namespace in
// /proc/[pid]/ns/*.
+//
+// +stateify savable
type namespaceInode struct {
implStatFS
kernfs.InodeAttrs
@@ -865,6 +868,8 @@ func (i *namespaceInode) Open(ctx context.Context, rp *vfs.ResolvingPath, d *ker
// namespace FD is a synthetic file that represents a namespace in
// /proc/[pid]/ns/*.
+//
+// +stateify savable
type namespaceFD struct {
vfs.FileDescriptionDefaultImpl
vfs.LockFD
diff --git a/pkg/sentry/fsimpl/proc/task_net.go b/pkg/sentry/fsimpl/proc/task_net.go
index 1607eac19..e7f748655 100644
--- a/pkg/sentry/fsimpl/proc/task_net.go
+++ b/pkg/sentry/fsimpl/proc/task_net.go
@@ -616,6 +616,7 @@ type netSnmpData struct {
var _ dynamicInode = (*netSnmpData)(nil)
+// +stateify savable
type snmpLine struct {
prefix string
header string
diff --git a/pkg/sentry/fsimpl/proc/tasks.go b/pkg/sentry/fsimpl/proc/tasks.go
index ad08c3626..d8f5dd509 100644
--- a/pkg/sentry/fsimpl/proc/tasks.go
+++ b/pkg/sentry/fsimpl/proc/tasks.go
@@ -236,6 +236,8 @@ func (i *tasksInode) DecRef(context.Context) {
// staticFileSetStat implements a special static file that allows inode
// attributes to be set. This is to support /proc files that are readonly, but
// allow attributes to be set.
+//
+// +stateify savable
type staticFileSetStat struct {
dynamicBytesFileSetAttr
vfs.StaticData
diff --git a/pkg/sentry/fsimpl/proc/tasks_files.go b/pkg/sentry/fsimpl/proc/tasks_files.go
index 459a8e52e..f268c59b0 100644
--- a/pkg/sentry/fsimpl/proc/tasks_files.go
+++ b/pkg/sentry/fsimpl/proc/tasks_files.go
@@ -31,6 +31,7 @@ import (
"gvisor.dev/gvisor/pkg/usermem"
)
+// +stateify savable
type selfSymlink struct {
implStatFS
kernfs.InodeAttrs
@@ -74,6 +75,7 @@ func (*selfSymlink) SetStat(context.Context, *vfs.Filesystem, *auth.Credentials,
return syserror.EPERM
}
+// +stateify savable
type threadSelfSymlink struct {
implStatFS
kernfs.InodeAttrs
@@ -121,6 +123,8 @@ func (*threadSelfSymlink) SetStat(context.Context, *vfs.Filesystem, *auth.Creden
// dynamicBytesFileSetAttr implements a special file that allows inode
// attributes to be set. This is to support /proc files that are readonly, but
// allow attributes to be set.
+//
+// +stateify savable
type dynamicBytesFileSetAttr struct {
kernfs.DynamicBytesFile
}
@@ -131,6 +135,8 @@ func (d *dynamicBytesFileSetAttr) SetStat(ctx context.Context, fs *vfs.Filesyste
}
// cpuStats contains the breakdown of CPU time for /proc/stat.
+//
+// +stateify savable
type cpuStats struct {
// user is time spent in userspace tasks with non-positive niceness.
user uint64
diff --git a/pkg/sentry/fsimpl/proc/tasks_sys.go b/pkg/sentry/fsimpl/proc/tasks_sys.go
index a3ffbb15e..3312b0418 100644
--- a/pkg/sentry/fsimpl/proc/tasks_sys.go
+++ b/pkg/sentry/fsimpl/proc/tasks_sys.go
@@ -31,6 +31,7 @@ import (
"gvisor.dev/gvisor/pkg/usermem"
)
+// +stateify savable
type tcpMemDir int
const (
diff --git a/pkg/sentry/fsimpl/signalfd/signalfd.go b/pkg/sentry/fsimpl/signalfd/signalfd.go
index 3c02af8c9..bf11b425a 100644
--- a/pkg/sentry/fsimpl/signalfd/signalfd.go
+++ b/pkg/sentry/fsimpl/signalfd/signalfd.go
@@ -27,6 +27,8 @@ import (
)
// SignalFileDescription implements vfs.FileDescriptionImpl for signal fds.
+//
+// +stateify savable
type SignalFileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
@@ -43,7 +45,7 @@ type SignalFileDescription struct {
target *kernel.Task
// mu protects mask.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
// mask is the signal mask. Protected by mu.
mask linux.SignalSet
diff --git a/pkg/sentry/fsimpl/signalfd/signalfd_state_autogen.go b/pkg/sentry/fsimpl/signalfd/signalfd_state_autogen.go
index c3d9b2ffb..acd2ff5b4 100644
--- a/pkg/sentry/fsimpl/signalfd/signalfd_state_autogen.go
+++ b/pkg/sentry/fsimpl/signalfd/signalfd_state_autogen.go
@@ -1,3 +1,49 @@
// automatically generated by stateify.
package signalfd
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *SignalFileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/signalfd.SignalFileDescription"
+}
+
+func (x *SignalFileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "DentryMetadataFileDescriptionImpl",
+ "NoLockFD",
+ "target",
+ "mask",
+ }
+}
+
+func (x *SignalFileDescription) beforeSave() {}
+
+func (x *SignalFileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Save(3, &x.NoLockFD)
+ m.Save(4, &x.target)
+ m.Save(5, &x.mask)
+}
+
+func (x *SignalFileDescription) afterLoad() {}
+
+func (x *SignalFileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Load(3, &x.NoLockFD)
+ m.Load(4, &x.target)
+ m.Load(5, &x.mask)
+}
+
+func init() {
+ state.Register((*SignalFileDescription)(nil))
+}
diff --git a/pkg/sentry/fsimpl/sockfs/sockfs.go b/pkg/sentry/fsimpl/sockfs/sockfs.go
index f1e75e277..29e5371d6 100644
--- a/pkg/sentry/fsimpl/sockfs/sockfs.go
+++ b/pkg/sentry/fsimpl/sockfs/sockfs.go
@@ -28,6 +28,8 @@ import (
)
// filesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type filesystemType struct{}
// GetFilesystem implements vfs.FilesystemType.GetFilesystem.
@@ -44,6 +46,7 @@ func (filesystemType) Name() string {
return "sockfs"
}
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
@@ -80,6 +83,8 @@ func (fs *filesystem) PrependPath(ctx context.Context, vfsroot, vd vfs.VirtualDe
}
// inode implements kernfs.Inode.
+//
+// +stateify savable
type inode struct {
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
diff --git a/pkg/sentry/fsimpl/sockfs/sockfs_state_autogen.go b/pkg/sentry/fsimpl/sockfs/sockfs_state_autogen.go
index 8d5b85e2c..bbc868a48 100644
--- a/pkg/sentry/fsimpl/sockfs/sockfs_state_autogen.go
+++ b/pkg/sentry/fsimpl/sockfs/sockfs_state_autogen.go
@@ -1,3 +1,90 @@
// automatically generated by stateify.
package sockfs
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *filesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sockfs.filesystemType"
+}
+
+func (x *filesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *filesystemType) beforeSave() {}
+
+func (x *filesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *filesystemType) afterLoad() {}
+
+func (x *filesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sockfs.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *inode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sockfs.inode"
+}
+
+func (x *inode) StateFields() []string {
+ return []string{
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ }
+}
+
+func (x *inode) beforeSave() {}
+
+func (x *inode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeAttrs)
+ m.Save(1, &x.InodeNoopRefCount)
+ m.Save(2, &x.InodeNotDirectory)
+ m.Save(3, &x.InodeNotSymlink)
+}
+
+func (x *inode) afterLoad() {}
+
+func (x *inode) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeAttrs)
+ m.Load(1, &x.InodeNoopRefCount)
+ m.Load(2, &x.InodeNotDirectory)
+ m.Load(3, &x.InodeNotSymlink)
+}
+
+func init() {
+ state.Register((*filesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*inode)(nil))
+}
diff --git a/pkg/sentry/fsimpl/sys/kcov.go b/pkg/sentry/fsimpl/sys/kcov.go
index 252f75d26..b75d70ae6 100644
--- a/pkg/sentry/fsimpl/sys/kcov.go
+++ b/pkg/sentry/fsimpl/sys/kcov.go
@@ -36,6 +36,8 @@ func (fs *filesystem) newKcovFile(ctx context.Context, creds *auth.Credentials)
}
// kcovInode implements kernfs.Inode.
+//
+// +stateify savable
type kcovInode struct {
kernfs.InodeAttrs
kernfs.InodeNoopRefCount
@@ -63,6 +65,7 @@ func (i *kcovInode) Open(ctx context.Context, rp *vfs.ResolvingPath, d *kernfs.D
return &fd.vfsfd, nil
}
+// +stateify savable
type kcovFD struct {
vfs.FileDescriptionDefaultImpl
vfs.NoLockFD
diff --git a/pkg/sentry/fsimpl/sys/sys.go b/pkg/sentry/fsimpl/sys/sys.go
index 8bcefc103..1568c581f 100644
--- a/pkg/sentry/fsimpl/sys/sys.go
+++ b/pkg/sentry/fsimpl/sys/sys.go
@@ -34,9 +34,13 @@ const Name = "sysfs"
const defaultSysDirMode = linux.FileMode(0755)
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
kernfs.Filesystem
@@ -117,6 +121,8 @@ func (fs *filesystem) Release(ctx context.Context) {
}
// dir implements kernfs.Inode.
+//
+// +stateify savable
type dir struct {
dirRefs
kernfs.InodeAttrs
@@ -169,6 +175,8 @@ func (d *dir) StatFS(ctx context.Context, fs *vfs.Filesystem) (linux.Statfs, err
}
// cpuFile implements kernfs.Inode.
+//
+// +stateify savable
type cpuFile struct {
implStatFS
kernfs.DynamicBytesFile
@@ -190,6 +198,7 @@ func (fs *filesystem) newCPUFile(creds *auth.Credentials, maxCores uint, mode li
return d
}
+// +stateify savable
type implStatFS struct{}
// StatFS implements kernfs.Inode.StatFS.
diff --git a/pkg/sentry/fsimpl/sys/sys_state_autogen.go b/pkg/sentry/fsimpl/sys/sys_state_autogen.go
index 347a46318..14d4efce9 100644
--- a/pkg/sentry/fsimpl/sys/sys_state_autogen.go
+++ b/pkg/sentry/fsimpl/sys/sys_state_autogen.go
@@ -29,6 +29,220 @@ func (x *dirRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *kcovInode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.kcovInode"
+}
+
+func (x *kcovInode) StateFields() []string {
+ return []string{
+ "InodeAttrs",
+ "InodeNoopRefCount",
+ "InodeNotDirectory",
+ "InodeNotSymlink",
+ "implStatFS",
+ }
+}
+
+func (x *kcovInode) beforeSave() {}
+
+func (x *kcovInode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeAttrs)
+ m.Save(1, &x.InodeNoopRefCount)
+ m.Save(2, &x.InodeNotDirectory)
+ m.Save(3, &x.InodeNotSymlink)
+ m.Save(4, &x.implStatFS)
+}
+
+func (x *kcovInode) afterLoad() {}
+
+func (x *kcovInode) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeAttrs)
+ m.Load(1, &x.InodeNoopRefCount)
+ m.Load(2, &x.InodeNotDirectory)
+ m.Load(3, &x.InodeNotSymlink)
+ m.Load(4, &x.implStatFS)
+}
+
+func (x *kcovFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.kcovFD"
+}
+
+func (x *kcovFD) StateFields() []string {
+ return []string{
+ "FileDescriptionDefaultImpl",
+ "NoLockFD",
+ "vfsfd",
+ "inode",
+ "kcov",
+ }
+}
+
+func (x *kcovFD) beforeSave() {}
+
+func (x *kcovFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.FileDescriptionDefaultImpl)
+ m.Save(1, &x.NoLockFD)
+ m.Save(2, &x.vfsfd)
+ m.Save(3, &x.inode)
+ m.Save(4, &x.kcov)
+}
+
+func (x *kcovFD) afterLoad() {}
+
+func (x *kcovFD) StateLoad(m state.Source) {
+ m.Load(0, &x.FileDescriptionDefaultImpl)
+ m.Load(1, &x.NoLockFD)
+ m.Load(2, &x.vfsfd)
+ m.Load(3, &x.inode)
+ m.Load(4, &x.kcov)
+}
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "Filesystem",
+ "devMinor",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Filesystem)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.Filesystem)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *dir) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.dir"
+}
+
+func (x *dir) StateFields() []string {
+ return []string{
+ "dirRefs",
+ "InodeAttrs",
+ "InodeNoDynamicLookup",
+ "InodeNotSymlink",
+ "InodeDirectoryNoNewChildren",
+ "OrderedChildren",
+ "locks",
+ "dentry",
+ }
+}
+
+func (x *dir) beforeSave() {}
+
+func (x *dir) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.dirRefs)
+ m.Save(1, &x.InodeAttrs)
+ m.Save(2, &x.InodeNoDynamicLookup)
+ m.Save(3, &x.InodeNotSymlink)
+ m.Save(4, &x.InodeDirectoryNoNewChildren)
+ m.Save(5, &x.OrderedChildren)
+ m.Save(6, &x.locks)
+ m.Save(7, &x.dentry)
+}
+
+func (x *dir) afterLoad() {}
+
+func (x *dir) StateLoad(m state.Source) {
+ m.Load(0, &x.dirRefs)
+ m.Load(1, &x.InodeAttrs)
+ m.Load(2, &x.InodeNoDynamicLookup)
+ m.Load(3, &x.InodeNotSymlink)
+ m.Load(4, &x.InodeDirectoryNoNewChildren)
+ m.Load(5, &x.OrderedChildren)
+ m.Load(6, &x.locks)
+ m.Load(7, &x.dentry)
+}
+
+func (x *cpuFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.cpuFile"
+}
+
+func (x *cpuFile) StateFields() []string {
+ return []string{
+ "implStatFS",
+ "DynamicBytesFile",
+ "maxCores",
+ }
+}
+
+func (x *cpuFile) beforeSave() {}
+
+func (x *cpuFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.implStatFS)
+ m.Save(1, &x.DynamicBytesFile)
+ m.Save(2, &x.maxCores)
+}
+
+func (x *cpuFile) afterLoad() {}
+
+func (x *cpuFile) StateLoad(m state.Source) {
+ m.Load(0, &x.implStatFS)
+ m.Load(1, &x.DynamicBytesFile)
+ m.Load(2, &x.maxCores)
+}
+
+func (x *implStatFS) StateTypeName() string {
+ return "pkg/sentry/fsimpl/sys.implStatFS"
+}
+
+func (x *implStatFS) StateFields() []string {
+ return []string{}
+}
+
+func (x *implStatFS) beforeSave() {}
+
+func (x *implStatFS) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *implStatFS) afterLoad() {}
+
+func (x *implStatFS) StateLoad(m state.Source) {
+}
+
func init() {
state.Register((*dirRefs)(nil))
+ state.Register((*kcovInode)(nil))
+ state.Register((*kcovFD)(nil))
+ state.Register((*FilesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*dir)(nil))
+ state.Register((*cpuFile)(nil))
+ state.Register((*implStatFS)(nil))
}
diff --git a/pkg/sentry/fsimpl/timerfd/timerfd.go b/pkg/sentry/fsimpl/timerfd/timerfd.go
index ac8a4e3bb..8853c8ad2 100644
--- a/pkg/sentry/fsimpl/timerfd/timerfd.go
+++ b/pkg/sentry/fsimpl/timerfd/timerfd.go
@@ -28,6 +28,8 @@ import (
// TimerFileDescription implements vfs.FileDescriptionImpl for timer fds. It also
// implements ktime.TimerListener.
+//
+// +stateify savable
type TimerFileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/timerfd/timerfd_state_autogen.go b/pkg/sentry/fsimpl/timerfd/timerfd_state_autogen.go
index 4e5976369..722153ff8 100644
--- a/pkg/sentry/fsimpl/timerfd/timerfd_state_autogen.go
+++ b/pkg/sentry/fsimpl/timerfd/timerfd_state_autogen.go
@@ -1,3 +1,52 @@
// automatically generated by stateify.
package timerfd
+
+import (
+ "gvisor.dev/gvisor/pkg/state"
+)
+
+func (x *TimerFileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/timerfd.TimerFileDescription"
+}
+
+func (x *TimerFileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "DentryMetadataFileDescriptionImpl",
+ "NoLockFD",
+ "events",
+ "timer",
+ "val",
+ }
+}
+
+func (x *TimerFileDescription) beforeSave() {}
+
+func (x *TimerFileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Save(3, &x.NoLockFD)
+ m.Save(4, &x.events)
+ m.Save(5, &x.timer)
+ m.Save(6, &x.val)
+}
+
+func (x *TimerFileDescription) afterLoad() {}
+
+func (x *TimerFileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.DentryMetadataFileDescriptionImpl)
+ m.Load(3, &x.NoLockFD)
+ m.Load(4, &x.events)
+ m.Load(5, &x.timer)
+ m.Load(6, &x.val)
+}
+
+func init() {
+ state.Register((*TimerFileDescription)(nil))
+}
diff --git a/pkg/sentry/fsimpl/tmpfs/device_file.go b/pkg/sentry/fsimpl/tmpfs/device_file.go
index ac54d420d..9129d35b7 100644
--- a/pkg/sentry/fsimpl/tmpfs/device_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/device_file.go
@@ -22,6 +22,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
+// +stateify savable
type deviceFile struct {
inode inode
kind vfs.DeviceKind
diff --git a/pkg/sentry/fsimpl/tmpfs/directory.go b/pkg/sentry/fsimpl/tmpfs/directory.go
index 070c75e68..e90669cf0 100644
--- a/pkg/sentry/fsimpl/tmpfs/directory.go
+++ b/pkg/sentry/fsimpl/tmpfs/directory.go
@@ -25,6 +25,7 @@ import (
"gvisor.dev/gvisor/pkg/syserror"
)
+// +stateify savable
type directory struct {
// Since directories can't be hard-linked, each directory can only be
// associated with a single dentry, which we can store in the directory
@@ -44,7 +45,7 @@ type directory struct {
// (with inode == nil) that represent the iteration position of
// directoryFDs. childList is used to support directoryFD.IterDirents()
// efficiently. childList is protected by iterMu.
- iterMu sync.Mutex
+ iterMu sync.Mutex `state:"nosave"`
childList dentryList
}
@@ -86,6 +87,7 @@ func (dir *directory) mayDelete(creds *auth.Credentials, child *dentry) error {
return vfs.CheckDeleteSticky(creds, linux.FileMode(atomic.LoadUint32(&dir.inode.mode)), auth.KUID(atomic.LoadUint32(&child.inode.uid)))
}
+// +stateify savable
type directoryFD struct {
fileDescription
vfs.DirectoryFileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/tmpfs/named_pipe.go b/pkg/sentry/fsimpl/tmpfs/named_pipe.go
index 5b0471ff4..d772db9e9 100644
--- a/pkg/sentry/fsimpl/tmpfs/named_pipe.go
+++ b/pkg/sentry/fsimpl/tmpfs/named_pipe.go
@@ -21,6 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/usermem"
)
+// +stateify savable
type namedPipe struct {
inode inode
diff --git a/pkg/sentry/fsimpl/tmpfs/regular_file.go b/pkg/sentry/fsimpl/tmpfs/regular_file.go
index b8699d064..a199eb33d 100644
--- a/pkg/sentry/fsimpl/tmpfs/regular_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/regular_file.go
@@ -36,6 +36,8 @@ import (
)
// regularFile is a regular (=S_IFREG) tmpfs file.
+//
+// +stateify savable
type regularFile struct {
inode inode
@@ -66,7 +68,7 @@ type regularFile struct {
writableMappingPages uint64
// dataMu protects the fields below.
- dataMu sync.RWMutex
+ dataMu sync.RWMutex `state:"nosave"`
// data maps offsets into the file to offsets into memFile that store
// the file's data.
@@ -325,13 +327,14 @@ func (*regularFile) InvalidateUnsavable(context.Context) error {
return nil
}
+// +stateify savable
type regularFileFD struct {
fileDescription
// off is the file offset. off is accessed using atomic memory operations.
// offMu serializes operations that may mutate off.
off int64
- offMu sync.Mutex
+ offMu sync.Mutex `state:"nosave"`
}
// Release implements vfs.FileDescriptionImpl.Release.
diff --git a/pkg/sentry/fsimpl/tmpfs/socket_file.go b/pkg/sentry/fsimpl/tmpfs/socket_file.go
index 3ed650474..5699d5975 100644
--- a/pkg/sentry/fsimpl/tmpfs/socket_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/socket_file.go
@@ -21,6 +21,8 @@ import (
)
// socketFile is a socket (=S_IFSOCK) tmpfs file.
+//
+// +stateify savable
type socketFile struct {
inode inode
ep transport.BoundEndpoint
diff --git a/pkg/sentry/fsimpl/tmpfs/symlink.go b/pkg/sentry/fsimpl/tmpfs/symlink.go
index b0de5fabe..a102a2ee2 100644
--- a/pkg/sentry/fsimpl/tmpfs/symlink.go
+++ b/pkg/sentry/fsimpl/tmpfs/symlink.go
@@ -19,6 +19,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
+// +stateify savable
type symlink struct {
inode inode
target string // immutable
diff --git a/pkg/sentry/fsimpl/tmpfs/tmpfs.go b/pkg/sentry/fsimpl/tmpfs/tmpfs.go
index 4658e1533..cefec8fde 100644
--- a/pkg/sentry/fsimpl/tmpfs/tmpfs.go
+++ b/pkg/sentry/fsimpl/tmpfs/tmpfs.go
@@ -51,9 +51,13 @@ import (
const Name = "tmpfs"
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
vfsfs vfs.Filesystem
@@ -67,7 +71,7 @@ type filesystem struct {
devMinor uint32
// mu serializes changes to the Dentry tree.
- mu sync.RWMutex
+ mu sync.RWMutex `state:"nosave"`
nextInoMinusOne uint64 // accessed using atomic memory operations
}
@@ -78,6 +82,8 @@ func (FilesystemType) Name() string {
}
// FilesystemOpts is used to pass configuration data to tmpfs.
+//
+// +stateify savable
type FilesystemOpts struct {
// RootFileType is the FileType of the filesystem root. Valid values
// are: S_IFDIR, S_IFREG, and S_IFLNK. Defaults to S_IFDIR.
@@ -221,6 +227,8 @@ var globalStatfs = linux.Statfs{
}
// dentry implements vfs.DentryImpl.
+//
+// +stateify savable
type dentry struct {
vfsd vfs.Dentry
@@ -300,6 +308,8 @@ func (d *dentry) Watches() *vfs.Watches {
func (d *dentry) OnZeroWatches(context.Context) {}
// inode represents a filesystem object.
+//
+// +stateify savable
type inode struct {
// fs is the owning filesystem. fs is immutable.
fs *filesystem
@@ -316,12 +326,12 @@ type inode struct {
// Inode metadata. Writing multiple fields atomically requires holding
// mu, othewise atomic operations can be used.
- mu sync.Mutex
- mode uint32 // file type and mode
- nlink uint32 // protected by filesystem.mu instead of inode.mu
- uid uint32 // auth.KUID, but stored as raw uint32 for sync/atomic
- gid uint32 // auth.KGID, but ...
- ino uint64 // immutable
+ mu sync.Mutex `state:"nosave"`
+ mode uint32 // file type and mode
+ nlink uint32 // protected by filesystem.mu instead of inode.mu
+ uid uint32 // auth.KUID, but stored as raw uint32 for sync/atomic
+ gid uint32 // auth.KGID, but ...
+ ino uint64 // immutable
// Linux's tmpfs has no concept of btime.
atime int64 // nanoseconds
@@ -668,6 +678,8 @@ func (i *inode) checkXattrPermissions(creds *auth.Credentials, name string, ats
// fileDescription is embedded by tmpfs implementations of
// vfs.FileDescriptionImpl.
+//
+// +stateify savable
type fileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go b/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go
index d88136656..4252b95e6 100644
--- a/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go
+++ b/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go
@@ -58,6 +58,105 @@ func (x *dentryEntry) StateLoad(m state.Source) {
m.Load(1, &x.prev)
}
+func (x *deviceFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.deviceFile"
+}
+
+func (x *deviceFile) StateFields() []string {
+ return []string{
+ "inode",
+ "kind",
+ "major",
+ "minor",
+ }
+}
+
+func (x *deviceFile) beforeSave() {}
+
+func (x *deviceFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.kind)
+ m.Save(2, &x.major)
+ m.Save(3, &x.minor)
+}
+
+func (x *deviceFile) afterLoad() {}
+
+func (x *deviceFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.kind)
+ m.Load(2, &x.major)
+ m.Load(3, &x.minor)
+}
+
+func (x *directory) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.directory"
+}
+
+func (x *directory) StateFields() []string {
+ return []string{
+ "dentry",
+ "inode",
+ "childMap",
+ "numChildren",
+ "childList",
+ }
+}
+
+func (x *directory) beforeSave() {}
+
+func (x *directory) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.dentry)
+ m.Save(1, &x.inode)
+ m.Save(2, &x.childMap)
+ m.Save(3, &x.numChildren)
+ m.Save(4, &x.childList)
+}
+
+func (x *directory) afterLoad() {}
+
+func (x *directory) StateLoad(m state.Source) {
+ m.Load(0, &x.dentry)
+ m.Load(1, &x.inode)
+ m.Load(2, &x.childMap)
+ m.Load(3, &x.numChildren)
+ m.Load(4, &x.childList)
+}
+
+func (x *directoryFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.directoryFD"
+}
+
+func (x *directoryFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "DirectoryFileDescriptionDefaultImpl",
+ "iter",
+ "off",
+ }
+}
+
+func (x *directoryFD) beforeSave() {}
+
+func (x *directoryFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Save(2, &x.iter)
+ m.Save(3, &x.off)
+}
+
+func (x *directoryFD) afterLoad() {}
+
+func (x *directoryFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Load(2, &x.iter)
+ m.Load(3, &x.off)
+}
+
func (x *inodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/tmpfs.inodeRefs"
}
@@ -81,8 +180,379 @@ func (x *inodeRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *namedPipe) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.namedPipe"
+}
+
+func (x *namedPipe) StateFields() []string {
+ return []string{
+ "inode",
+ "pipe",
+ }
+}
+
+func (x *namedPipe) beforeSave() {}
+
+func (x *namedPipe) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.pipe)
+}
+
+func (x *namedPipe) afterLoad() {}
+
+func (x *namedPipe) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.pipe)
+}
+
+func (x *regularFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.regularFile"
+}
+
+func (x *regularFile) StateFields() []string {
+ return []string{
+ "inode",
+ "memFile",
+ "memoryUsageKind",
+ "mappings",
+ "writableMappingPages",
+ "data",
+ "seals",
+ "size",
+ }
+}
+
+func (x *regularFile) beforeSave() {}
+
+func (x *regularFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.memFile)
+ m.Save(2, &x.memoryUsageKind)
+ m.Save(3, &x.mappings)
+ m.Save(4, &x.writableMappingPages)
+ m.Save(5, &x.data)
+ m.Save(6, &x.seals)
+ m.Save(7, &x.size)
+}
+
+func (x *regularFile) afterLoad() {}
+
+func (x *regularFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.memFile)
+ m.Load(2, &x.memoryUsageKind)
+ m.Load(3, &x.mappings)
+ m.Load(4, &x.writableMappingPages)
+ m.Load(5, &x.data)
+ m.Load(6, &x.seals)
+ m.Load(7, &x.size)
+}
+
+func (x *regularFileFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.regularFileFD"
+}
+
+func (x *regularFileFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "off",
+ }
+}
+
+func (x *regularFileFD) beforeSave() {}
+
+func (x *regularFileFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.off)
+}
+
+func (x *regularFileFD) afterLoad() {}
+
+func (x *regularFileFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.off)
+}
+
+func (x *socketFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.socketFile"
+}
+
+func (x *socketFile) StateFields() []string {
+ return []string{
+ "inode",
+ "ep",
+ }
+}
+
+func (x *socketFile) beforeSave() {}
+
+func (x *socketFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.ep)
+}
+
+func (x *socketFile) afterLoad() {}
+
+func (x *socketFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.ep)
+}
+
+func (x *symlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.symlink"
+}
+
+func (x *symlink) StateFields() []string {
+ return []string{
+ "inode",
+ "target",
+ }
+}
+
+func (x *symlink) beforeSave() {}
+
+func (x *symlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.target)
+}
+
+func (x *symlink) afterLoad() {}
+
+func (x *symlink) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.target)
+}
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "vfsfs",
+ "memFile",
+ "clock",
+ "devMinor",
+ "nextInoMinusOne",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfs)
+ m.Save(1, &x.memFile)
+ m.Save(2, &x.clock)
+ m.Save(3, &x.devMinor)
+ m.Save(4, &x.nextInoMinusOne)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfs)
+ m.Load(1, &x.memFile)
+ m.Load(2, &x.clock)
+ m.Load(3, &x.devMinor)
+ m.Load(4, &x.nextInoMinusOne)
+}
+
+func (x *FilesystemOpts) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.FilesystemOpts"
+}
+
+func (x *FilesystemOpts) StateFields() []string {
+ return []string{
+ "RootFileType",
+ "RootSymlinkTarget",
+ "FilesystemType",
+ }
+}
+
+func (x *FilesystemOpts) beforeSave() {}
+
+func (x *FilesystemOpts) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.RootFileType)
+ m.Save(1, &x.RootSymlinkTarget)
+ m.Save(2, &x.FilesystemType)
+}
+
+func (x *FilesystemOpts) afterLoad() {}
+
+func (x *FilesystemOpts) StateLoad(m state.Source) {
+ m.Load(0, &x.RootFileType)
+ m.Load(1, &x.RootSymlinkTarget)
+ m.Load(2, &x.FilesystemType)
+}
+
+func (x *dentry) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.dentry"
+}
+
+func (x *dentry) StateFields() []string {
+ return []string{
+ "vfsd",
+ "parent",
+ "name",
+ "dentryEntry",
+ "inode",
+ }
+}
+
+func (x *dentry) beforeSave() {}
+
+func (x *dentry) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsd)
+ m.Save(1, &x.parent)
+ m.Save(2, &x.name)
+ m.Save(3, &x.dentryEntry)
+ m.Save(4, &x.inode)
+}
+
+func (x *dentry) afterLoad() {}
+
+func (x *dentry) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsd)
+ m.Load(1, &x.parent)
+ m.Load(2, &x.name)
+ m.Load(3, &x.dentryEntry)
+ m.Load(4, &x.inode)
+}
+
+func (x *inode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.inode"
+}
+
+func (x *inode) StateFields() []string {
+ return []string{
+ "fs",
+ "refs",
+ "xattrs",
+ "mode",
+ "nlink",
+ "uid",
+ "gid",
+ "ino",
+ "atime",
+ "ctime",
+ "mtime",
+ "locks",
+ "watches",
+ "impl",
+ }
+}
+
+func (x *inode) beforeSave() {}
+
+func (x *inode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fs)
+ m.Save(1, &x.refs)
+ m.Save(2, &x.xattrs)
+ m.Save(3, &x.mode)
+ m.Save(4, &x.nlink)
+ m.Save(5, &x.uid)
+ m.Save(6, &x.gid)
+ m.Save(7, &x.ino)
+ m.Save(8, &x.atime)
+ m.Save(9, &x.ctime)
+ m.Save(10, &x.mtime)
+ m.Save(11, &x.locks)
+ m.Save(12, &x.watches)
+ m.Save(13, &x.impl)
+}
+
+func (x *inode) afterLoad() {}
+
+func (x *inode) StateLoad(m state.Source) {
+ m.Load(0, &x.fs)
+ m.Load(1, &x.refs)
+ m.Load(2, &x.xattrs)
+ m.Load(3, &x.mode)
+ m.Load(4, &x.nlink)
+ m.Load(5, &x.uid)
+ m.Load(6, &x.gid)
+ m.Load(7, &x.ino)
+ m.Load(8, &x.atime)
+ m.Load(9, &x.ctime)
+ m.Load(10, &x.mtime)
+ m.Load(11, &x.locks)
+ m.Load(12, &x.watches)
+ m.Load(13, &x.impl)
+}
+
+func (x *fileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.fileDescription"
+}
+
+func (x *fileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ }
+}
+
+func (x *fileDescription) beforeSave() {}
+
+func (x *fileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+}
+
+func (x *fileDescription) afterLoad() {}
+
+func (x *fileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+}
+
func init() {
state.Register((*dentryList)(nil))
state.Register((*dentryEntry)(nil))
+ state.Register((*deviceFile)(nil))
+ state.Register((*directory)(nil))
+ state.Register((*directoryFD)(nil))
state.Register((*inodeRefs)(nil))
+ state.Register((*namedPipe)(nil))
+ state.Register((*regularFile)(nil))
+ state.Register((*regularFileFD)(nil))
+ state.Register((*socketFile)(nil))
+ state.Register((*symlink)(nil))
+ state.Register((*FilesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*FilesystemOpts)(nil))
+ state.Register((*dentry)(nil))
+ state.Register((*inode)(nil))
+ state.Register((*fileDescription)(nil))
}