summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/kernfs
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs')
-rw-r--r--pkg/sentry/fsimpl/kernfs/fd_impl_util.go8
-rw-r--r--pkg/sentry/fsimpl/kernfs/inode_impl_util.go26
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs.go10
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go493
-rw-r--r--pkg/sentry/fsimpl/kernfs/symlink.go2
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