diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-09-24 17:19:53 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-09-24 17:19:53 +0000 |
commit | 61cc049caaa2317eda73e66f65f82b5099dd2bc2 (patch) | |
tree | 352bfc9c114c181e052a9656be9f3b2acd5f7b33 /pkg/sentry/fsimpl | |
parent | 3102024707dc370e025f1b46fa2be12eade2f9cb (diff) | |
parent | 0a7075f38a4870ded687e117a299ac4996c0673e (diff) |
Merge release-20200914.0-152-g0a7075f38 (automated)
Diffstat (limited to 'pkg/sentry/fsimpl')
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)) } |