diff options
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs')
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/fd_impl_util.go | 8 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/inode_impl_util.go | 26 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/kernfs.go | 10 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go | 493 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/symlink.go | 2 |
5 files changed, 534 insertions, 5 deletions
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 |