summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/vfs')
-rw-r--r--pkg/sentry/vfs/anonfs.go5
-rw-r--r--pkg/sentry/vfs/dentry.go2
-rw-r--r--pkg/sentry/vfs/device.go3
-rw-r--r--pkg/sentry/vfs/epoll.go9
-rw-r--r--pkg/sentry/vfs/file_description.go10
-rw-r--r--pkg/sentry/vfs/file_description_impl_util.go28
-rw-r--r--pkg/sentry/vfs/filesystem.go6
-rw-r--r--pkg/sentry/vfs/filesystem_type.go2
-rw-r--r--pkg/sentry/vfs/inotify.go2
-rw-r--r--pkg/sentry/vfs/lock.go2
-rw-r--r--pkg/sentry/vfs/mount.go9
-rw-r--r--pkg/sentry/vfs/mount_unsafe.go11
-rw-r--r--pkg/sentry/vfs/options.go30
-rw-r--r--pkg/sentry/vfs/permissions.go2
-rw-r--r--pkg/sentry/vfs/resolving_path.go5
-rw-r--r--pkg/sentry/vfs/vfs.go2
-rw-r--r--pkg/sentry/vfs/vfs_state_autogen.go1252
17 files changed, 1366 insertions, 14 deletions
diff --git a/pkg/sentry/vfs/anonfs.go b/pkg/sentry/vfs/anonfs.go
index 9c4db3047..bdfd3ca8f 100644
--- a/pkg/sentry/vfs/anonfs.go
+++ b/pkg/sentry/vfs/anonfs.go
@@ -52,6 +52,8 @@ const (
)
// anonFilesystemType implements FilesystemType.
+//
+// +stateify savable
type anonFilesystemType struct{}
// GetFilesystem implements FilesystemType.GetFilesystem.
@@ -69,12 +71,15 @@ func (anonFilesystemType) Name() string {
//
// Since all Dentries in anonFilesystem are non-directories, all FilesystemImpl
// methods that would require an anonDentry to be a directory return ENOTDIR.
+//
+// +stateify savable
type anonFilesystem struct {
vfsfs Filesystem
devMinor uint32
}
+// +stateify savable
type anonDentry struct {
vfsd Dentry
diff --git a/pkg/sentry/vfs/dentry.go b/pkg/sentry/vfs/dentry.go
index a69a5b2f1..320ab7ce1 100644
--- a/pkg/sentry/vfs/dentry.go
+++ b/pkg/sentry/vfs/dentry.go
@@ -89,6 +89,8 @@ func (d *Dentry) Impl() DentryImpl {
// DentryImpl contains implementation details for a Dentry. Implementations of
// DentryImpl should contain their associated Dentry by value as their first
// field.
+//
+// +stateify savable
type DentryImpl interface {
// IncRef increments the Dentry's reference count. A Dentry with a non-zero
// reference count must remain coherent with the state of the filesystem.
diff --git a/pkg/sentry/vfs/device.go b/pkg/sentry/vfs/device.go
index 1e9dffc8f..dde2ad79b 100644
--- a/pkg/sentry/vfs/device.go
+++ b/pkg/sentry/vfs/device.go
@@ -22,6 +22,8 @@ import (
)
// DeviceKind indicates whether a device is a block or character device.
+//
+// +stateify savable
type DeviceKind uint32
const (
@@ -44,6 +46,7 @@ func (kind DeviceKind) String() string {
}
}
+// +stateify savable
type devTuple struct {
kind DeviceKind
major uint32
diff --git a/pkg/sentry/vfs/epoll.go b/pkg/sentry/vfs/epoll.go
index 754e76aec..8f36c3e3b 100644
--- a/pkg/sentry/vfs/epoll.go
+++ b/pkg/sentry/vfs/epoll.go
@@ -27,6 +27,8 @@ import (
var epollCycleMu sync.Mutex
// EpollInstance represents an epoll instance, as described by epoll(7).
+//
+// +stateify savable
type EpollInstance struct {
vfsfd FileDescription
FileDescriptionDefaultImpl
@@ -38,11 +40,11 @@ type EpollInstance struct {
// interest is the set of file descriptors that are registered with the
// EpollInstance for monitoring. interest is protected by interestMu.
- interestMu sync.Mutex
+ interestMu sync.Mutex `state:"nosave"`
interest map[epollInterestKey]*epollInterest
// mu protects fields in registered epollInterests.
- mu sync.Mutex
+ mu sync.Mutex `state:"nosave"`
// ready is the set of file descriptors that may be "ready" for I/O. Note
// that this must be an ordered list, not a map: "If more than maxevents
@@ -55,6 +57,7 @@ type EpollInstance struct {
ready epollInterestList
}
+// +stateify savable
type epollInterestKey struct {
// file is the registered FileDescription. No reference is held on file;
// instead, when the last reference is dropped, FileDescription.DecRef()
@@ -67,6 +70,8 @@ type epollInterestKey struct {
}
// epollInterest represents an EpollInstance's interest in a file descriptor.
+//
+// +stateify savable
type epollInterest struct {
// epoll is the owning EpollInstance. epoll is immutable.
epoll *EpollInstance
diff --git a/pkg/sentry/vfs/file_description.go b/pkg/sentry/vfs/file_description.go
index 73bb36d3e..1eba0270f 100644
--- a/pkg/sentry/vfs/file_description.go
+++ b/pkg/sentry/vfs/file_description.go
@@ -37,11 +37,13 @@ import (
// FileDescription methods require that a reference is held.
//
// FileDescription is analogous to Linux's struct file.
+//
+// +stateify savable
type FileDescription struct {
FileDescriptionRefs
// flagsMu protects statusFlags and asyncHandler below.
- flagsMu sync.Mutex
+ flagsMu sync.Mutex `state:"nosave"`
// statusFlags contains status flags, "initialized by open(2) and possibly
// modified by fcntl()" - fcntl(2). statusFlags can be read using atomic
@@ -56,7 +58,7 @@ type FileDescription struct {
// epolls is the set of epollInterests registered for this FileDescription.
// epolls is protected by epollMu.
- epollMu sync.Mutex
+ epollMu sync.Mutex `state:"nosave"`
epolls map[*epollInterest]struct{}
// vd is the filesystem location at which this FileDescription was opened.
@@ -88,6 +90,8 @@ type FileDescription struct {
}
// FileDescriptionOptions contains options to FileDescription.Init().
+//
+// +stateify savable
type FileDescriptionOptions struct {
// If AllowDirectIO is true, allow O_DIRECT to be set on the file.
AllowDirectIO bool
@@ -451,6 +455,8 @@ type FileDescriptionImpl interface {
}
// Dirent holds the information contained in struct linux_dirent64.
+//
+// +stateify savable
type Dirent struct {
// Name is the filename.
Name string
diff --git a/pkg/sentry/vfs/file_description_impl_util.go b/pkg/sentry/vfs/file_description_impl_util.go
index 78da16bac..48ca9de44 100644
--- a/pkg/sentry/vfs/file_description_impl_util.go
+++ b/pkg/sentry/vfs/file_description_impl_util.go
@@ -42,6 +42,8 @@ import (
// FileDescriptionDefaultImpl may be embedded by implementations of
// FileDescriptionImpl to obtain implementations of many FileDescriptionImpl
// methods with default behavior analogous to Linux's.
+//
+// +stateify savable
type FileDescriptionDefaultImpl struct{}
// OnClose implements FileDescriptionImpl.OnClose analogously to
@@ -166,6 +168,8 @@ func (FileDescriptionDefaultImpl) RemoveXattr(ctx context.Context, name string)
// DirectoryFileDescriptionDefaultImpl may be embedded by implementations of
// FileDescriptionImpl that always represent directories to obtain
// implementations of non-directory I/O methods that return EISDIR.
+//
+// +stateify savable
type DirectoryFileDescriptionDefaultImpl struct{}
// Allocate implements DirectoryFileDescriptionDefaultImpl.Allocate.
@@ -196,6 +200,8 @@ func (DirectoryFileDescriptionDefaultImpl) Write(ctx context.Context, src userme
// DentryMetadataFileDescriptionImpl may be embedded by implementations of
// FileDescriptionImpl for which FileDescriptionOptions.UseDentryMetadata is
// true to obtain implementations of Stat and SetStat that panic.
+//
+// +stateify savable
type DentryMetadataFileDescriptionImpl struct{}
// Stat implements FileDescriptionImpl.Stat.
@@ -210,12 +216,16 @@ func (DentryMetadataFileDescriptionImpl) SetStat(ctx context.Context, opts SetSt
// DynamicBytesSource represents a data source for a
// DynamicBytesFileDescriptionImpl.
+//
+// +stateify savable
type DynamicBytesSource interface {
// Generate writes the file's contents to buf.
Generate(ctx context.Context, buf *bytes.Buffer) error
}
// StaticData implements DynamicBytesSource over a static string.
+//
+// +stateify savable
type StaticData struct {
Data string
}
@@ -242,14 +252,24 @@ type WritableDynamicBytesSource interface {
//
// DynamicBytesFileDescriptionImpl.SetDataSource() must be called before first
// use.
+//
+// +stateify savable
type DynamicBytesFileDescriptionImpl struct {
data DynamicBytesSource // immutable
- mu sync.Mutex // protects the following fields
- buf bytes.Buffer
+ mu sync.Mutex `state:"nosave"` // protects the following fields
+ buf bytes.Buffer `state:".([]byte)"`
off int64
lastRead int64 // offset at which the last Read, PRead, or Seek ended
}
+func (fd *DynamicBytesFileDescriptionImpl) saveBuf() []byte {
+ return fd.buf.Bytes()
+}
+
+func (fd *DynamicBytesFileDescriptionImpl) loadBuf(p []byte) {
+ fd.buf.Write(p)
+}
+
// SetDataSource must be called exactly once on fd before first use.
func (fd *DynamicBytesFileDescriptionImpl) SetDataSource(data DynamicBytesSource) {
fd.data = data
@@ -382,6 +402,8 @@ func GenericConfigureMMap(fd *FileDescription, m memmap.Mappable, opts *memmap.M
// LockFD may be used by most implementations of FileDescriptionImpl.Lock*
// functions. Caller must call Init().
+//
+// +stateify savable
type LockFD struct {
locks *FileLocks
}
@@ -409,6 +431,8 @@ func (fd *LockFD) UnlockBSD(ctx context.Context, uid fslock.UniqueID) error {
// NoLockFD implements Lock*/Unlock* portion of FileDescriptionImpl interface
// returning ENOLCK.
+//
+// +stateify savable
type NoLockFD struct{}
// LockBSD implements vfs.FileDescriptionImpl.LockBSD.
diff --git a/pkg/sentry/vfs/filesystem.go b/pkg/sentry/vfs/filesystem.go
index 7dae4e7e8..c93d94634 100644
--- a/pkg/sentry/vfs/filesystem.go
+++ b/pkg/sentry/vfs/filesystem.go
@@ -506,6 +506,8 @@ type FilesystemImpl interface {
// PrependPathAtVFSRootError is returned by implementations of
// FilesystemImpl.PrependPath() when they encounter the contextual VFS root.
+//
+// +stateify savable
type PrependPathAtVFSRootError struct{}
// Error implements error.Error.
@@ -516,6 +518,8 @@ func (PrependPathAtVFSRootError) Error() string {
// PrependPathAtNonMountRootError is returned by implementations of
// FilesystemImpl.PrependPath() when they encounter an independent ancestor
// Dentry that is not the Mount root.
+//
+// +stateify savable
type PrependPathAtNonMountRootError struct{}
// Error implements error.Error.
@@ -526,6 +530,8 @@ func (PrependPathAtNonMountRootError) Error() string {
// PrependPathSyntheticError is returned by implementations of
// FilesystemImpl.PrependPath() for which prepended names do not represent real
// paths.
+//
+// +stateify savable
type PrependPathSyntheticError struct{}
// Error implements error.Error.
diff --git a/pkg/sentry/vfs/filesystem_type.go b/pkg/sentry/vfs/filesystem_type.go
index 82ae35fdc..bc19db1d5 100644
--- a/pkg/sentry/vfs/filesystem_type.go
+++ b/pkg/sentry/vfs/filesystem_type.go
@@ -55,6 +55,8 @@ type registeredFilesystemType struct {
// RegisterFilesystemTypeOptions contains options to
// VirtualFilesystem.RegisterFilesystem().
+//
+// +stateify savable
type RegisterFilesystemTypeOptions struct {
// AllowUserMount determines whether users are allowed to mount a file system
// of this type, i.e. through mount(2). If AllowUserMount is true, allow calls
diff --git a/pkg/sentry/vfs/inotify.go b/pkg/sentry/vfs/inotify.go
index aff220a61..3f0b8f45b 100644
--- a/pkg/sentry/vfs/inotify.go
+++ b/pkg/sentry/vfs/inotify.go
@@ -37,6 +37,8 @@ const inotifyEventBaseSize = 16
//
// The way events are labelled appears somewhat arbitrary, but they must match
// Linux so that IN_EXCL_UNLINK behaves as it does in Linux.
+//
+// +stateify savable
type EventType uint8
// PathEvent and InodeEvent correspond to FSNOTIFY_EVENT_PATH and
diff --git a/pkg/sentry/vfs/lock.go b/pkg/sentry/vfs/lock.go
index 42666eebf..55783d4eb 100644
--- a/pkg/sentry/vfs/lock.go
+++ b/pkg/sentry/vfs/lock.go
@@ -33,6 +33,8 @@ import (
// Note that in Linux these two types of locks are _not_ cooperative, because
// race and deadlock conditions make merging them prohibitive. We do the same
// and keep them oblivious to each other.
+//
+// +stateify savable
type FileLocks struct {
// bsd is a set of BSD-style advisory file wide locks, see flock(2).
bsd fslock.Locks
diff --git a/pkg/sentry/vfs/mount.go b/pkg/sentry/vfs/mount.go
index 9da09d4c1..dfc3ae6c0 100644
--- a/pkg/sentry/vfs/mount.go
+++ b/pkg/sentry/vfs/mount.go
@@ -65,7 +65,7 @@ type Mount struct {
//
// Invariant: key.parent != nil iff key.point != nil. key.point belongs to
// key.parent.fs.
- key mountKey
+ key mountKey `state:".(VirtualDentry)"`
// ns is the namespace in which this Mount was mounted. ns is protected by
// VirtualFilesystem.mountMu.
@@ -345,6 +345,7 @@ func (vfs *VirtualFilesystem) UmountAt(ctx context.Context, creds *auth.Credenti
return nil
}
+// +stateify savable
type umountRecursiveOptions struct {
// If eager is true, ensure that future calls to Mount.tryIncMountedRef()
// on umounted mounts fail.
@@ -414,7 +415,7 @@ func (vfs *VirtualFilesystem) connectLocked(mnt *Mount, vd VirtualDentry, mntns
}
}
mnt.IncRef() // dropped by callers of umountRecursiveLocked
- mnt.storeKey(vd)
+ mnt.setKey(vd)
if vd.mount.children == nil {
vd.mount.children = make(map[*Mount]struct{})
}
@@ -439,13 +440,13 @@ func (vfs *VirtualFilesystem) connectLocked(mnt *Mount, vd VirtualDentry, mntns
// * vfs.mounts.seq must be in a writer critical section.
// * mnt.parent() != nil.
func (vfs *VirtualFilesystem) disconnectLocked(mnt *Mount) VirtualDentry {
- vd := mnt.loadKey()
+ vd := mnt.getKey()
if checkInvariants {
if vd.mount != nil {
panic("VFS.disconnectLocked called on disconnected mount")
}
}
- mnt.storeKey(VirtualDentry{})
+ mnt.loadKey(VirtualDentry{})
delete(vd.mount.children, mnt)
atomic.AddUint32(&vd.dentry.mounts, math.MaxUint32) // -1
mnt.ns.mountpoints[vd.dentry]--
diff --git a/pkg/sentry/vfs/mount_unsafe.go b/pkg/sentry/vfs/mount_unsafe.go
index da2a2e9c4..b7d122d22 100644
--- a/pkg/sentry/vfs/mount_unsafe.go
+++ b/pkg/sentry/vfs/mount_unsafe.go
@@ -34,6 +34,8 @@ import (
// structurally identical to VirtualDentry, but stores its fields as
// unsafe.Pointer since mutators synchronize with VFS path traversal using
// seqcounts.
+//
+// This is explicitly not savable.
type mountKey struct {
parent unsafe.Pointer // *Mount
point unsafe.Pointer // *Dentry
@@ -47,19 +49,23 @@ func (mnt *Mount) point() *Dentry {
return (*Dentry)(atomic.LoadPointer(&mnt.key.point))
}
-func (mnt *Mount) loadKey() VirtualDentry {
+func (mnt *Mount) getKey() VirtualDentry {
return VirtualDentry{
mount: mnt.parent(),
dentry: mnt.point(),
}
}
+func (mnt *Mount) saveKey() VirtualDentry { return mnt.getKey() }
+
// Invariant: mnt.key.parent == nil. vd.Ok().
-func (mnt *Mount) storeKey(vd VirtualDentry) {
+func (mnt *Mount) setKey(vd VirtualDentry) {
atomic.StorePointer(&mnt.key.parent, unsafe.Pointer(vd.mount))
atomic.StorePointer(&mnt.key.point, unsafe.Pointer(vd.dentry))
}
+func (mnt *Mount) loadKey(vd VirtualDentry) { mnt.setKey(vd) }
+
// mountTable maps (mount parent, mount point) pairs to mounts. It supports
// efficient concurrent lookup, even in the presence of concurrent mutators
// (provided mutation is sufficiently uncommon).
@@ -92,6 +98,7 @@ type mountTable struct {
// length and cap in separate uint32s) for ~free.
size uint64
+ // FIXME(gvisor.dev/issue/1663): Slots need to be saved.
slots unsafe.Pointer `state:"nosave"` // []mountSlot; never nil after Init
}
diff --git a/pkg/sentry/vfs/options.go b/pkg/sentry/vfs/options.go
index 413cfb101..bc79e5ecc 100644
--- a/pkg/sentry/vfs/options.go
+++ b/pkg/sentry/vfs/options.go
@@ -21,6 +21,8 @@ import (
// GetDentryOptions contains options to VirtualFilesystem.GetDentryAt() and
// FilesystemImpl.GetDentryAt().
+//
+// +stateify savable
type GetDentryOptions struct {
// If CheckSearchable is true, FilesystemImpl.GetDentryAt() must check that
// the returned Dentry is a directory for which creds has search
@@ -30,6 +32,8 @@ type GetDentryOptions struct {
// MkdirOptions contains options to VirtualFilesystem.MkdirAt() and
// FilesystemImpl.MkdirAt().
+//
+// +stateify savable
type MkdirOptions struct {
// Mode is the file mode bits for the created directory.
Mode linux.FileMode
@@ -56,6 +60,8 @@ type MkdirOptions struct {
// MknodOptions contains options to VirtualFilesystem.MknodAt() and
// FilesystemImpl.MknodAt().
+//
+// +stateify savable
type MknodOptions struct {
// Mode is the file type and mode bits for the created file.
Mode linux.FileMode
@@ -72,6 +78,8 @@ type MknodOptions struct {
// MountFlags contains flags as specified for mount(2), e.g. MS_NOEXEC.
// MS_RDONLY is not part of MountFlags because it's tracked in Mount.writers.
+//
+// +stateify savable
type MountFlags struct {
// NoExec is equivalent to MS_NOEXEC.
NoExec bool
@@ -93,6 +101,8 @@ type MountFlags struct {
}
// MountOptions contains options to VirtualFilesystem.MountAt().
+//
+// +stateify savable
type MountOptions struct {
// Flags contains flags as specified for mount(2), e.g. MS_NOEXEC.
Flags MountFlags
@@ -112,6 +122,8 @@ type MountOptions struct {
// OpenOptions contains options to VirtualFilesystem.OpenAt() and
// FilesystemImpl.OpenAt().
+//
+// +stateify savable
type OpenOptions struct {
// Flags contains access mode and flags as specified for open(2).
//
@@ -137,6 +149,8 @@ type OpenOptions struct {
// ReadOptions contains options to FileDescription.PRead(),
// FileDescriptionImpl.PRead(), FileDescription.Read(), and
// FileDescriptionImpl.Read().
+//
+// +stateify savable
type ReadOptions struct {
// Flags contains flags as specified for preadv2(2).
Flags uint32
@@ -144,6 +158,8 @@ type ReadOptions struct {
// RenameOptions contains options to VirtualFilesystem.RenameAt() and
// FilesystemImpl.RenameAt().
+//
+// +stateify savable
type RenameOptions struct {
// Flags contains flags as specified for renameat2(2).
Flags uint32
@@ -155,6 +171,8 @@ type RenameOptions struct {
// SetStatOptions contains options to VirtualFilesystem.SetStatAt(),
// FilesystemImpl.SetStatAt(), FileDescription.SetStat(), and
// FileDescriptionImpl.SetStat().
+//
+// +stateify savable
type SetStatOptions struct {
// Stat is the metadata that should be set. Only fields indicated by
// Stat.Mask should be set.
@@ -176,6 +194,8 @@ type SetStatOptions struct {
// BoundEndpointOptions contains options to VirtualFilesystem.BoundEndpointAt()
// and FilesystemImpl.BoundEndpointAt().
+//
+// +stateify savable
type BoundEndpointOptions struct {
// Addr is the path of the file whose socket endpoint is being retrieved.
// It is generally irrelevant: most endpoints are stored at a dentry that
@@ -195,6 +215,8 @@ type BoundEndpointOptions struct {
// GetXattrOptions contains options to VirtualFilesystem.GetXattrAt(),
// FilesystemImpl.GetXattrAt(), FileDescription.GetXattr(), and
// FileDescriptionImpl.GetXattr().
+//
+// +stateify savable
type GetXattrOptions struct {
// Name is the name of the extended attribute to retrieve.
Name string
@@ -209,6 +231,8 @@ type GetXattrOptions struct {
// SetXattrOptions contains options to VirtualFilesystem.SetXattrAt(),
// FilesystemImpl.SetXattrAt(), FileDescription.SetXattr(), and
// FileDescriptionImpl.SetXattr().
+//
+// +stateify savable
type SetXattrOptions struct {
// Name is the name of the extended attribute being mutated.
Name string
@@ -223,6 +247,8 @@ type SetXattrOptions struct {
// StatOptions contains options to VirtualFilesystem.StatAt(),
// FilesystemImpl.StatAt(), FileDescription.Stat(), and
// FileDescriptionImpl.Stat().
+//
+// +stateify savable
type StatOptions struct {
// Mask is the set of fields in the returned Statx that the FilesystemImpl
// or FileDescriptionImpl should provide. Bits are as in linux.Statx.Mask.
@@ -240,6 +266,8 @@ type StatOptions struct {
}
// UmountOptions contains options to VirtualFilesystem.UmountAt().
+//
+// +stateify savable
type UmountOptions struct {
// Flags contains flags as specified for umount2(2).
Flags uint32
@@ -248,6 +276,8 @@ type UmountOptions struct {
// WriteOptions contains options to FileDescription.PWrite(),
// FileDescriptionImpl.PWrite(), FileDescription.Write(), and
// FileDescriptionImpl.Write().
+//
+// +stateify savable
type WriteOptions struct {
// Flags contains flags as specified for pwritev2(2).
Flags uint32
diff --git a/pkg/sentry/vfs/permissions.go b/pkg/sentry/vfs/permissions.go
index 00eeb8842..d48520d58 100644
--- a/pkg/sentry/vfs/permissions.go
+++ b/pkg/sentry/vfs/permissions.go
@@ -26,6 +26,8 @@ import (
)
// AccessTypes is a bitmask of Unix file permissions.
+//
+// +stateify savable
type AccessTypes uint16
// Bits in AccessTypes.
diff --git a/pkg/sentry/vfs/resolving_path.go b/pkg/sentry/vfs/resolving_path.go
index 3304372d9..e4fd55012 100644
--- a/pkg/sentry/vfs/resolving_path.go
+++ b/pkg/sentry/vfs/resolving_path.go
@@ -35,6 +35,8 @@ import (
// FilesystemImpl methods.
//
// ResolvingPath is loosely analogous to Linux's struct nameidata.
+//
+// +stateify savable
type ResolvingPath struct {
vfs *VirtualFilesystem
root VirtualDentry // refs borrowed from PathOperation
@@ -88,6 +90,7 @@ func init() {
// so error "constants" are really mutable vars, necessitating somewhat
// expensive interface object comparisons.
+// +stateify savable
type resolveMountRootOrJumpError struct{}
// Error implements error.Error.
@@ -95,6 +98,7 @@ func (resolveMountRootOrJumpError) Error() string {
return "resolving mount root or jump"
}
+// +stateify savable
type resolveMountPointError struct{}
// Error implements error.Error.
@@ -102,6 +106,7 @@ func (resolveMountPointError) Error() string {
return "resolving mount point"
}
+// +stateify savable
type resolveAbsSymlinkError struct{}
// Error implements error.Error.
diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go
index 1ebf355ef..5bd756ea5 100644
--- a/pkg/sentry/vfs/vfs.go
+++ b/pkg/sentry/vfs/vfs.go
@@ -163,6 +163,8 @@ func (vfs *VirtualFilesystem) Init(ctx context.Context) error {
// PathOperation is passed to VFS methods by pointer to reduce memory copying:
// it's somewhat large and should never escape. (Options structs are passed by
// pointer to VFS and FileDescription methods for the same reason.)
+//
+// +stateify savable
type PathOperation struct {
// Root is the VFS root. References on Root are borrowed from the provider
// of the PathOperation.
diff --git a/pkg/sentry/vfs/vfs_state_autogen.go b/pkg/sentry/vfs/vfs_state_autogen.go
index be649f60a..3c35d1577 100644
--- a/pkg/sentry/vfs/vfs_state_autogen.go
+++ b/pkg/sentry/vfs/vfs_state_autogen.go
@@ -6,6 +6,77 @@ import (
"gvisor.dev/gvisor/pkg/state"
)
+func (x *anonFilesystemType) StateTypeName() string {
+ return "pkg/sentry/vfs.anonFilesystemType"
+}
+
+func (x *anonFilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *anonFilesystemType) beforeSave() {}
+
+func (x *anonFilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *anonFilesystemType) afterLoad() {}
+
+func (x *anonFilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *anonFilesystem) StateTypeName() string {
+ return "pkg/sentry/vfs.anonFilesystem"
+}
+
+func (x *anonFilesystem) StateFields() []string {
+ return []string{
+ "vfsfs",
+ "devMinor",
+ }
+}
+
+func (x *anonFilesystem) beforeSave() {}
+
+func (x *anonFilesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfs)
+ m.Save(1, &x.devMinor)
+}
+
+func (x *anonFilesystem) afterLoad() {}
+
+func (x *anonFilesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfs)
+ m.Load(1, &x.devMinor)
+}
+
+func (x *anonDentry) StateTypeName() string {
+ return "pkg/sentry/vfs.anonDentry"
+}
+
+func (x *anonDentry) StateFields() []string {
+ return []string{
+ "vfsd",
+ "name",
+ }
+}
+
+func (x *anonDentry) beforeSave() {}
+
+func (x *anonDentry) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsd)
+ m.Save(1, &x.name)
+}
+
+func (x *anonDentry) afterLoad() {}
+
+func (x *anonDentry) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsd)
+ m.Load(1, &x.name)
+}
+
func (x *Dentry) StateTypeName() string {
return "pkg/sentry/vfs.Dentry"
}
@@ -35,6 +106,43 @@ func (x *Dentry) StateLoad(m state.Source) {
m.Load(2, &x.impl)
}
+func (x *DeviceKind) StateTypeName() string {
+ return "pkg/sentry/vfs.DeviceKind"
+}
+
+func (x *DeviceKind) StateFields() []string {
+ return nil
+}
+
+func (x *devTuple) StateTypeName() string {
+ return "pkg/sentry/vfs.devTuple"
+}
+
+func (x *devTuple) StateFields() []string {
+ return []string{
+ "kind",
+ "major",
+ "minor",
+ }
+}
+
+func (x *devTuple) beforeSave() {}
+
+func (x *devTuple) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.kind)
+ m.Save(1, &x.major)
+ m.Save(2, &x.minor)
+}
+
+func (x *devTuple) afterLoad() {}
+
+func (x *devTuple) StateLoad(m state.Source) {
+ m.Load(0, &x.kind)
+ m.Load(1, &x.major)
+ m.Load(2, &x.minor)
+}
+
func (x *registeredDevice) StateTypeName() string {
return "pkg/sentry/vfs.registeredDevice"
}
@@ -84,6 +192,114 @@ func (x *RegisterDeviceOptions) StateLoad(m state.Source) {
m.Load(0, &x.GroupName)
}
+func (x *EpollInstance) StateTypeName() string {
+ return "pkg/sentry/vfs.EpollInstance"
+}
+
+func (x *EpollInstance) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "DentryMetadataFileDescriptionImpl",
+ "NoLockFD",
+ "q",
+ "interest",
+ "ready",
+ }
+}
+
+func (x *EpollInstance) beforeSave() {}
+
+func (x *EpollInstance) 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.q)
+ m.Save(5, &x.interest)
+ m.Save(6, &x.ready)
+}
+
+func (x *EpollInstance) afterLoad() {}
+
+func (x *EpollInstance) 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.q)
+ m.Load(5, &x.interest)
+ m.Load(6, &x.ready)
+}
+
+func (x *epollInterestKey) StateTypeName() string {
+ return "pkg/sentry/vfs.epollInterestKey"
+}
+
+func (x *epollInterestKey) StateFields() []string {
+ return []string{
+ "file",
+ "num",
+ }
+}
+
+func (x *epollInterestKey) beforeSave() {}
+
+func (x *epollInterestKey) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.file)
+ m.Save(1, &x.num)
+}
+
+func (x *epollInterestKey) afterLoad() {}
+
+func (x *epollInterestKey) StateLoad(m state.Source) {
+ m.Load(0, &x.file)
+ m.Load(1, &x.num)
+}
+
+func (x *epollInterest) StateTypeName() string {
+ return "pkg/sentry/vfs.epollInterest"
+}
+
+func (x *epollInterest) StateFields() []string {
+ return []string{
+ "epoll",
+ "key",
+ "waiter",
+ "mask",
+ "ready",
+ "epollInterestEntry",
+ "userData",
+ }
+}
+
+func (x *epollInterest) beforeSave() {}
+
+func (x *epollInterest) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.epoll)
+ m.Save(1, &x.key)
+ m.Save(2, &x.waiter)
+ m.Save(3, &x.mask)
+ m.Save(4, &x.ready)
+ m.Save(5, &x.epollInterestEntry)
+ m.Save(6, &x.userData)
+}
+
+func (x *epollInterest) afterLoad() {}
+
+func (x *epollInterest) StateLoad(m state.Source) {
+ m.Load(0, &x.epoll)
+ m.Load(1, &x.key)
+ m.Load(2, &x.waiter)
+ m.Load(3, &x.mask)
+ m.Load(4, &x.ready)
+ m.Load(5, &x.epollInterestEntry)
+ m.Load(6, &x.userData)
+}
+
func (x *epollInterestList) StateTypeName() string {
return "pkg/sentry/vfs.epollInterestList"
}
@@ -188,6 +404,275 @@ func (x *eventEntry) StateLoad(m state.Source) {
m.Load(1, &x.prev)
}
+func (x *FileDescription) StateTypeName() string {
+ return "pkg/sentry/vfs.FileDescription"
+}
+
+func (x *FileDescription) StateFields() []string {
+ return []string{
+ "FileDescriptionRefs",
+ "statusFlags",
+ "asyncHandler",
+ "epolls",
+ "vd",
+ "opts",
+ "readable",
+ "writable",
+ "usedLockBSD",
+ "impl",
+ }
+}
+
+func (x *FileDescription) beforeSave() {}
+
+func (x *FileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.FileDescriptionRefs)
+ m.Save(1, &x.statusFlags)
+ m.Save(2, &x.asyncHandler)
+ m.Save(3, &x.epolls)
+ m.Save(4, &x.vd)
+ m.Save(5, &x.opts)
+ m.Save(6, &x.readable)
+ m.Save(7, &x.writable)
+ m.Save(8, &x.usedLockBSD)
+ m.Save(9, &x.impl)
+}
+
+func (x *FileDescription) afterLoad() {}
+
+func (x *FileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.FileDescriptionRefs)
+ m.Load(1, &x.statusFlags)
+ m.Load(2, &x.asyncHandler)
+ m.Load(3, &x.epolls)
+ m.Load(4, &x.vd)
+ m.Load(5, &x.opts)
+ m.Load(6, &x.readable)
+ m.Load(7, &x.writable)
+ m.Load(8, &x.usedLockBSD)
+ m.Load(9, &x.impl)
+}
+
+func (x *FileDescriptionOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.FileDescriptionOptions"
+}
+
+func (x *FileDescriptionOptions) StateFields() []string {
+ return []string{
+ "AllowDirectIO",
+ "DenyPRead",
+ "DenyPWrite",
+ "UseDentryMetadata",
+ }
+}
+
+func (x *FileDescriptionOptions) beforeSave() {}
+
+func (x *FileDescriptionOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.AllowDirectIO)
+ m.Save(1, &x.DenyPRead)
+ m.Save(2, &x.DenyPWrite)
+ m.Save(3, &x.UseDentryMetadata)
+}
+
+func (x *FileDescriptionOptions) afterLoad() {}
+
+func (x *FileDescriptionOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.AllowDirectIO)
+ m.Load(1, &x.DenyPRead)
+ m.Load(2, &x.DenyPWrite)
+ m.Load(3, &x.UseDentryMetadata)
+}
+
+func (x *Dirent) StateTypeName() string {
+ return "pkg/sentry/vfs.Dirent"
+}
+
+func (x *Dirent) StateFields() []string {
+ return []string{
+ "Name",
+ "Type",
+ "Ino",
+ "NextOff",
+ }
+}
+
+func (x *Dirent) beforeSave() {}
+
+func (x *Dirent) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Name)
+ m.Save(1, &x.Type)
+ m.Save(2, &x.Ino)
+ m.Save(3, &x.NextOff)
+}
+
+func (x *Dirent) afterLoad() {}
+
+func (x *Dirent) StateLoad(m state.Source) {
+ m.Load(0, &x.Name)
+ m.Load(1, &x.Type)
+ m.Load(2, &x.Ino)
+ m.Load(3, &x.NextOff)
+}
+
+func (x *FileDescriptionDefaultImpl) StateTypeName() string {
+ return "pkg/sentry/vfs.FileDescriptionDefaultImpl"
+}
+
+func (x *FileDescriptionDefaultImpl) StateFields() []string {
+ return []string{}
+}
+
+func (x *FileDescriptionDefaultImpl) beforeSave() {}
+
+func (x *FileDescriptionDefaultImpl) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FileDescriptionDefaultImpl) afterLoad() {}
+
+func (x *FileDescriptionDefaultImpl) StateLoad(m state.Source) {
+}
+
+func (x *DirectoryFileDescriptionDefaultImpl) StateTypeName() string {
+ return "pkg/sentry/vfs.DirectoryFileDescriptionDefaultImpl"
+}
+
+func (x *DirectoryFileDescriptionDefaultImpl) StateFields() []string {
+ return []string{}
+}
+
+func (x *DirectoryFileDescriptionDefaultImpl) beforeSave() {}
+
+func (x *DirectoryFileDescriptionDefaultImpl) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *DirectoryFileDescriptionDefaultImpl) afterLoad() {}
+
+func (x *DirectoryFileDescriptionDefaultImpl) StateLoad(m state.Source) {
+}
+
+func (x *DentryMetadataFileDescriptionImpl) StateTypeName() string {
+ return "pkg/sentry/vfs.DentryMetadataFileDescriptionImpl"
+}
+
+func (x *DentryMetadataFileDescriptionImpl) StateFields() []string {
+ return []string{}
+}
+
+func (x *DentryMetadataFileDescriptionImpl) beforeSave() {}
+
+func (x *DentryMetadataFileDescriptionImpl) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *DentryMetadataFileDescriptionImpl) afterLoad() {}
+
+func (x *DentryMetadataFileDescriptionImpl) StateLoad(m state.Source) {
+}
+
+func (x *StaticData) StateTypeName() string {
+ return "pkg/sentry/vfs.StaticData"
+}
+
+func (x *StaticData) StateFields() []string {
+ return []string{
+ "Data",
+ }
+}
+
+func (x *StaticData) beforeSave() {}
+
+func (x *StaticData) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Data)
+}
+
+func (x *StaticData) afterLoad() {}
+
+func (x *StaticData) StateLoad(m state.Source) {
+ m.Load(0, &x.Data)
+}
+
+func (x *DynamicBytesFileDescriptionImpl) StateTypeName() string {
+ return "pkg/sentry/vfs.DynamicBytesFileDescriptionImpl"
+}
+
+func (x *DynamicBytesFileDescriptionImpl) StateFields() []string {
+ return []string{
+ "data",
+ "buf",
+ "off",
+ "lastRead",
+ }
+}
+
+func (x *DynamicBytesFileDescriptionImpl) beforeSave() {}
+
+func (x *DynamicBytesFileDescriptionImpl) StateSave(m state.Sink) {
+ x.beforeSave()
+ var buf []byte = x.saveBuf()
+ m.SaveValue(1, buf)
+ m.Save(0, &x.data)
+ m.Save(2, &x.off)
+ m.Save(3, &x.lastRead)
+}
+
+func (x *DynamicBytesFileDescriptionImpl) afterLoad() {}
+
+func (x *DynamicBytesFileDescriptionImpl) StateLoad(m state.Source) {
+ m.Load(0, &x.data)
+ m.Load(2, &x.off)
+ m.Load(3, &x.lastRead)
+ m.LoadValue(1, new([]byte), func(y interface{}) { x.loadBuf(y.([]byte)) })
+}
+
+func (x *LockFD) StateTypeName() string {
+ return "pkg/sentry/vfs.LockFD"
+}
+
+func (x *LockFD) StateFields() []string {
+ return []string{
+ "locks",
+ }
+}
+
+func (x *LockFD) beforeSave() {}
+
+func (x *LockFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.locks)
+}
+
+func (x *LockFD) afterLoad() {}
+
+func (x *LockFD) StateLoad(m state.Source) {
+ m.Load(0, &x.locks)
+}
+
+func (x *NoLockFD) StateTypeName() string {
+ return "pkg/sentry/vfs.NoLockFD"
+}
+
+func (x *NoLockFD) StateFields() []string {
+ return []string{}
+}
+
+func (x *NoLockFD) beforeSave() {}
+
+func (x *NoLockFD) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *NoLockFD) afterLoad() {}
+
+func (x *NoLockFD) StateLoad(m state.Source) {
+}
+
func (x *FileDescriptionRefs) StateTypeName() string {
return "pkg/sentry/vfs.FileDescriptionRefs"
}
@@ -243,6 +728,63 @@ func (x *Filesystem) StateLoad(m state.Source) {
m.Load(3, &x.impl)
}
+func (x *PrependPathAtVFSRootError) StateTypeName() string {
+ return "pkg/sentry/vfs.PrependPathAtVFSRootError"
+}
+
+func (x *PrependPathAtVFSRootError) StateFields() []string {
+ return []string{}
+}
+
+func (x *PrependPathAtVFSRootError) beforeSave() {}
+
+func (x *PrependPathAtVFSRootError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *PrependPathAtVFSRootError) afterLoad() {}
+
+func (x *PrependPathAtVFSRootError) StateLoad(m state.Source) {
+}
+
+func (x *PrependPathAtNonMountRootError) StateTypeName() string {
+ return "pkg/sentry/vfs.PrependPathAtNonMountRootError"
+}
+
+func (x *PrependPathAtNonMountRootError) StateFields() []string {
+ return []string{}
+}
+
+func (x *PrependPathAtNonMountRootError) beforeSave() {}
+
+func (x *PrependPathAtNonMountRootError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *PrependPathAtNonMountRootError) afterLoad() {}
+
+func (x *PrependPathAtNonMountRootError) StateLoad(m state.Source) {
+}
+
+func (x *PrependPathSyntheticError) StateTypeName() string {
+ return "pkg/sentry/vfs.PrependPathSyntheticError"
+}
+
+func (x *PrependPathSyntheticError) StateFields() []string {
+ return []string{}
+}
+
+func (x *PrependPathSyntheticError) beforeSave() {}
+
+func (x *PrependPathSyntheticError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *PrependPathSyntheticError) afterLoad() {}
+
+func (x *PrependPathSyntheticError) StateLoad(m state.Source) {
+}
+
func (x *FilesystemRefs) StateTypeName() string {
return "pkg/sentry/vfs.FilesystemRefs"
}
@@ -292,6 +834,43 @@ func (x *registeredFilesystemType) StateLoad(m state.Source) {
m.Load(1, &x.opts)
}
+func (x *RegisterFilesystemTypeOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.RegisterFilesystemTypeOptions"
+}
+
+func (x *RegisterFilesystemTypeOptions) StateFields() []string {
+ return []string{
+ "AllowUserMount",
+ "AllowUserList",
+ "RequiresDevice",
+ }
+}
+
+func (x *RegisterFilesystemTypeOptions) beforeSave() {}
+
+func (x *RegisterFilesystemTypeOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.AllowUserMount)
+ m.Save(1, &x.AllowUserList)
+ m.Save(2, &x.RequiresDevice)
+}
+
+func (x *RegisterFilesystemTypeOptions) afterLoad() {}
+
+func (x *RegisterFilesystemTypeOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.AllowUserMount)
+ m.Load(1, &x.AllowUserList)
+ m.Load(2, &x.RequiresDevice)
+}
+
+func (x *EventType) StateTypeName() string {
+ return "pkg/sentry/vfs.EventType"
+}
+
+func (x *EventType) StateFields() []string {
+ return nil
+}
+
func (x *Inotify) StateTypeName() string {
return "pkg/sentry/vfs.Inotify"
}
@@ -435,6 +1014,32 @@ func (x *Event) StateLoad(m state.Source) {
m.Load(5, &x.name)
}
+func (x *FileLocks) StateTypeName() string {
+ return "pkg/sentry/vfs.FileLocks"
+}
+
+func (x *FileLocks) StateFields() []string {
+ return []string{
+ "bsd",
+ "posix",
+ }
+}
+
+func (x *FileLocks) beforeSave() {}
+
+func (x *FileLocks) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.bsd)
+ m.Save(1, &x.posix)
+}
+
+func (x *FileLocks) afterLoad() {}
+
+func (x *FileLocks) StateLoad(m state.Source) {
+ m.Load(0, &x.bsd)
+ m.Load(1, &x.posix)
+}
+
func (x *Mount) StateTypeName() string {
return "pkg/sentry/vfs.Mount"
}
@@ -459,12 +1064,13 @@ func (x *Mount) beforeSave() {}
func (x *Mount) StateSave(m state.Sink) {
x.beforeSave()
+ var key VirtualDentry = x.saveKey()
+ m.SaveValue(5, key)
m.Save(0, &x.vfs)
m.Save(1, &x.fs)
m.Save(2, &x.root)
m.Save(3, &x.ID)
m.Save(4, &x.Flags)
- m.Save(5, &x.key)
m.Save(6, &x.ns)
m.Save(7, &x.refs)
m.Save(8, &x.children)
@@ -480,12 +1086,12 @@ func (x *Mount) StateLoad(m state.Source) {
m.Load(2, &x.root)
m.Load(3, &x.ID)
m.Load(4, &x.Flags)
- m.Load(5, &x.key)
m.Load(6, &x.ns)
m.Load(7, &x.refs)
m.Load(8, &x.children)
m.Load(9, &x.umounted)
m.Load(10, &x.writers)
+ m.LoadValue(5, new(VirtualDentry), func(y interface{}) { x.loadKey(y.(VirtualDentry)) })
}
func (x *MountNamespace) StateTypeName() string {
@@ -520,6 +1126,32 @@ func (x *MountNamespace) StateLoad(m state.Source) {
m.Load(3, &x.mountpoints)
}
+func (x *umountRecursiveOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.umountRecursiveOptions"
+}
+
+func (x *umountRecursiveOptions) StateFields() []string {
+ return []string{
+ "eager",
+ "disconnectHierarchy",
+ }
+}
+
+func (x *umountRecursiveOptions) beforeSave() {}
+
+func (x *umountRecursiveOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.eager)
+ m.Save(1, &x.disconnectHierarchy)
+}
+
+func (x *umountRecursiveOptions) afterLoad() {}
+
+func (x *umountRecursiveOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.eager)
+ m.Load(1, &x.disconnectHierarchy)
+}
+
func (x *MountNamespaceRefs) StateTypeName() string {
return "pkg/sentry/vfs.MountNamespaceRefs"
}
@@ -543,6 +1175,544 @@ func (x *MountNamespaceRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *GetDentryOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.GetDentryOptions"
+}
+
+func (x *GetDentryOptions) StateFields() []string {
+ return []string{
+ "CheckSearchable",
+ }
+}
+
+func (x *GetDentryOptions) beforeSave() {}
+
+func (x *GetDentryOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.CheckSearchable)
+}
+
+func (x *GetDentryOptions) afterLoad() {}
+
+func (x *GetDentryOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.CheckSearchable)
+}
+
+func (x *MkdirOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.MkdirOptions"
+}
+
+func (x *MkdirOptions) StateFields() []string {
+ return []string{
+ "Mode",
+ "ForSyntheticMountpoint",
+ }
+}
+
+func (x *MkdirOptions) beforeSave() {}
+
+func (x *MkdirOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Mode)
+ m.Save(1, &x.ForSyntheticMountpoint)
+}
+
+func (x *MkdirOptions) afterLoad() {}
+
+func (x *MkdirOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Mode)
+ m.Load(1, &x.ForSyntheticMountpoint)
+}
+
+func (x *MknodOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.MknodOptions"
+}
+
+func (x *MknodOptions) StateFields() []string {
+ return []string{
+ "Mode",
+ "DevMajor",
+ "DevMinor",
+ "Endpoint",
+ }
+}
+
+func (x *MknodOptions) beforeSave() {}
+
+func (x *MknodOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Mode)
+ m.Save(1, &x.DevMajor)
+ m.Save(2, &x.DevMinor)
+ m.Save(3, &x.Endpoint)
+}
+
+func (x *MknodOptions) afterLoad() {}
+
+func (x *MknodOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Mode)
+ m.Load(1, &x.DevMajor)
+ m.Load(2, &x.DevMinor)
+ m.Load(3, &x.Endpoint)
+}
+
+func (x *MountFlags) StateTypeName() string {
+ return "pkg/sentry/vfs.MountFlags"
+}
+
+func (x *MountFlags) StateFields() []string {
+ return []string{
+ "NoExec",
+ "NoATime",
+ "NoDev",
+ "NoSUID",
+ }
+}
+
+func (x *MountFlags) beforeSave() {}
+
+func (x *MountFlags) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.NoExec)
+ m.Save(1, &x.NoATime)
+ m.Save(2, &x.NoDev)
+ m.Save(3, &x.NoSUID)
+}
+
+func (x *MountFlags) afterLoad() {}
+
+func (x *MountFlags) StateLoad(m state.Source) {
+ m.Load(0, &x.NoExec)
+ m.Load(1, &x.NoATime)
+ m.Load(2, &x.NoDev)
+ m.Load(3, &x.NoSUID)
+}
+
+func (x *MountOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.MountOptions"
+}
+
+func (x *MountOptions) StateFields() []string {
+ return []string{
+ "Flags",
+ "ReadOnly",
+ "GetFilesystemOptions",
+ "InternalMount",
+ }
+}
+
+func (x *MountOptions) beforeSave() {}
+
+func (x *MountOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Flags)
+ m.Save(1, &x.ReadOnly)
+ m.Save(2, &x.GetFilesystemOptions)
+ m.Save(3, &x.InternalMount)
+}
+
+func (x *MountOptions) afterLoad() {}
+
+func (x *MountOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Flags)
+ m.Load(1, &x.ReadOnly)
+ m.Load(2, &x.GetFilesystemOptions)
+ m.Load(3, &x.InternalMount)
+}
+
+func (x *OpenOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.OpenOptions"
+}
+
+func (x *OpenOptions) StateFields() []string {
+ return []string{
+ "Flags",
+ "Mode",
+ "FileExec",
+ }
+}
+
+func (x *OpenOptions) beforeSave() {}
+
+func (x *OpenOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Flags)
+ m.Save(1, &x.Mode)
+ m.Save(2, &x.FileExec)
+}
+
+func (x *OpenOptions) afterLoad() {}
+
+func (x *OpenOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Flags)
+ m.Load(1, &x.Mode)
+ m.Load(2, &x.FileExec)
+}
+
+func (x *ReadOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.ReadOptions"
+}
+
+func (x *ReadOptions) StateFields() []string {
+ return []string{
+ "Flags",
+ }
+}
+
+func (x *ReadOptions) beforeSave() {}
+
+func (x *ReadOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Flags)
+}
+
+func (x *ReadOptions) afterLoad() {}
+
+func (x *ReadOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Flags)
+}
+
+func (x *RenameOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.RenameOptions"
+}
+
+func (x *RenameOptions) StateFields() []string {
+ return []string{
+ "Flags",
+ "MustBeDir",
+ }
+}
+
+func (x *RenameOptions) beforeSave() {}
+
+func (x *RenameOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Flags)
+ m.Save(1, &x.MustBeDir)
+}
+
+func (x *RenameOptions) afterLoad() {}
+
+func (x *RenameOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Flags)
+ m.Load(1, &x.MustBeDir)
+}
+
+func (x *SetStatOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.SetStatOptions"
+}
+
+func (x *SetStatOptions) StateFields() []string {
+ return []string{
+ "Stat",
+ "NeedWritePerm",
+ }
+}
+
+func (x *SetStatOptions) beforeSave() {}
+
+func (x *SetStatOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Stat)
+ m.Save(1, &x.NeedWritePerm)
+}
+
+func (x *SetStatOptions) afterLoad() {}
+
+func (x *SetStatOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Stat)
+ m.Load(1, &x.NeedWritePerm)
+}
+
+func (x *BoundEndpointOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.BoundEndpointOptions"
+}
+
+func (x *BoundEndpointOptions) StateFields() []string {
+ return []string{
+ "Addr",
+ }
+}
+
+func (x *BoundEndpointOptions) beforeSave() {}
+
+func (x *BoundEndpointOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Addr)
+}
+
+func (x *BoundEndpointOptions) afterLoad() {}
+
+func (x *BoundEndpointOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Addr)
+}
+
+func (x *GetXattrOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.GetXattrOptions"
+}
+
+func (x *GetXattrOptions) StateFields() []string {
+ return []string{
+ "Name",
+ "Size",
+ }
+}
+
+func (x *GetXattrOptions) beforeSave() {}
+
+func (x *GetXattrOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Name)
+ m.Save(1, &x.Size)
+}
+
+func (x *GetXattrOptions) afterLoad() {}
+
+func (x *GetXattrOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Name)
+ m.Load(1, &x.Size)
+}
+
+func (x *SetXattrOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.SetXattrOptions"
+}
+
+func (x *SetXattrOptions) StateFields() []string {
+ return []string{
+ "Name",
+ "Value",
+ "Flags",
+ }
+}
+
+func (x *SetXattrOptions) beforeSave() {}
+
+func (x *SetXattrOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Name)
+ m.Save(1, &x.Value)
+ m.Save(2, &x.Flags)
+}
+
+func (x *SetXattrOptions) afterLoad() {}
+
+func (x *SetXattrOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Name)
+ m.Load(1, &x.Value)
+ m.Load(2, &x.Flags)
+}
+
+func (x *StatOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.StatOptions"
+}
+
+func (x *StatOptions) StateFields() []string {
+ return []string{
+ "Mask",
+ "Sync",
+ }
+}
+
+func (x *StatOptions) beforeSave() {}
+
+func (x *StatOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Mask)
+ m.Save(1, &x.Sync)
+}
+
+func (x *StatOptions) afterLoad() {}
+
+func (x *StatOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Mask)
+ m.Load(1, &x.Sync)
+}
+
+func (x *UmountOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.UmountOptions"
+}
+
+func (x *UmountOptions) StateFields() []string {
+ return []string{
+ "Flags",
+ }
+}
+
+func (x *UmountOptions) beforeSave() {}
+
+func (x *UmountOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Flags)
+}
+
+func (x *UmountOptions) afterLoad() {}
+
+func (x *UmountOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Flags)
+}
+
+func (x *WriteOptions) StateTypeName() string {
+ return "pkg/sentry/vfs.WriteOptions"
+}
+
+func (x *WriteOptions) StateFields() []string {
+ return []string{
+ "Flags",
+ }
+}
+
+func (x *WriteOptions) beforeSave() {}
+
+func (x *WriteOptions) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Flags)
+}
+
+func (x *WriteOptions) afterLoad() {}
+
+func (x *WriteOptions) StateLoad(m state.Source) {
+ m.Load(0, &x.Flags)
+}
+
+func (x *AccessTypes) StateTypeName() string {
+ return "pkg/sentry/vfs.AccessTypes"
+}
+
+func (x *AccessTypes) StateFields() []string {
+ return nil
+}
+
+func (x *ResolvingPath) StateTypeName() string {
+ return "pkg/sentry/vfs.ResolvingPath"
+}
+
+func (x *ResolvingPath) StateFields() []string {
+ return []string{
+ "vfs",
+ "root",
+ "mount",
+ "start",
+ "pit",
+ "flags",
+ "mustBeDir",
+ "mustBeDirOrig",
+ "symlinks",
+ "symlinksOrig",
+ "curPart",
+ "numOrigParts",
+ "creds",
+ "nextMount",
+ "nextStart",
+ "absSymlinkTarget",
+ "parts",
+ "origParts",
+ }
+}
+
+func (x *ResolvingPath) beforeSave() {}
+
+func (x *ResolvingPath) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfs)
+ m.Save(1, &x.root)
+ m.Save(2, &x.mount)
+ m.Save(3, &x.start)
+ m.Save(4, &x.pit)
+ m.Save(5, &x.flags)
+ m.Save(6, &x.mustBeDir)
+ m.Save(7, &x.mustBeDirOrig)
+ m.Save(8, &x.symlinks)
+ m.Save(9, &x.symlinksOrig)
+ m.Save(10, &x.curPart)
+ m.Save(11, &x.numOrigParts)
+ m.Save(12, &x.creds)
+ m.Save(13, &x.nextMount)
+ m.Save(14, &x.nextStart)
+ m.Save(15, &x.absSymlinkTarget)
+ m.Save(16, &x.parts)
+ m.Save(17, &x.origParts)
+}
+
+func (x *ResolvingPath) afterLoad() {}
+
+func (x *ResolvingPath) StateLoad(m state.Source) {
+ m.Load(0, &x.vfs)
+ m.Load(1, &x.root)
+ m.Load(2, &x.mount)
+ m.Load(3, &x.start)
+ m.Load(4, &x.pit)
+ m.Load(5, &x.flags)
+ m.Load(6, &x.mustBeDir)
+ m.Load(7, &x.mustBeDirOrig)
+ m.Load(8, &x.symlinks)
+ m.Load(9, &x.symlinksOrig)
+ m.Load(10, &x.curPart)
+ m.Load(11, &x.numOrigParts)
+ m.Load(12, &x.creds)
+ m.Load(13, &x.nextMount)
+ m.Load(14, &x.nextStart)
+ m.Load(15, &x.absSymlinkTarget)
+ m.Load(16, &x.parts)
+ m.Load(17, &x.origParts)
+}
+
+func (x *resolveMountRootOrJumpError) StateTypeName() string {
+ return "pkg/sentry/vfs.resolveMountRootOrJumpError"
+}
+
+func (x *resolveMountRootOrJumpError) StateFields() []string {
+ return []string{}
+}
+
+func (x *resolveMountRootOrJumpError) beforeSave() {}
+
+func (x *resolveMountRootOrJumpError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *resolveMountRootOrJumpError) afterLoad() {}
+
+func (x *resolveMountRootOrJumpError) StateLoad(m state.Source) {
+}
+
+func (x *resolveMountPointError) StateTypeName() string {
+ return "pkg/sentry/vfs.resolveMountPointError"
+}
+
+func (x *resolveMountPointError) StateFields() []string {
+ return []string{}
+}
+
+func (x *resolveMountPointError) beforeSave() {}
+
+func (x *resolveMountPointError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *resolveMountPointError) afterLoad() {}
+
+func (x *resolveMountPointError) StateLoad(m state.Source) {
+}
+
+func (x *resolveAbsSymlinkError) StateTypeName() string {
+ return "pkg/sentry/vfs.resolveAbsSymlinkError"
+}
+
+func (x *resolveAbsSymlinkError) StateFields() []string {
+ return []string{}
+}
+
+func (x *resolveAbsSymlinkError) beforeSave() {}
+
+func (x *resolveAbsSymlinkError) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *resolveAbsSymlinkError) afterLoad() {}
+
+func (x *resolveAbsSymlinkError) StateLoad(m state.Source) {
+}
+
func (x *VirtualFilesystem) StateTypeName() string {
return "pkg/sentry/vfs.VirtualFilesystem"
}
@@ -590,6 +1760,38 @@ func (x *VirtualFilesystem) StateLoad(m state.Source) {
m.Load(8, &x.filesystems)
}
+func (x *PathOperation) StateTypeName() string {
+ return "pkg/sentry/vfs.PathOperation"
+}
+
+func (x *PathOperation) StateFields() []string {
+ return []string{
+ "Root",
+ "Start",
+ "Path",
+ "FollowFinalSymlink",
+ }
+}
+
+func (x *PathOperation) beforeSave() {}
+
+func (x *PathOperation) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.Root)
+ m.Save(1, &x.Start)
+ m.Save(2, &x.Path)
+ m.Save(3, &x.FollowFinalSymlink)
+}
+
+func (x *PathOperation) afterLoad() {}
+
+func (x *PathOperation) StateLoad(m state.Source) {
+ m.Load(0, &x.Root)
+ m.Load(1, &x.Start)
+ m.Load(2, &x.Path)
+ m.Load(3, &x.FollowFinalSymlink)
+}
+
func (x *VirtualDentry) StateTypeName() string {
return "pkg/sentry/vfs.VirtualDentry"
}
@@ -617,24 +1819,70 @@ func (x *VirtualDentry) StateLoad(m state.Source) {
}
func init() {
+ state.Register((*anonFilesystemType)(nil))
+ state.Register((*anonFilesystem)(nil))
+ state.Register((*anonDentry)(nil))
state.Register((*Dentry)(nil))
+ state.Register((*DeviceKind)(nil))
+ state.Register((*devTuple)(nil))
state.Register((*registeredDevice)(nil))
state.Register((*RegisterDeviceOptions)(nil))
+ state.Register((*EpollInstance)(nil))
+ state.Register((*epollInterestKey)(nil))
+ state.Register((*epollInterest)(nil))
state.Register((*epollInterestList)(nil))
state.Register((*epollInterestEntry)(nil))
state.Register((*eventList)(nil))
state.Register((*eventEntry)(nil))
+ state.Register((*FileDescription)(nil))
+ state.Register((*FileDescriptionOptions)(nil))
+ state.Register((*Dirent)(nil))
+ state.Register((*FileDescriptionDefaultImpl)(nil))
+ state.Register((*DirectoryFileDescriptionDefaultImpl)(nil))
+ state.Register((*DentryMetadataFileDescriptionImpl)(nil))
+ state.Register((*StaticData)(nil))
+ state.Register((*DynamicBytesFileDescriptionImpl)(nil))
+ state.Register((*LockFD)(nil))
+ state.Register((*NoLockFD)(nil))
state.Register((*FileDescriptionRefs)(nil))
state.Register((*Filesystem)(nil))
+ state.Register((*PrependPathAtVFSRootError)(nil))
+ state.Register((*PrependPathAtNonMountRootError)(nil))
+ state.Register((*PrependPathSyntheticError)(nil))
state.Register((*FilesystemRefs)(nil))
state.Register((*registeredFilesystemType)(nil))
+ state.Register((*RegisterFilesystemTypeOptions)(nil))
+ state.Register((*EventType)(nil))
state.Register((*Inotify)(nil))
state.Register((*Watches)(nil))
state.Register((*Watch)(nil))
state.Register((*Event)(nil))
+ state.Register((*FileLocks)(nil))
state.Register((*Mount)(nil))
state.Register((*MountNamespace)(nil))
+ state.Register((*umountRecursiveOptions)(nil))
state.Register((*MountNamespaceRefs)(nil))
+ state.Register((*GetDentryOptions)(nil))
+ state.Register((*MkdirOptions)(nil))
+ state.Register((*MknodOptions)(nil))
+ state.Register((*MountFlags)(nil))
+ state.Register((*MountOptions)(nil))
+ state.Register((*OpenOptions)(nil))
+ state.Register((*ReadOptions)(nil))
+ state.Register((*RenameOptions)(nil))
+ state.Register((*SetStatOptions)(nil))
+ state.Register((*BoundEndpointOptions)(nil))
+ state.Register((*GetXattrOptions)(nil))
+ state.Register((*SetXattrOptions)(nil))
+ state.Register((*StatOptions)(nil))
+ state.Register((*UmountOptions)(nil))
+ state.Register((*WriteOptions)(nil))
+ state.Register((*AccessTypes)(nil))
+ state.Register((*ResolvingPath)(nil))
+ state.Register((*resolveMountRootOrJumpError)(nil))
+ state.Register((*resolveMountPointError)(nil))
+ state.Register((*resolveAbsSymlinkError)(nil))
state.Register((*VirtualFilesystem)(nil))
+ state.Register((*PathOperation)(nil))
state.Register((*VirtualDentry)(nil))
}