summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/tmpfs
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-09-24 17:19:53 +0000
committergVisor bot <gvisor-bot@google.com>2020-09-24 17:19:53 +0000
commit61cc049caaa2317eda73e66f65f82b5099dd2bc2 (patch)
tree352bfc9c114c181e052a9656be9f3b2acd5f7b33 /pkg/sentry/fsimpl/tmpfs
parent3102024707dc370e025f1b46fa2be12eade2f9cb (diff)
parent0a7075f38a4870ded687e117a299ac4996c0673e (diff)
Merge release-20200914.0-152-g0a7075f38 (automated)
Diffstat (limited to 'pkg/sentry/fsimpl/tmpfs')
-rw-r--r--pkg/sentry/fsimpl/tmpfs/device_file.go1
-rw-r--r--pkg/sentry/fsimpl/tmpfs/directory.go4
-rw-r--r--pkg/sentry/fsimpl/tmpfs/named_pipe.go1
-rw-r--r--pkg/sentry/fsimpl/tmpfs/regular_file.go7
-rw-r--r--pkg/sentry/fsimpl/tmpfs/socket_file.go2
-rw-r--r--pkg/sentry/fsimpl/tmpfs/symlink.go1
-rw-r--r--pkg/sentry/fsimpl/tmpfs/tmpfs.go26
-rw-r--r--pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go470
8 files changed, 502 insertions, 10 deletions
diff --git a/pkg/sentry/fsimpl/tmpfs/device_file.go b/pkg/sentry/fsimpl/tmpfs/device_file.go
index ac54d420d..9129d35b7 100644
--- a/pkg/sentry/fsimpl/tmpfs/device_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/device_file.go
@@ -22,6 +22,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/vfs"
)
+// +stateify savable
type deviceFile struct {
inode inode
kind vfs.DeviceKind
diff --git a/pkg/sentry/fsimpl/tmpfs/directory.go b/pkg/sentry/fsimpl/tmpfs/directory.go
index 070c75e68..e90669cf0 100644
--- a/pkg/sentry/fsimpl/tmpfs/directory.go
+++ b/pkg/sentry/fsimpl/tmpfs/directory.go
@@ -25,6 +25,7 @@ import (
"gvisor.dev/gvisor/pkg/syserror"
)
+// +stateify savable
type directory struct {
// Since directories can't be hard-linked, each directory can only be
// associated with a single dentry, which we can store in the directory
@@ -44,7 +45,7 @@ type directory struct {
// (with inode == nil) that represent the iteration position of
// directoryFDs. childList is used to support directoryFD.IterDirents()
// efficiently. childList is protected by iterMu.
- iterMu sync.Mutex
+ iterMu sync.Mutex `state:"nosave"`
childList dentryList
}
@@ -86,6 +87,7 @@ func (dir *directory) mayDelete(creds *auth.Credentials, child *dentry) error {
return vfs.CheckDeleteSticky(creds, linux.FileMode(atomic.LoadUint32(&dir.inode.mode)), auth.KUID(atomic.LoadUint32(&child.inode.uid)))
}
+// +stateify savable
type directoryFD struct {
fileDescription
vfs.DirectoryFileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/tmpfs/named_pipe.go b/pkg/sentry/fsimpl/tmpfs/named_pipe.go
index 5b0471ff4..d772db9e9 100644
--- a/pkg/sentry/fsimpl/tmpfs/named_pipe.go
+++ b/pkg/sentry/fsimpl/tmpfs/named_pipe.go
@@ -21,6 +21,7 @@ import (
"gvisor.dev/gvisor/pkg/usermem"
)
+// +stateify savable
type namedPipe struct {
inode inode
diff --git a/pkg/sentry/fsimpl/tmpfs/regular_file.go b/pkg/sentry/fsimpl/tmpfs/regular_file.go
index b8699d064..a199eb33d 100644
--- a/pkg/sentry/fsimpl/tmpfs/regular_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/regular_file.go
@@ -36,6 +36,8 @@ import (
)
// regularFile is a regular (=S_IFREG) tmpfs file.
+//
+// +stateify savable
type regularFile struct {
inode inode
@@ -66,7 +68,7 @@ type regularFile struct {
writableMappingPages uint64
// dataMu protects the fields below.
- dataMu sync.RWMutex
+ dataMu sync.RWMutex `state:"nosave"`
// data maps offsets into the file to offsets into memFile that store
// the file's data.
@@ -325,13 +327,14 @@ func (*regularFile) InvalidateUnsavable(context.Context) error {
return nil
}
+// +stateify savable
type regularFileFD struct {
fileDescription
// off is the file offset. off is accessed using atomic memory operations.
// offMu serializes operations that may mutate off.
off int64
- offMu sync.Mutex
+ offMu sync.Mutex `state:"nosave"`
}
// Release implements vfs.FileDescriptionImpl.Release.
diff --git a/pkg/sentry/fsimpl/tmpfs/socket_file.go b/pkg/sentry/fsimpl/tmpfs/socket_file.go
index 3ed650474..5699d5975 100644
--- a/pkg/sentry/fsimpl/tmpfs/socket_file.go
+++ b/pkg/sentry/fsimpl/tmpfs/socket_file.go
@@ -21,6 +21,8 @@ import (
)
// socketFile is a socket (=S_IFSOCK) tmpfs file.
+//
+// +stateify savable
type socketFile struct {
inode inode
ep transport.BoundEndpoint
diff --git a/pkg/sentry/fsimpl/tmpfs/symlink.go b/pkg/sentry/fsimpl/tmpfs/symlink.go
index b0de5fabe..a102a2ee2 100644
--- a/pkg/sentry/fsimpl/tmpfs/symlink.go
+++ b/pkg/sentry/fsimpl/tmpfs/symlink.go
@@ -19,6 +19,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/kernel/auth"
)
+// +stateify savable
type symlink struct {
inode inode
target string // immutable
diff --git a/pkg/sentry/fsimpl/tmpfs/tmpfs.go b/pkg/sentry/fsimpl/tmpfs/tmpfs.go
index 4658e1533..cefec8fde 100644
--- a/pkg/sentry/fsimpl/tmpfs/tmpfs.go
+++ b/pkg/sentry/fsimpl/tmpfs/tmpfs.go
@@ -51,9 +51,13 @@ import (
const Name = "tmpfs"
// FilesystemType implements vfs.FilesystemType.
+//
+// +stateify savable
type FilesystemType struct{}
// filesystem implements vfs.FilesystemImpl.
+//
+// +stateify savable
type filesystem struct {
vfsfs vfs.Filesystem
@@ -67,7 +71,7 @@ type filesystem struct {
devMinor uint32
// mu serializes changes to the Dentry tree.
- mu sync.RWMutex
+ mu sync.RWMutex `state:"nosave"`
nextInoMinusOne uint64 // accessed using atomic memory operations
}
@@ -78,6 +82,8 @@ func (FilesystemType) Name() string {
}
// FilesystemOpts is used to pass configuration data to tmpfs.
+//
+// +stateify savable
type FilesystemOpts struct {
// RootFileType is the FileType of the filesystem root. Valid values
// are: S_IFDIR, S_IFREG, and S_IFLNK. Defaults to S_IFDIR.
@@ -221,6 +227,8 @@ var globalStatfs = linux.Statfs{
}
// dentry implements vfs.DentryImpl.
+//
+// +stateify savable
type dentry struct {
vfsd vfs.Dentry
@@ -300,6 +308,8 @@ func (d *dentry) Watches() *vfs.Watches {
func (d *dentry) OnZeroWatches(context.Context) {}
// inode represents a filesystem object.
+//
+// +stateify savable
type inode struct {
// fs is the owning filesystem. fs is immutable.
fs *filesystem
@@ -316,12 +326,12 @@ type inode struct {
// Inode metadata. Writing multiple fields atomically requires holding
// mu, othewise atomic operations can be used.
- mu sync.Mutex
- mode uint32 // file type and mode
- nlink uint32 // protected by filesystem.mu instead of inode.mu
- uid uint32 // auth.KUID, but stored as raw uint32 for sync/atomic
- gid uint32 // auth.KGID, but ...
- ino uint64 // immutable
+ mu sync.Mutex `state:"nosave"`
+ mode uint32 // file type and mode
+ nlink uint32 // protected by filesystem.mu instead of inode.mu
+ uid uint32 // auth.KUID, but stored as raw uint32 for sync/atomic
+ gid uint32 // auth.KGID, but ...
+ ino uint64 // immutable
// Linux's tmpfs has no concept of btime.
atime int64 // nanoseconds
@@ -668,6 +678,8 @@ func (i *inode) checkXattrPermissions(creds *auth.Credentials, name string, ats
// fileDescription is embedded by tmpfs implementations of
// vfs.FileDescriptionImpl.
+//
+// +stateify savable
type fileDescription struct {
vfsfd vfs.FileDescription
vfs.FileDescriptionDefaultImpl
diff --git a/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go b/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go
index d88136656..4252b95e6 100644
--- a/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go
+++ b/pkg/sentry/fsimpl/tmpfs/tmpfs_state_autogen.go
@@ -58,6 +58,105 @@ func (x *dentryEntry) StateLoad(m state.Source) {
m.Load(1, &x.prev)
}
+func (x *deviceFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.deviceFile"
+}
+
+func (x *deviceFile) StateFields() []string {
+ return []string{
+ "inode",
+ "kind",
+ "major",
+ "minor",
+ }
+}
+
+func (x *deviceFile) beforeSave() {}
+
+func (x *deviceFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.kind)
+ m.Save(2, &x.major)
+ m.Save(3, &x.minor)
+}
+
+func (x *deviceFile) afterLoad() {}
+
+func (x *deviceFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.kind)
+ m.Load(2, &x.major)
+ m.Load(3, &x.minor)
+}
+
+func (x *directory) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.directory"
+}
+
+func (x *directory) StateFields() []string {
+ return []string{
+ "dentry",
+ "inode",
+ "childMap",
+ "numChildren",
+ "childList",
+ }
+}
+
+func (x *directory) beforeSave() {}
+
+func (x *directory) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.dentry)
+ m.Save(1, &x.inode)
+ m.Save(2, &x.childMap)
+ m.Save(3, &x.numChildren)
+ m.Save(4, &x.childList)
+}
+
+func (x *directory) afterLoad() {}
+
+func (x *directory) StateLoad(m state.Source) {
+ m.Load(0, &x.dentry)
+ m.Load(1, &x.inode)
+ m.Load(2, &x.childMap)
+ m.Load(3, &x.numChildren)
+ m.Load(4, &x.childList)
+}
+
+func (x *directoryFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.directoryFD"
+}
+
+func (x *directoryFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "DirectoryFileDescriptionDefaultImpl",
+ "iter",
+ "off",
+ }
+}
+
+func (x *directoryFD) beforeSave() {}
+
+func (x *directoryFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Save(2, &x.iter)
+ m.Save(3, &x.off)
+}
+
+func (x *directoryFD) afterLoad() {}
+
+func (x *directoryFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.DirectoryFileDescriptionDefaultImpl)
+ m.Load(2, &x.iter)
+ m.Load(3, &x.off)
+}
+
func (x *inodeRefs) StateTypeName() string {
return "pkg/sentry/fsimpl/tmpfs.inodeRefs"
}
@@ -81,8 +180,379 @@ func (x *inodeRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *namedPipe) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.namedPipe"
+}
+
+func (x *namedPipe) StateFields() []string {
+ return []string{
+ "inode",
+ "pipe",
+ }
+}
+
+func (x *namedPipe) beforeSave() {}
+
+func (x *namedPipe) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.pipe)
+}
+
+func (x *namedPipe) afterLoad() {}
+
+func (x *namedPipe) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.pipe)
+}
+
+func (x *regularFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.regularFile"
+}
+
+func (x *regularFile) StateFields() []string {
+ return []string{
+ "inode",
+ "memFile",
+ "memoryUsageKind",
+ "mappings",
+ "writableMappingPages",
+ "data",
+ "seals",
+ "size",
+ }
+}
+
+func (x *regularFile) beforeSave() {}
+
+func (x *regularFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.memFile)
+ m.Save(2, &x.memoryUsageKind)
+ m.Save(3, &x.mappings)
+ m.Save(4, &x.writableMappingPages)
+ m.Save(5, &x.data)
+ m.Save(6, &x.seals)
+ m.Save(7, &x.size)
+}
+
+func (x *regularFile) afterLoad() {}
+
+func (x *regularFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.memFile)
+ m.Load(2, &x.memoryUsageKind)
+ m.Load(3, &x.mappings)
+ m.Load(4, &x.writableMappingPages)
+ m.Load(5, &x.data)
+ m.Load(6, &x.seals)
+ m.Load(7, &x.size)
+}
+
+func (x *regularFileFD) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.regularFileFD"
+}
+
+func (x *regularFileFD) StateFields() []string {
+ return []string{
+ "fileDescription",
+ "off",
+ }
+}
+
+func (x *regularFileFD) beforeSave() {}
+
+func (x *regularFileFD) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fileDescription)
+ m.Save(1, &x.off)
+}
+
+func (x *regularFileFD) afterLoad() {}
+
+func (x *regularFileFD) StateLoad(m state.Source) {
+ m.Load(0, &x.fileDescription)
+ m.Load(1, &x.off)
+}
+
+func (x *socketFile) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.socketFile"
+}
+
+func (x *socketFile) StateFields() []string {
+ return []string{
+ "inode",
+ "ep",
+ }
+}
+
+func (x *socketFile) beforeSave() {}
+
+func (x *socketFile) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.ep)
+}
+
+func (x *socketFile) afterLoad() {}
+
+func (x *socketFile) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.ep)
+}
+
+func (x *symlink) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.symlink"
+}
+
+func (x *symlink) StateFields() []string {
+ return []string{
+ "inode",
+ "target",
+ }
+}
+
+func (x *symlink) beforeSave() {}
+
+func (x *symlink) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.inode)
+ m.Save(1, &x.target)
+}
+
+func (x *symlink) afterLoad() {}
+
+func (x *symlink) StateLoad(m state.Source) {
+ m.Load(0, &x.inode)
+ m.Load(1, &x.target)
+}
+
+func (x *FilesystemType) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.FilesystemType"
+}
+
+func (x *FilesystemType) StateFields() []string {
+ return []string{}
+}
+
+func (x *FilesystemType) beforeSave() {}
+
+func (x *FilesystemType) StateSave(m state.Sink) {
+ x.beforeSave()
+}
+
+func (x *FilesystemType) afterLoad() {}
+
+func (x *FilesystemType) StateLoad(m state.Source) {
+}
+
+func (x *filesystem) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.filesystem"
+}
+
+func (x *filesystem) StateFields() []string {
+ return []string{
+ "vfsfs",
+ "memFile",
+ "clock",
+ "devMinor",
+ "nextInoMinusOne",
+ }
+}
+
+func (x *filesystem) beforeSave() {}
+
+func (x *filesystem) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfs)
+ m.Save(1, &x.memFile)
+ m.Save(2, &x.clock)
+ m.Save(3, &x.devMinor)
+ m.Save(4, &x.nextInoMinusOne)
+}
+
+func (x *filesystem) afterLoad() {}
+
+func (x *filesystem) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfs)
+ m.Load(1, &x.memFile)
+ m.Load(2, &x.clock)
+ m.Load(3, &x.devMinor)
+ m.Load(4, &x.nextInoMinusOne)
+}
+
+func (x *FilesystemOpts) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.FilesystemOpts"
+}
+
+func (x *FilesystemOpts) StateFields() []string {
+ return []string{
+ "RootFileType",
+ "RootSymlinkTarget",
+ "FilesystemType",
+ }
+}
+
+func (x *FilesystemOpts) beforeSave() {}
+
+func (x *FilesystemOpts) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.RootFileType)
+ m.Save(1, &x.RootSymlinkTarget)
+ m.Save(2, &x.FilesystemType)
+}
+
+func (x *FilesystemOpts) afterLoad() {}
+
+func (x *FilesystemOpts) StateLoad(m state.Source) {
+ m.Load(0, &x.RootFileType)
+ m.Load(1, &x.RootSymlinkTarget)
+ m.Load(2, &x.FilesystemType)
+}
+
+func (x *dentry) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.dentry"
+}
+
+func (x *dentry) StateFields() []string {
+ return []string{
+ "vfsd",
+ "parent",
+ "name",
+ "dentryEntry",
+ "inode",
+ }
+}
+
+func (x *dentry) beforeSave() {}
+
+func (x *dentry) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsd)
+ m.Save(1, &x.parent)
+ m.Save(2, &x.name)
+ m.Save(3, &x.dentryEntry)
+ m.Save(4, &x.inode)
+}
+
+func (x *dentry) afterLoad() {}
+
+func (x *dentry) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsd)
+ m.Load(1, &x.parent)
+ m.Load(2, &x.name)
+ m.Load(3, &x.dentryEntry)
+ m.Load(4, &x.inode)
+}
+
+func (x *inode) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.inode"
+}
+
+func (x *inode) StateFields() []string {
+ return []string{
+ "fs",
+ "refs",
+ "xattrs",
+ "mode",
+ "nlink",
+ "uid",
+ "gid",
+ "ino",
+ "atime",
+ "ctime",
+ "mtime",
+ "locks",
+ "watches",
+ "impl",
+ }
+}
+
+func (x *inode) beforeSave() {}
+
+func (x *inode) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.fs)
+ m.Save(1, &x.refs)
+ m.Save(2, &x.xattrs)
+ m.Save(3, &x.mode)
+ m.Save(4, &x.nlink)
+ m.Save(5, &x.uid)
+ m.Save(6, &x.gid)
+ m.Save(7, &x.ino)
+ m.Save(8, &x.atime)
+ m.Save(9, &x.ctime)
+ m.Save(10, &x.mtime)
+ m.Save(11, &x.locks)
+ m.Save(12, &x.watches)
+ m.Save(13, &x.impl)
+}
+
+func (x *inode) afterLoad() {}
+
+func (x *inode) StateLoad(m state.Source) {
+ m.Load(0, &x.fs)
+ m.Load(1, &x.refs)
+ m.Load(2, &x.xattrs)
+ m.Load(3, &x.mode)
+ m.Load(4, &x.nlink)
+ m.Load(5, &x.uid)
+ m.Load(6, &x.gid)
+ m.Load(7, &x.ino)
+ m.Load(8, &x.atime)
+ m.Load(9, &x.ctime)
+ m.Load(10, &x.mtime)
+ m.Load(11, &x.locks)
+ m.Load(12, &x.watches)
+ m.Load(13, &x.impl)
+}
+
+func (x *fileDescription) StateTypeName() string {
+ return "pkg/sentry/fsimpl/tmpfs.fileDescription"
+}
+
+func (x *fileDescription) StateFields() []string {
+ return []string{
+ "vfsfd",
+ "FileDescriptionDefaultImpl",
+ "LockFD",
+ }
+}
+
+func (x *fileDescription) beforeSave() {}
+
+func (x *fileDescription) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.vfsfd)
+ m.Save(1, &x.FileDescriptionDefaultImpl)
+ m.Save(2, &x.LockFD)
+}
+
+func (x *fileDescription) afterLoad() {}
+
+func (x *fileDescription) StateLoad(m state.Source) {
+ m.Load(0, &x.vfsfd)
+ m.Load(1, &x.FileDescriptionDefaultImpl)
+ m.Load(2, &x.LockFD)
+}
+
func init() {
state.Register((*dentryList)(nil))
state.Register((*dentryEntry)(nil))
+ state.Register((*deviceFile)(nil))
+ state.Register((*directory)(nil))
+ state.Register((*directoryFD)(nil))
state.Register((*inodeRefs)(nil))
+ state.Register((*namedPipe)(nil))
+ state.Register((*regularFile)(nil))
+ state.Register((*regularFileFD)(nil))
+ state.Register((*socketFile)(nil))
+ state.Register((*symlink)(nil))
+ state.Register((*FilesystemType)(nil))
+ state.Register((*filesystem)(nil))
+ state.Register((*FilesystemOpts)(nil))
+ state.Register((*dentry)(nil))
+ state.Register((*inode)(nil))
+ state.Register((*fileDescription)(nil))
}