diff options
Diffstat (limited to 'pkg/sentry/fs/proc')
-rw-r--r-- | pkg/sentry/fs/proc/BUILD | 73 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/README.md | 336 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/device/BUILD | 10 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/device/device_state_autogen.go | 3 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/net_test.go | 74 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/proc_state_autogen.go | 1575 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/seqfile/BUILD | 35 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go | 100 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/seqfile/seqfile_test.go | 279 | ||||
-rw-r--r-- | pkg/sentry/fs/proc/sys_net_test.go | 198 |
10 files changed, 1678 insertions, 1005 deletions
diff --git a/pkg/sentry/fs/proc/BUILD b/pkg/sentry/fs/proc/BUILD deleted file mode 100644 index b8b2281a8..000000000 --- a/pkg/sentry/fs/proc/BUILD +++ /dev/null @@ -1,73 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package(licenses = ["notice"]) - -go_library( - name = "proc", - srcs = [ - "cgroup.go", - "cpuinfo.go", - "exec_args.go", - "fds.go", - "filesystems.go", - "fs.go", - "inode.go", - "loadavg.go", - "meminfo.go", - "mounts.go", - "net.go", - "proc.go", - "stat.go", - "sys.go", - "sys_net.go", - "sys_net_state.go", - "task.go", - "uid_gid_map.go", - "uptime.go", - "version.go", - ], - visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/abi/linux", - "//pkg/context", - "//pkg/log", - "//pkg/sentry/fs", - "//pkg/sentry/fs/fsutil", - "//pkg/sentry/fs/proc/device", - "//pkg/sentry/fs/proc/seqfile", - "//pkg/sentry/fs/ramfs", - "//pkg/sentry/fsbridge", - "//pkg/sentry/inet", - "//pkg/sentry/kernel", - "//pkg/sentry/kernel/auth", - "//pkg/sentry/kernel/time", - "//pkg/sentry/limits", - "//pkg/sentry/mm", - "//pkg/sentry/socket", - "//pkg/sentry/socket/unix", - "//pkg/sentry/socket/unix/transport", - "//pkg/sentry/usage", - "//pkg/sync", - "//pkg/syserror", - "//pkg/tcpip/header", - "//pkg/tcpip/network/ipv4", - "//pkg/usermem", - "//pkg/waiter", - ], -) - -go_test( - name = "proc_test", - size = "small", - srcs = [ - "net_test.go", - "sys_net_test.go", - ], - library = ":proc", - deps = [ - "//pkg/abi/linux", - "//pkg/context", - "//pkg/sentry/inet", - "//pkg/usermem", - ], -) diff --git a/pkg/sentry/fs/proc/README.md b/pkg/sentry/fs/proc/README.md deleted file mode 100644 index 6667a0916..000000000 --- a/pkg/sentry/fs/proc/README.md +++ /dev/null @@ -1,336 +0,0 @@ -This document tracks what is implemented in procfs. Refer to -Documentation/filesystems/proc.txt in the Linux project for information about -procfs generally. - -**NOTE**: This document is not guaranteed to be up to date. If you find an -inconsistency, please file a bug. - -[TOC] - -## Kernel data - -The following files are implemented: - -<!-- mdformat off(don't wrap the table) --> - -| File /proc/ | Content | -| :------------------------ | :---------------------------------------------------- | -| [cpuinfo](#cpuinfo) | Info about the CPU | -| [filesystems](#filesystems) | Supported filesystems | -| [loadavg](#loadavg) | Load average of last 1, 5 & 15 minutes | -| [meminfo](#meminfo) | Overall memory info | -| [stat](#stat) | Overall kernel statistics | -| [sys](#sys) | Change parameters within the kernel | -| [uptime](#uptime) | Wall clock since boot, combined idle time of all cpus | -| [version](#version) | Kernel version | - -<!-- mdformat on --> - -### cpuinfo - -```bash -$ cat /proc/cpuinfo -processor : 0 -vendor_id : GenuineIntel -cpu family : 6 -model : 45 -model name : unknown -stepping : unknown -cpu MHz : 1234.588 -fpu : yes -fpu_exception : yes -cpuid level : 13 -wp : yes -flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx xsaveopt -bogomips : 1234.59 -clflush size : 64 -cache_alignment : 64 -address sizes : 46 bits physical, 48 bits virtual -power management: - -... -``` - -Notable divergences: - -Field name | Notes -:--------------- | :--------------------------------------- -model name | Always unknown -stepping | Always unknown -fpu | Always yes -fpu_exception | Always yes -wp | Always yes -bogomips | Bogus value (matches cpu MHz) -clflush size | Always 64 -cache_alignment | Always 64 -address sizes | Always 46 bits physical, 48 bits virtual -power management | Always blank - -Otherwise fields are derived from the sentry configuration. - -### filesystems - -```bash -$ cat /proc/filesystems -nodev 9p -nodev devpts -nodev devtmpfs -nodev proc -nodev sysfs -nodev tmpfs -``` - -### loadavg - -```bash -$ cat /proc/loadavg -0.00 0.00 0.00 0/0 0 -``` - -Column | Notes -:------------------------------------ | :---------- -CPU.IO utilization in last 1 minute | Always zero -CPU.IO utilization in last 5 minutes | Always zero -CPU.IO utilization in last 10 minutes | Always zero -Num currently running processes | Always zero -Total num processes | Always zero - -TODO(b/62345059): Populate the columns with accurate statistics. - -### meminfo - -```bash -$ cat /proc/meminfo -MemTotal: 2097152 kB -MemFree: 2083540 kB -MemAvailable: 2083540 kB -Buffers: 0 kB -Cached: 4428 kB -SwapCache: 0 kB -Active: 10812 kB -Inactive: 2216 kB -Active(anon): 8600 kB -Inactive(anon): 0 kB -Active(file): 2212 kB -Inactive(file): 2216 kB -Unevictable: 0 kB -Mlocked: 0 kB -SwapTotal: 0 kB -SwapFree: 0 kB -Dirty: 0 kB -Writeback: 0 kB -AnonPages: 8600 kB -Mapped: 4428 kB -Shmem: 0 kB - -``` - -Notable divergences: - -Field name | Notes -:---------------- | :----------------------------------------------------- -Buffers | Always zero, no block devices -SwapCache | Always zero, no swap -Inactive(anon) | Always zero, see SwapCache -Unevictable | Always zero TODO(b/31823263) -Mlocked | Always zero TODO(b/31823263) -SwapTotal | Always zero, no swap -SwapFree | Always zero, no swap -Dirty | Always zero TODO(b/31823263) -Writeback | Always zero TODO(b/31823263) -MemAvailable | Uses the same value as MemFree since there is no swap. -Slab | Missing -SReclaimable | Missing -SUnreclaim | Missing -KernelStack | Missing -PageTables | Missing -NFS_Unstable | Missing -Bounce | Missing -WritebackTmp | Missing -CommitLimit | Missing -Committed_AS | Missing -VmallocTotal | Missing -VmallocUsed | Missing -VmallocChunk | Missing -HardwareCorrupted | Missing -AnonHugePages | Missing -ShmemHugePages | Missing -ShmemPmdMapped | Missing -HugePages_Total | Missing -HugePages_Free | Missing -HugePages_Rsvd | Missing -HugePages_Surp | Missing -Hugepagesize | Missing -DirectMap4k | Missing -DirectMap2M | Missing -DirectMap1G | Missing - -### stat - -```bash -$ cat /proc/stat -cpu 0 0 0 0 0 0 0 0 0 0 -cpu0 0 0 0 0 0 0 0 0 0 0 -cpu1 0 0 0 0 0 0 0 0 0 0 -cpu2 0 0 0 0 0 0 0 0 0 0 -cpu3 0 0 0 0 0 0 0 0 0 0 -cpu4 0 0 0 0 0 0 0 0 0 0 -cpu5 0 0 0 0 0 0 0 0 0 0 -cpu6 0 0 0 0 0 0 0 0 0 0 -cpu7 0 0 0 0 0 0 0 0 0 0 -intr 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -ctxt 0 -btime 1504040968 -processes 0 -procs_running 0 -procs_blokkcked 0 -softirq 0 0 0 0 0 0 0 0 0 0 0 -``` - -All fields except for `btime` are always zero. - -TODO(b/37226836): Populate with accurate fields. - -### sys - -```bash -$ ls /proc/sys -kernel vm -``` - -Directory | Notes -:-------- | :---------------------------- -abi | Missing -debug | Missing -dev | Missing -fs | Missing -kernel | Contains hostname (only) -net | Missing -user | Missing -vm | Contains mmap_min_addr (only) - -### uptime - -```bash -$ cat /proc/uptime -3204.62 0.00 -``` - -Column | Notes -:------------------------------- | :---------------------------- -Total num seconds system running | Time since procfs was mounted -Number of seconds idle | Always zero - -### version - -```bash -$ cat /proc/version -Linux version 4.4 #1 SMP Sun Jan 10 15:06:54 PST 2016 -``` - -## Process-specific data - -The following files are implemented: - -File /proc/PID | Content -:---------------------- | :--------------------------------------------------- -[auxv](#auxv) | Copy of auxiliary vector for the process -[cmdline](#cmdline) | Command line arguments -[comm](#comm) | Command name associated with the process -[environ](#environ) | Process environment -[exe](#exe) | Symlink to the process's executable -[fd](#fd) | Directory containing links to open file descriptors -[fdinfo](#fdinfo) | Information associated with open file descriptors -[gid_map](#gid_map) | Mappings for group IDs inside the user namespace -[io](#io) | IO statistics -[maps](#maps) | Memory mappings (anon, executables, library files) -[mounts](#mounts) | Mounted filesystems -[mountinfo](#mountinfo) | Information about mounts -[ns](#ns) | Directory containing info about supported namespaces -[stat](#stat) | Process statistics -[statm](#statm) | Process memory statistics -[status](#status) | Process status in human readable format -[task](#task) | Directory containing info about running threads -[uid_map](#uid_map) | Mappings for user IDs inside the user namespace - -### auxv - -TODO - -### cmdline - -TODO - -### comm - -TODO - -### environment - -TODO - -### exe - -TODO - -### fd - -TODO - -### fdinfo - -TODO - -### gid_map - -TODO - -### io - -Only has data for rchar, wchar, syscr, and syscw. - -TODO: add more detail. - -### maps - -TODO - -### mounts - -TODO - -### mountinfo - -TODO - -### ns - -TODO - -### stat - -Only has data for pid, comm, state, ppid, utime, stime, cutime, cstime, -num_threads, and exit_signal. - -TODO: add more detail. - -### statm - -Only has data for vss and rss. - -TODO: add more detail. - -### status - -Contains data for Name, State, Tgid, Pid, Ppid, TracerPid, FDSize, VmSize, -VmRSS, Threads, CapInh, CapPrm, CapEff, CapBnd, Seccomp. - -TODO: add more detail. - -### task - -TODO - -### uid_map - -TODO diff --git a/pkg/sentry/fs/proc/device/BUILD b/pkg/sentry/fs/proc/device/BUILD deleted file mode 100644 index 52c9aa93d..000000000 --- a/pkg/sentry/fs/proc/device/BUILD +++ /dev/null @@ -1,10 +0,0 @@ -load("//tools:defs.bzl", "go_library") - -package(licenses = ["notice"]) - -go_library( - name = "device", - srcs = ["device.go"], - visibility = ["//pkg/sentry:internal"], - deps = ["//pkg/sentry/device"], -) diff --git a/pkg/sentry/fs/proc/device/device_state_autogen.go b/pkg/sentry/fs/proc/device/device_state_autogen.go new file mode 100644 index 000000000..4a5e3cc88 --- /dev/null +++ b/pkg/sentry/fs/proc/device/device_state_autogen.go @@ -0,0 +1,3 @@ +// automatically generated by stateify. + +package device diff --git a/pkg/sentry/fs/proc/net_test.go b/pkg/sentry/fs/proc/net_test.go deleted file mode 100644 index f18681405..000000000 --- a/pkg/sentry/fs/proc/net_test.go +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package proc - -import ( - "reflect" - "testing" - - "gvisor.dev/gvisor/pkg/abi/linux" - "gvisor.dev/gvisor/pkg/sentry/inet" -) - -func newIPv6TestStack() *inet.TestStack { - s := inet.NewTestStack() - s.SupportsIPv6Flag = true - return s -} - -func TestIfinet6NoAddresses(t *testing.T) { - n := &ifinet6{s: newIPv6TestStack()} - if got := n.contents(); got != nil { - t.Errorf("Got n.contents() = %v, want = %v", got, nil) - } -} - -func TestIfinet6(t *testing.T) { - s := newIPv6TestStack() - s.InterfacesMap[1] = inet.Interface{Name: "eth0"} - s.InterfaceAddrsMap[1] = []inet.InterfaceAddr{ - { - Family: linux.AF_INET6, - PrefixLen: 128, - Addr: []byte("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"), - }, - } - s.InterfacesMap[2] = inet.Interface{Name: "eth1"} - s.InterfaceAddrsMap[2] = []inet.InterfaceAddr{ - { - Family: linux.AF_INET6, - PrefixLen: 128, - Addr: []byte("\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"), - }, - } - want := map[string]struct{}{ - "000102030405060708090a0b0c0d0e0f 01 80 00 00 eth0\n": {}, - "101112131415161718191a1b1c1d1e1f 02 80 00 00 eth1\n": {}, - } - - n := &ifinet6{s: s} - contents := n.contents() - if len(contents) != len(want) { - t.Errorf("Got len(n.contents()) = %d, want = %d", len(contents), len(want)) - } - got := map[string]struct{}{} - for _, l := range contents { - got[l] = struct{}{} - } - - if !reflect.DeepEqual(got, want) { - t.Errorf("Got n.contents() = %v, want = %v", got, want) - } -} diff --git a/pkg/sentry/fs/proc/proc_state_autogen.go b/pkg/sentry/fs/proc/proc_state_autogen.go new file mode 100644 index 000000000..d39cd1d2e --- /dev/null +++ b/pkg/sentry/fs/proc/proc_state_autogen.go @@ -0,0 +1,1575 @@ +// automatically generated by stateify. + +package proc + +import ( + "gvisor.dev/gvisor/pkg/state" +) + +func (i *execArgInode) StateTypeName() string { + return "pkg/sentry/fs/proc.execArgInode" +} + +func (i *execArgInode) StateFields() []string { + return []string{ + "SimpleFileInode", + "arg", + "t", + } +} + +func (i *execArgInode) beforeSave() {} + +func (i *execArgInode) StateSave(stateSinkObject state.Sink) { + i.beforeSave() + stateSinkObject.Save(0, &i.SimpleFileInode) + stateSinkObject.Save(1, &i.arg) + stateSinkObject.Save(2, &i.t) +} + +func (i *execArgInode) afterLoad() {} + +func (i *execArgInode) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &i.SimpleFileInode) + stateSourceObject.Load(1, &i.arg) + stateSourceObject.Load(2, &i.t) +} + +func (f *execArgFile) StateTypeName() string { + return "pkg/sentry/fs/proc.execArgFile" +} + +func (f *execArgFile) StateFields() []string { + return []string{ + "arg", + "t", + } +} + +func (f *execArgFile) beforeSave() {} + +func (f *execArgFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.arg) + stateSinkObject.Save(1, &f.t) +} + +func (f *execArgFile) afterLoad() {} + +func (f *execArgFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.arg) + stateSourceObject.Load(1, &f.t) +} + +func (f *fdDir) StateTypeName() string { + return "pkg/sentry/fs/proc.fdDir" +} + +func (f *fdDir) StateFields() []string { + return []string{ + "Dir", + "t", + } +} + +func (f *fdDir) beforeSave() {} + +func (f *fdDir) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.Dir) + stateSinkObject.Save(1, &f.t) +} + +func (f *fdDir) afterLoad() {} + +func (f *fdDir) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.Dir) + stateSourceObject.Load(1, &f.t) +} + +func (f *fdDirFile) StateTypeName() string { + return "pkg/sentry/fs/proc.fdDirFile" +} + +func (f *fdDirFile) StateFields() []string { + return []string{ + "isInfoFile", + "t", + } +} + +func (f *fdDirFile) beforeSave() {} + +func (f *fdDirFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.isInfoFile) + stateSinkObject.Save(1, &f.t) +} + +func (f *fdDirFile) afterLoad() {} + +func (f *fdDirFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.isInfoFile) + stateSourceObject.Load(1, &f.t) +} + +func (fdid *fdInfoDir) StateTypeName() string { + return "pkg/sentry/fs/proc.fdInfoDir" +} + +func (fdid *fdInfoDir) StateFields() []string { + return []string{ + "Dir", + "t", + } +} + +func (fdid *fdInfoDir) beforeSave() {} + +func (fdid *fdInfoDir) StateSave(stateSinkObject state.Sink) { + fdid.beforeSave() + stateSinkObject.Save(0, &fdid.Dir) + stateSinkObject.Save(1, &fdid.t) +} + +func (fdid *fdInfoDir) afterLoad() {} + +func (fdid *fdInfoDir) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &fdid.Dir) + stateSourceObject.Load(1, &fdid.t) +} + +func (f *filesystemsData) StateTypeName() string { + return "pkg/sentry/fs/proc.filesystemsData" +} + +func (f *filesystemsData) StateFields() []string { + return []string{} +} + +func (f *filesystemsData) beforeSave() {} + +func (f *filesystemsData) StateSave(stateSinkObject state.Sink) { + f.beforeSave() +} + +func (f *filesystemsData) afterLoad() {} + +func (f *filesystemsData) StateLoad(stateSourceObject state.Source) { +} + +func (f *filesystem) StateTypeName() string { + return "pkg/sentry/fs/proc.filesystem" +} + +func (f *filesystem) StateFields() []string { + return []string{} +} + +func (f *filesystem) beforeSave() {} + +func (f *filesystem) StateSave(stateSinkObject state.Sink) { + f.beforeSave() +} + +func (f *filesystem) afterLoad() {} + +func (f *filesystem) StateLoad(stateSourceObject state.Source) { +} + +func (i *taskOwnedInodeOps) StateTypeName() string { + return "pkg/sentry/fs/proc.taskOwnedInodeOps" +} + +func (i *taskOwnedInodeOps) StateFields() []string { + return []string{ + "InodeOperations", + "t", + } +} + +func (i *taskOwnedInodeOps) beforeSave() {} + +func (i *taskOwnedInodeOps) StateSave(stateSinkObject state.Sink) { + i.beforeSave() + stateSinkObject.Save(0, &i.InodeOperations) + stateSinkObject.Save(1, &i.t) +} + +func (i *taskOwnedInodeOps) afterLoad() {} + +func (i *taskOwnedInodeOps) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &i.InodeOperations) + stateSourceObject.Load(1, &i.t) +} + +func (s *staticFileInodeOps) StateTypeName() string { + return "pkg/sentry/fs/proc.staticFileInodeOps" +} + +func (s *staticFileInodeOps) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeStaticFileGetter", + } +} + +func (s *staticFileInodeOps) beforeSave() {} + +func (s *staticFileInodeOps) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.InodeSimpleAttributes) + stateSinkObject.Save(1, &s.InodeStaticFileGetter) +} + +func (s *staticFileInodeOps) afterLoad() {} + +func (s *staticFileInodeOps) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.InodeSimpleAttributes) + stateSourceObject.Load(1, &s.InodeStaticFileGetter) +} + +func (d *loadavgData) StateTypeName() string { + return "pkg/sentry/fs/proc.loadavgData" +} + +func (d *loadavgData) StateFields() []string { + return []string{} +} + +func (d *loadavgData) beforeSave() {} + +func (d *loadavgData) StateSave(stateSinkObject state.Sink) { + d.beforeSave() +} + +func (d *loadavgData) afterLoad() {} + +func (d *loadavgData) StateLoad(stateSourceObject state.Source) { +} + +func (d *meminfoData) StateTypeName() string { + return "pkg/sentry/fs/proc.meminfoData" +} + +func (d *meminfoData) StateFields() []string { + return []string{ + "k", + } +} + +func (d *meminfoData) beforeSave() {} + +func (d *meminfoData) StateSave(stateSinkObject state.Sink) { + d.beforeSave() + stateSinkObject.Save(0, &d.k) +} + +func (d *meminfoData) afterLoad() {} + +func (d *meminfoData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &d.k) +} + +func (mif *mountInfoFile) StateTypeName() string { + return "pkg/sentry/fs/proc.mountInfoFile" +} + +func (mif *mountInfoFile) StateFields() []string { + return []string{ + "t", + } +} + +func (mif *mountInfoFile) beforeSave() {} + +func (mif *mountInfoFile) StateSave(stateSinkObject state.Sink) { + mif.beforeSave() + stateSinkObject.Save(0, &mif.t) +} + +func (mif *mountInfoFile) afterLoad() {} + +func (mif *mountInfoFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &mif.t) +} + +func (mf *mountsFile) StateTypeName() string { + return "pkg/sentry/fs/proc.mountsFile" +} + +func (mf *mountsFile) StateFields() []string { + return []string{ + "t", + } +} + +func (mf *mountsFile) beforeSave() {} + +func (mf *mountsFile) StateSave(stateSinkObject state.Sink) { + mf.beforeSave() + stateSinkObject.Save(0, &mf.t) +} + +func (mf *mountsFile) afterLoad() {} + +func (mf *mountsFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &mf.t) +} + +func (n *ifinet6) StateTypeName() string { + return "pkg/sentry/fs/proc.ifinet6" +} + +func (n *ifinet6) StateFields() []string { + return []string{ + "s", + } +} + +func (n *ifinet6) beforeSave() {} + +func (n *ifinet6) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.s) +} + +func (n *ifinet6) afterLoad() {} + +func (n *ifinet6) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.s) +} + +func (n *netDev) StateTypeName() string { + return "pkg/sentry/fs/proc.netDev" +} + +func (n *netDev) StateFields() []string { + return []string{ + "s", + } +} + +func (n *netDev) beforeSave() {} + +func (n *netDev) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.s) +} + +func (n *netDev) afterLoad() {} + +func (n *netDev) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.s) +} + +func (n *netSnmp) StateTypeName() string { + return "pkg/sentry/fs/proc.netSnmp" +} + +func (n *netSnmp) StateFields() []string { + return []string{ + "s", + } +} + +func (n *netSnmp) beforeSave() {} + +func (n *netSnmp) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.s) +} + +func (n *netSnmp) afterLoad() {} + +func (n *netSnmp) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.s) +} + +func (n *netRoute) StateTypeName() string { + return "pkg/sentry/fs/proc.netRoute" +} + +func (n *netRoute) StateFields() []string { + return []string{ + "s", + } +} + +func (n *netRoute) beforeSave() {} + +func (n *netRoute) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.s) +} + +func (n *netRoute) afterLoad() {} + +func (n *netRoute) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.s) +} + +func (n *netUnix) StateTypeName() string { + return "pkg/sentry/fs/proc.netUnix" +} + +func (n *netUnix) StateFields() []string { + return []string{ + "k", + } +} + +func (n *netUnix) beforeSave() {} + +func (n *netUnix) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.k) +} + +func (n *netUnix) afterLoad() {} + +func (n *netUnix) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.k) +} + +func (n *netTCP) StateTypeName() string { + return "pkg/sentry/fs/proc.netTCP" +} + +func (n *netTCP) StateFields() []string { + return []string{ + "k", + } +} + +func (n *netTCP) beforeSave() {} + +func (n *netTCP) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.k) +} + +func (n *netTCP) afterLoad() {} + +func (n *netTCP) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.k) +} + +func (n *netTCP6) StateTypeName() string { + return "pkg/sentry/fs/proc.netTCP6" +} + +func (n *netTCP6) StateFields() []string { + return []string{ + "k", + } +} + +func (n *netTCP6) beforeSave() {} + +func (n *netTCP6) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.k) +} + +func (n *netTCP6) afterLoad() {} + +func (n *netTCP6) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.k) +} + +func (n *netUDP) StateTypeName() string { + return "pkg/sentry/fs/proc.netUDP" +} + +func (n *netUDP) StateFields() []string { + return []string{ + "k", + } +} + +func (n *netUDP) beforeSave() {} + +func (n *netUDP) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.k) +} + +func (n *netUDP) afterLoad() {} + +func (n *netUDP) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.k) +} + +func (p *proc) StateTypeName() string { + return "pkg/sentry/fs/proc.proc" +} + +func (p *proc) StateFields() []string { + return []string{ + "Dir", + "k", + "pidns", + "cgroupControllers", + } +} + +func (p *proc) beforeSave() {} + +func (p *proc) StateSave(stateSinkObject state.Sink) { + p.beforeSave() + stateSinkObject.Save(0, &p.Dir) + stateSinkObject.Save(1, &p.k) + stateSinkObject.Save(2, &p.pidns) + stateSinkObject.Save(3, &p.cgroupControllers) +} + +func (p *proc) afterLoad() {} + +func (p *proc) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &p.Dir) + stateSourceObject.Load(1, &p.k) + stateSourceObject.Load(2, &p.pidns) + stateSourceObject.Load(3, &p.cgroupControllers) +} + +func (s *self) StateTypeName() string { + return "pkg/sentry/fs/proc.self" +} + +func (s *self) StateFields() []string { + return []string{ + "Symlink", + "pidns", + } +} + +func (s *self) beforeSave() {} + +func (s *self) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.Symlink) + stateSinkObject.Save(1, &s.pidns) +} + +func (s *self) afterLoad() {} + +func (s *self) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.Symlink) + stateSourceObject.Load(1, &s.pidns) +} + +func (s *threadSelf) StateTypeName() string { + return "pkg/sentry/fs/proc.threadSelf" +} + +func (s *threadSelf) StateFields() []string { + return []string{ + "Symlink", + "pidns", + } +} + +func (s *threadSelf) beforeSave() {} + +func (s *threadSelf) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.Symlink) + stateSinkObject.Save(1, &s.pidns) +} + +func (s *threadSelf) afterLoad() {} + +func (s *threadSelf) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.Symlink) + stateSourceObject.Load(1, &s.pidns) +} + +func (rpf *rootProcFile) StateTypeName() string { + return "pkg/sentry/fs/proc.rootProcFile" +} + +func (rpf *rootProcFile) StateFields() []string { + return []string{ + "iops", + } +} + +func (rpf *rootProcFile) beforeSave() {} + +func (rpf *rootProcFile) StateSave(stateSinkObject state.Sink) { + rpf.beforeSave() + stateSinkObject.Save(0, &rpf.iops) +} + +func (rpf *rootProcFile) afterLoad() {} + +func (rpf *rootProcFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &rpf.iops) +} + +func (s *statData) StateTypeName() string { + return "pkg/sentry/fs/proc.statData" +} + +func (s *statData) StateFields() []string { + return []string{ + "k", + } +} + +func (s *statData) beforeSave() {} + +func (s *statData) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.k) +} + +func (s *statData) afterLoad() {} + +func (s *statData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.k) +} + +func (d *mmapMinAddrData) StateTypeName() string { + return "pkg/sentry/fs/proc.mmapMinAddrData" +} + +func (d *mmapMinAddrData) StateFields() []string { + return []string{ + "k", + } +} + +func (d *mmapMinAddrData) beforeSave() {} + +func (d *mmapMinAddrData) StateSave(stateSinkObject state.Sink) { + d.beforeSave() + stateSinkObject.Save(0, &d.k) +} + +func (d *mmapMinAddrData) afterLoad() {} + +func (d *mmapMinAddrData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &d.k) +} + +func (o *overcommitMemory) StateTypeName() string { + return "pkg/sentry/fs/proc.overcommitMemory" +} + +func (o *overcommitMemory) StateFields() []string { + return []string{} +} + +func (o *overcommitMemory) beforeSave() {} + +func (o *overcommitMemory) StateSave(stateSinkObject state.Sink) { + o.beforeSave() +} + +func (o *overcommitMemory) afterLoad() {} + +func (o *overcommitMemory) StateLoad(stateSourceObject state.Source) { +} + +func (h *hostname) StateTypeName() string { + return "pkg/sentry/fs/proc.hostname" +} + +func (h *hostname) StateFields() []string { + return []string{ + "SimpleFileInode", + } +} + +func (h *hostname) beforeSave() {} + +func (h *hostname) StateSave(stateSinkObject state.Sink) { + h.beforeSave() + stateSinkObject.Save(0, &h.SimpleFileInode) +} + +func (h *hostname) afterLoad() {} + +func (h *hostname) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &h.SimpleFileInode) +} + +func (hf *hostnameFile) StateTypeName() string { + return "pkg/sentry/fs/proc.hostnameFile" +} + +func (hf *hostnameFile) StateFields() []string { + return []string{} +} + +func (hf *hostnameFile) beforeSave() {} + +func (hf *hostnameFile) StateSave(stateSinkObject state.Sink) { + hf.beforeSave() +} + +func (hf *hostnameFile) afterLoad() {} + +func (hf *hostnameFile) StateLoad(stateSourceObject state.Source) { +} + +func (t *tcpMemInode) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpMemInode" +} + +func (t *tcpMemInode) StateFields() []string { + return []string{ + "SimpleFileInode", + "dir", + "s", + "size", + } +} + +func (t *tcpMemInode) StateSave(stateSinkObject state.Sink) { + t.beforeSave() + stateSinkObject.Save(0, &t.SimpleFileInode) + stateSinkObject.Save(1, &t.dir) + stateSinkObject.Save(2, &t.s) + stateSinkObject.Save(3, &t.size) +} + +func (t *tcpMemInode) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &t.SimpleFileInode) + stateSourceObject.Load(1, &t.dir) + stateSourceObject.LoadWait(2, &t.s) + stateSourceObject.Load(3, &t.size) + stateSourceObject.AfterLoad(t.afterLoad) +} + +func (f *tcpMemFile) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpMemFile" +} + +func (f *tcpMemFile) StateFields() []string { + return []string{ + "tcpMemInode", + } +} + +func (f *tcpMemFile) beforeSave() {} + +func (f *tcpMemFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.tcpMemInode) +} + +func (f *tcpMemFile) afterLoad() {} + +func (f *tcpMemFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.tcpMemInode) +} + +func (s *tcpSack) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpSack" +} + +func (s *tcpSack) StateFields() []string { + return []string{ + "SimpleFileInode", + "stack", + "enabled", + } +} + +func (s *tcpSack) beforeSave() {} + +func (s *tcpSack) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.SimpleFileInode) + stateSinkObject.Save(1, &s.stack) + stateSinkObject.Save(2, &s.enabled) +} + +func (s *tcpSack) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.SimpleFileInode) + stateSourceObject.LoadWait(1, &s.stack) + stateSourceObject.Load(2, &s.enabled) + stateSourceObject.AfterLoad(s.afterLoad) +} + +func (f *tcpSackFile) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpSackFile" +} + +func (f *tcpSackFile) StateFields() []string { + return []string{ + "tcpSack", + "stack", + } +} + +func (f *tcpSackFile) beforeSave() {} + +func (f *tcpSackFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.tcpSack) + stateSinkObject.Save(1, &f.stack) +} + +func (f *tcpSackFile) afterLoad() {} + +func (f *tcpSackFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.tcpSack) + stateSourceObject.LoadWait(1, &f.stack) +} + +func (r *tcpRecovery) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpRecovery" +} + +func (r *tcpRecovery) StateFields() []string { + return []string{ + "SimpleFileInode", + "stack", + "recovery", + } +} + +func (r *tcpRecovery) beforeSave() {} + +func (r *tcpRecovery) StateSave(stateSinkObject state.Sink) { + r.beforeSave() + stateSinkObject.Save(0, &r.SimpleFileInode) + stateSinkObject.Save(1, &r.stack) + stateSinkObject.Save(2, &r.recovery) +} + +func (r *tcpRecovery) afterLoad() {} + +func (r *tcpRecovery) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &r.SimpleFileInode) + stateSourceObject.LoadWait(1, &r.stack) + stateSourceObject.Load(2, &r.recovery) +} + +func (f *tcpRecoveryFile) StateTypeName() string { + return "pkg/sentry/fs/proc.tcpRecoveryFile" +} + +func (f *tcpRecoveryFile) StateFields() []string { + return []string{ + "tcpRecovery", + "stack", + } +} + +func (f *tcpRecoveryFile) beforeSave() {} + +func (f *tcpRecoveryFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.tcpRecovery) + stateSinkObject.Save(1, &f.stack) +} + +func (f *tcpRecoveryFile) afterLoad() {} + +func (f *tcpRecoveryFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.tcpRecovery) + stateSourceObject.LoadWait(1, &f.stack) +} + +func (ipf *ipForwarding) StateTypeName() string { + return "pkg/sentry/fs/proc.ipForwarding" +} + +func (ipf *ipForwarding) StateFields() []string { + return []string{ + "SimpleFileInode", + "stack", + "enabled", + } +} + +func (ipf *ipForwarding) beforeSave() {} + +func (ipf *ipForwarding) StateSave(stateSinkObject state.Sink) { + ipf.beforeSave() + stateSinkObject.Save(0, &ipf.SimpleFileInode) + stateSinkObject.Save(1, &ipf.stack) + stateSinkObject.Save(2, &ipf.enabled) +} + +func (ipf *ipForwarding) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &ipf.SimpleFileInode) + stateSourceObject.LoadWait(1, &ipf.stack) + stateSourceObject.Load(2, &ipf.enabled) + stateSourceObject.AfterLoad(ipf.afterLoad) +} + +func (f *ipForwardingFile) StateTypeName() string { + return "pkg/sentry/fs/proc.ipForwardingFile" +} + +func (f *ipForwardingFile) StateFields() []string { + return []string{ + "ipf", + "stack", + } +} + +func (f *ipForwardingFile) beforeSave() {} + +func (f *ipForwardingFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.ipf) + stateSinkObject.Save(1, &f.stack) +} + +func (f *ipForwardingFile) afterLoad() {} + +func (f *ipForwardingFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.ipf) + stateSourceObject.LoadWait(1, &f.stack) +} + +func (t *taskDir) StateTypeName() string { + return "pkg/sentry/fs/proc.taskDir" +} + +func (t *taskDir) StateFields() []string { + return []string{ + "Dir", + "t", + } +} + +func (t *taskDir) beforeSave() {} + +func (t *taskDir) StateSave(stateSinkObject state.Sink) { + t.beforeSave() + stateSinkObject.Save(0, &t.Dir) + stateSinkObject.Save(1, &t.t) +} + +func (t *taskDir) afterLoad() {} + +func (t *taskDir) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &t.Dir) + stateSourceObject.Load(1, &t.t) +} + +func (s *subtasks) StateTypeName() string { + return "pkg/sentry/fs/proc.subtasks" +} + +func (s *subtasks) StateFields() []string { + return []string{ + "Dir", + "t", + "p", + } +} + +func (s *subtasks) beforeSave() {} + +func (s *subtasks) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.Dir) + stateSinkObject.Save(1, &s.t) + stateSinkObject.Save(2, &s.p) +} + +func (s *subtasks) afterLoad() {} + +func (s *subtasks) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.Dir) + stateSourceObject.Load(1, &s.t) + stateSourceObject.Load(2, &s.p) +} + +func (f *subtasksFile) StateTypeName() string { + return "pkg/sentry/fs/proc.subtasksFile" +} + +func (f *subtasksFile) StateFields() []string { + return []string{ + "t", + "pidns", + } +} + +func (f *subtasksFile) beforeSave() {} + +func (f *subtasksFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.t) + stateSinkObject.Save(1, &f.pidns) +} + +func (f *subtasksFile) afterLoad() {} + +func (f *subtasksFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.t) + stateSourceObject.Load(1, &f.pidns) +} + +func (e *exe) StateTypeName() string { + return "pkg/sentry/fs/proc.exe" +} + +func (e *exe) StateFields() []string { + return []string{ + "Symlink", + "t", + } +} + +func (e *exe) beforeSave() {} + +func (e *exe) StateSave(stateSinkObject state.Sink) { + e.beforeSave() + stateSinkObject.Save(0, &e.Symlink) + stateSinkObject.Save(1, &e.t) +} + +func (e *exe) afterLoad() {} + +func (e *exe) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &e.Symlink) + stateSourceObject.Load(1, &e.t) +} + +func (e *cwd) StateTypeName() string { + return "pkg/sentry/fs/proc.cwd" +} + +func (e *cwd) StateFields() []string { + return []string{ + "Symlink", + "t", + } +} + +func (e *cwd) beforeSave() {} + +func (e *cwd) StateSave(stateSinkObject state.Sink) { + e.beforeSave() + stateSinkObject.Save(0, &e.Symlink) + stateSinkObject.Save(1, &e.t) +} + +func (e *cwd) afterLoad() {} + +func (e *cwd) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &e.Symlink) + stateSourceObject.Load(1, &e.t) +} + +func (n *namespaceSymlink) StateTypeName() string { + return "pkg/sentry/fs/proc.namespaceSymlink" +} + +func (n *namespaceSymlink) StateFields() []string { + return []string{ + "Symlink", + "t", + } +} + +func (n *namespaceSymlink) beforeSave() {} + +func (n *namespaceSymlink) StateSave(stateSinkObject state.Sink) { + n.beforeSave() + stateSinkObject.Save(0, &n.Symlink) + stateSinkObject.Save(1, &n.t) +} + +func (n *namespaceSymlink) afterLoad() {} + +func (n *namespaceSymlink) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &n.Symlink) + stateSourceObject.Load(1, &n.t) +} + +func (md *mapsData) StateTypeName() string { + return "pkg/sentry/fs/proc.mapsData" +} + +func (md *mapsData) StateFields() []string { + return []string{ + "t", + } +} + +func (md *mapsData) beforeSave() {} + +func (md *mapsData) StateSave(stateSinkObject state.Sink) { + md.beforeSave() + stateSinkObject.Save(0, &md.t) +} + +func (md *mapsData) afterLoad() {} + +func (md *mapsData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &md.t) +} + +func (sd *smapsData) StateTypeName() string { + return "pkg/sentry/fs/proc.smapsData" +} + +func (sd *smapsData) StateFields() []string { + return []string{ + "t", + } +} + +func (sd *smapsData) beforeSave() {} + +func (sd *smapsData) StateSave(stateSinkObject state.Sink) { + sd.beforeSave() + stateSinkObject.Save(0, &sd.t) +} + +func (sd *smapsData) afterLoad() {} + +func (sd *smapsData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &sd.t) +} + +func (s *taskStatData) StateTypeName() string { + return "pkg/sentry/fs/proc.taskStatData" +} + +func (s *taskStatData) StateFields() []string { + return []string{ + "t", + "tgstats", + "pidns", + } +} + +func (s *taskStatData) beforeSave() {} + +func (s *taskStatData) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.t) + stateSinkObject.Save(1, &s.tgstats) + stateSinkObject.Save(2, &s.pidns) +} + +func (s *taskStatData) afterLoad() {} + +func (s *taskStatData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.t) + stateSourceObject.Load(1, &s.tgstats) + stateSourceObject.Load(2, &s.pidns) +} + +func (s *statmData) StateTypeName() string { + return "pkg/sentry/fs/proc.statmData" +} + +func (s *statmData) StateFields() []string { + return []string{ + "t", + } +} + +func (s *statmData) beforeSave() {} + +func (s *statmData) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.t) +} + +func (s *statmData) afterLoad() {} + +func (s *statmData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.t) +} + +func (s *statusData) StateTypeName() string { + return "pkg/sentry/fs/proc.statusData" +} + +func (s *statusData) StateFields() []string { + return []string{ + "t", + "pidns", + } +} + +func (s *statusData) beforeSave() {} + +func (s *statusData) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.t) + stateSinkObject.Save(1, &s.pidns) +} + +func (s *statusData) afterLoad() {} + +func (s *statusData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.t) + stateSourceObject.Load(1, &s.pidns) +} + +func (i *ioData) StateTypeName() string { + return "pkg/sentry/fs/proc.ioData" +} + +func (i *ioData) StateFields() []string { + return []string{ + "ioUsage", + } +} + +func (i *ioData) beforeSave() {} + +func (i *ioData) StateSave(stateSinkObject state.Sink) { + i.beforeSave() + stateSinkObject.Save(0, &i.ioUsage) +} + +func (i *ioData) afterLoad() {} + +func (i *ioData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &i.ioUsage) +} + +func (c *comm) StateTypeName() string { + return "pkg/sentry/fs/proc.comm" +} + +func (c *comm) StateFields() []string { + return []string{ + "SimpleFileInode", + "t", + } +} + +func (c *comm) beforeSave() {} + +func (c *comm) StateSave(stateSinkObject state.Sink) { + c.beforeSave() + stateSinkObject.Save(0, &c.SimpleFileInode) + stateSinkObject.Save(1, &c.t) +} + +func (c *comm) afterLoad() {} + +func (c *comm) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &c.SimpleFileInode) + stateSourceObject.Load(1, &c.t) +} + +func (f *commFile) StateTypeName() string { + return "pkg/sentry/fs/proc.commFile" +} + +func (f *commFile) StateFields() []string { + return []string{ + "t", + } +} + +func (f *commFile) beforeSave() {} + +func (f *commFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.t) +} + +func (f *commFile) afterLoad() {} + +func (f *commFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.t) +} + +func (a *auxvec) StateTypeName() string { + return "pkg/sentry/fs/proc.auxvec" +} + +func (a *auxvec) StateFields() []string { + return []string{ + "SimpleFileInode", + "t", + } +} + +func (a *auxvec) beforeSave() {} + +func (a *auxvec) StateSave(stateSinkObject state.Sink) { + a.beforeSave() + stateSinkObject.Save(0, &a.SimpleFileInode) + stateSinkObject.Save(1, &a.t) +} + +func (a *auxvec) afterLoad() {} + +func (a *auxvec) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &a.SimpleFileInode) + stateSourceObject.Load(1, &a.t) +} + +func (f *auxvecFile) StateTypeName() string { + return "pkg/sentry/fs/proc.auxvecFile" +} + +func (f *auxvecFile) StateFields() []string { + return []string{ + "t", + } +} + +func (f *auxvecFile) beforeSave() {} + +func (f *auxvecFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.t) +} + +func (f *auxvecFile) afterLoad() {} + +func (f *auxvecFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.t) +} + +func (o *oomScoreAdj) StateTypeName() string { + return "pkg/sentry/fs/proc.oomScoreAdj" +} + +func (o *oomScoreAdj) StateFields() []string { + return []string{ + "SimpleFileInode", + "t", + } +} + +func (o *oomScoreAdj) beforeSave() {} + +func (o *oomScoreAdj) StateSave(stateSinkObject state.Sink) { + o.beforeSave() + stateSinkObject.Save(0, &o.SimpleFileInode) + stateSinkObject.Save(1, &o.t) +} + +func (o *oomScoreAdj) afterLoad() {} + +func (o *oomScoreAdj) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &o.SimpleFileInode) + stateSourceObject.Load(1, &o.t) +} + +func (f *oomScoreAdjFile) StateTypeName() string { + return "pkg/sentry/fs/proc.oomScoreAdjFile" +} + +func (f *oomScoreAdjFile) StateFields() []string { + return []string{ + "t", + } +} + +func (f *oomScoreAdjFile) beforeSave() {} + +func (f *oomScoreAdjFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.t) +} + +func (f *oomScoreAdjFile) afterLoad() {} + +func (f *oomScoreAdjFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.t) +} + +func (imio *idMapInodeOperations) StateTypeName() string { + return "pkg/sentry/fs/proc.idMapInodeOperations" +} + +func (imio *idMapInodeOperations) StateFields() []string { + return []string{ + "InodeSimpleAttributes", + "InodeSimpleExtendedAttributes", + "t", + "gids", + } +} + +func (imio *idMapInodeOperations) beforeSave() {} + +func (imio *idMapInodeOperations) StateSave(stateSinkObject state.Sink) { + imio.beforeSave() + stateSinkObject.Save(0, &imio.InodeSimpleAttributes) + stateSinkObject.Save(1, &imio.InodeSimpleExtendedAttributes) + stateSinkObject.Save(2, &imio.t) + stateSinkObject.Save(3, &imio.gids) +} + +func (imio *idMapInodeOperations) afterLoad() {} + +func (imio *idMapInodeOperations) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &imio.InodeSimpleAttributes) + stateSourceObject.Load(1, &imio.InodeSimpleExtendedAttributes) + stateSourceObject.Load(2, &imio.t) + stateSourceObject.Load(3, &imio.gids) +} + +func (imfo *idMapFileOperations) StateTypeName() string { + return "pkg/sentry/fs/proc.idMapFileOperations" +} + +func (imfo *idMapFileOperations) StateFields() []string { + return []string{ + "iops", + } +} + +func (imfo *idMapFileOperations) beforeSave() {} + +func (imfo *idMapFileOperations) StateSave(stateSinkObject state.Sink) { + imfo.beforeSave() + stateSinkObject.Save(0, &imfo.iops) +} + +func (imfo *idMapFileOperations) afterLoad() {} + +func (imfo *idMapFileOperations) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &imfo.iops) +} + +func (u *uptime) StateTypeName() string { + return "pkg/sentry/fs/proc.uptime" +} + +func (u *uptime) StateFields() []string { + return []string{ + "SimpleFileInode", + "startTime", + } +} + +func (u *uptime) beforeSave() {} + +func (u *uptime) StateSave(stateSinkObject state.Sink) { + u.beforeSave() + stateSinkObject.Save(0, &u.SimpleFileInode) + stateSinkObject.Save(1, &u.startTime) +} + +func (u *uptime) afterLoad() {} + +func (u *uptime) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &u.SimpleFileInode) + stateSourceObject.Load(1, &u.startTime) +} + +func (f *uptimeFile) StateTypeName() string { + return "pkg/sentry/fs/proc.uptimeFile" +} + +func (f *uptimeFile) StateFields() []string { + return []string{ + "startTime", + } +} + +func (f *uptimeFile) beforeSave() {} + +func (f *uptimeFile) StateSave(stateSinkObject state.Sink) { + f.beforeSave() + stateSinkObject.Save(0, &f.startTime) +} + +func (f *uptimeFile) afterLoad() {} + +func (f *uptimeFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &f.startTime) +} + +func (v *versionData) StateTypeName() string { + return "pkg/sentry/fs/proc.versionData" +} + +func (v *versionData) StateFields() []string { + return []string{ + "k", + } +} + +func (v *versionData) beforeSave() {} + +func (v *versionData) StateSave(stateSinkObject state.Sink) { + v.beforeSave() + stateSinkObject.Save(0, &v.k) +} + +func (v *versionData) afterLoad() {} + +func (v *versionData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &v.k) +} + +func init() { + state.Register((*execArgInode)(nil)) + state.Register((*execArgFile)(nil)) + state.Register((*fdDir)(nil)) + state.Register((*fdDirFile)(nil)) + state.Register((*fdInfoDir)(nil)) + state.Register((*filesystemsData)(nil)) + state.Register((*filesystem)(nil)) + state.Register((*taskOwnedInodeOps)(nil)) + state.Register((*staticFileInodeOps)(nil)) + state.Register((*loadavgData)(nil)) + state.Register((*meminfoData)(nil)) + state.Register((*mountInfoFile)(nil)) + state.Register((*mountsFile)(nil)) + state.Register((*ifinet6)(nil)) + state.Register((*netDev)(nil)) + state.Register((*netSnmp)(nil)) + state.Register((*netRoute)(nil)) + state.Register((*netUnix)(nil)) + state.Register((*netTCP)(nil)) + state.Register((*netTCP6)(nil)) + state.Register((*netUDP)(nil)) + state.Register((*proc)(nil)) + state.Register((*self)(nil)) + state.Register((*threadSelf)(nil)) + state.Register((*rootProcFile)(nil)) + state.Register((*statData)(nil)) + state.Register((*mmapMinAddrData)(nil)) + state.Register((*overcommitMemory)(nil)) + state.Register((*hostname)(nil)) + state.Register((*hostnameFile)(nil)) + state.Register((*tcpMemInode)(nil)) + state.Register((*tcpMemFile)(nil)) + state.Register((*tcpSack)(nil)) + state.Register((*tcpSackFile)(nil)) + state.Register((*tcpRecovery)(nil)) + state.Register((*tcpRecoveryFile)(nil)) + state.Register((*ipForwarding)(nil)) + state.Register((*ipForwardingFile)(nil)) + state.Register((*taskDir)(nil)) + state.Register((*subtasks)(nil)) + state.Register((*subtasksFile)(nil)) + state.Register((*exe)(nil)) + state.Register((*cwd)(nil)) + state.Register((*namespaceSymlink)(nil)) + state.Register((*mapsData)(nil)) + state.Register((*smapsData)(nil)) + state.Register((*taskStatData)(nil)) + state.Register((*statmData)(nil)) + state.Register((*statusData)(nil)) + state.Register((*ioData)(nil)) + state.Register((*comm)(nil)) + state.Register((*commFile)(nil)) + state.Register((*auxvec)(nil)) + state.Register((*auxvecFile)(nil)) + state.Register((*oomScoreAdj)(nil)) + state.Register((*oomScoreAdjFile)(nil)) + state.Register((*idMapInodeOperations)(nil)) + state.Register((*idMapFileOperations)(nil)) + state.Register((*uptime)(nil)) + state.Register((*uptimeFile)(nil)) + state.Register((*versionData)(nil)) +} diff --git a/pkg/sentry/fs/proc/seqfile/BUILD b/pkg/sentry/fs/proc/seqfile/BUILD deleted file mode 100644 index 21338d912..000000000 --- a/pkg/sentry/fs/proc/seqfile/BUILD +++ /dev/null @@ -1,35 +0,0 @@ -load("//tools:defs.bzl", "go_library", "go_test") - -package(licenses = ["notice"]) - -go_library( - name = "seqfile", - srcs = ["seqfile.go"], - visibility = ["//pkg/sentry:internal"], - deps = [ - "//pkg/abi/linux", - "//pkg/context", - "//pkg/sentry/fs", - "//pkg/sentry/fs/fsutil", - "//pkg/sentry/fs/proc/device", - "//pkg/sentry/kernel/time", - "//pkg/sync", - "//pkg/syserror", - "//pkg/usermem", - "//pkg/waiter", - ], -) - -go_test( - name = "seqfile_test", - size = "small", - srcs = ["seqfile_test.go"], - library = ":seqfile", - deps = [ - "//pkg/context", - "//pkg/sentry/contexttest", - "//pkg/sentry/fs", - "//pkg/sentry/fs/ramfs", - "//pkg/usermem", - ], -) diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go b/pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go new file mode 100644 index 000000000..ab08bbaa3 --- /dev/null +++ b/pkg/sentry/fs/proc/seqfile/seqfile_state_autogen.go @@ -0,0 +1,100 @@ +// automatically generated by stateify. + +package seqfile + +import ( + "gvisor.dev/gvisor/pkg/state" +) + +func (s *SeqData) StateTypeName() string { + return "pkg/sentry/fs/proc/seqfile.SeqData" +} + +func (s *SeqData) StateFields() []string { + return []string{ + "Buf", + "Handle", + } +} + +func (s *SeqData) beforeSave() {} + +func (s *SeqData) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.Buf) + stateSinkObject.Save(1, &s.Handle) +} + +func (s *SeqData) afterLoad() {} + +func (s *SeqData) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.Buf) + stateSourceObject.Load(1, &s.Handle) +} + +func (s *SeqFile) StateTypeName() string { + return "pkg/sentry/fs/proc/seqfile.SeqFile" +} + +func (s *SeqFile) StateFields() []string { + return []string{ + "InodeSimpleExtendedAttributes", + "InodeSimpleAttributes", + "SeqSource", + "source", + "generation", + "lastRead", + } +} + +func (s *SeqFile) beforeSave() {} + +func (s *SeqFile) StateSave(stateSinkObject state.Sink) { + s.beforeSave() + stateSinkObject.Save(0, &s.InodeSimpleExtendedAttributes) + stateSinkObject.Save(1, &s.InodeSimpleAttributes) + stateSinkObject.Save(2, &s.SeqSource) + stateSinkObject.Save(3, &s.source) + stateSinkObject.Save(4, &s.generation) + stateSinkObject.Save(5, &s.lastRead) +} + +func (s *SeqFile) afterLoad() {} + +func (s *SeqFile) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &s.InodeSimpleExtendedAttributes) + stateSourceObject.Load(1, &s.InodeSimpleAttributes) + stateSourceObject.Load(2, &s.SeqSource) + stateSourceObject.Load(3, &s.source) + stateSourceObject.Load(4, &s.generation) + stateSourceObject.Load(5, &s.lastRead) +} + +func (sfo *seqFileOperations) StateTypeName() string { + return "pkg/sentry/fs/proc/seqfile.seqFileOperations" +} + +func (sfo *seqFileOperations) StateFields() []string { + return []string{ + "seqFile", + } +} + +func (sfo *seqFileOperations) beforeSave() {} + +func (sfo *seqFileOperations) StateSave(stateSinkObject state.Sink) { + sfo.beforeSave() + stateSinkObject.Save(0, &sfo.seqFile) +} + +func (sfo *seqFileOperations) afterLoad() {} + +func (sfo *seqFileOperations) StateLoad(stateSourceObject state.Source) { + stateSourceObject.Load(0, &sfo.seqFile) +} + +func init() { + state.Register((*SeqData)(nil)) + state.Register((*SeqFile)(nil)) + state.Register((*seqFileOperations)(nil)) +} diff --git a/pkg/sentry/fs/proc/seqfile/seqfile_test.go b/pkg/sentry/fs/proc/seqfile/seqfile_test.go deleted file mode 100644 index 98e394569..000000000 --- a/pkg/sentry/fs/proc/seqfile/seqfile_test.go +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package seqfile - -import ( - "bytes" - "fmt" - "io" - "testing" - - "gvisor.dev/gvisor/pkg/context" - "gvisor.dev/gvisor/pkg/sentry/contexttest" - "gvisor.dev/gvisor/pkg/sentry/fs" - "gvisor.dev/gvisor/pkg/sentry/fs/ramfs" - "gvisor.dev/gvisor/pkg/usermem" -) - -type seqTest struct { - actual []SeqData - update bool -} - -func (s *seqTest) Init() { - var sq []SeqData - // Create some SeqData. - for i := 0; i < 10; i++ { - var b []byte - for j := 0; j < 10; j++ { - b = append(b, byte(i)) - } - sq = append(sq, SeqData{ - Buf: b, - Handle: &testHandle{i: i}, - }) - } - s.actual = sq -} - -// NeedsUpdate reports whether we need to update the data we've previously read. -func (s *seqTest) NeedsUpdate(int64) bool { - return s.update -} - -// ReadSeqFiledata returns a slice of SeqData which contains elements -// greater than the handle. -func (s *seqTest) ReadSeqFileData(ctx context.Context, handle SeqHandle) ([]SeqData, int64) { - if handle == nil { - return s.actual, 0 - } - h := *handle.(*testHandle) - var ret []SeqData - for _, b := range s.actual { - // We want the next one. - h2 := *b.Handle.(*testHandle) - if h2.i > h.i { - ret = append(ret, b) - } - } - return ret, 0 -} - -// Flatten a slice of slices into one slice. -func flatten(buf ...[]byte) []byte { - var flat []byte - for _, b := range buf { - flat = append(flat, b...) - } - return flat -} - -type testHandle struct { - i int -} - -type testTable struct { - offset int64 - readBufferSize int - expectedData []byte - expectedError error -} - -func runTableTests(ctx context.Context, table []testTable, dirent *fs.Dirent) error { - for _, tt := range table { - file, err := dirent.Inode.InodeOperations.GetFile(ctx, dirent, fs.FileFlags{Read: true}) - if err != nil { - return fmt.Errorf("GetFile returned error: %v", err) - } - - data := make([]byte, tt.readBufferSize) - resultLen, err := file.Preadv(ctx, usermem.BytesIOSequence(data), tt.offset) - if err != tt.expectedError { - return fmt.Errorf("t.Preadv(len: %v, offset: %v) (error) => %v expected %v", tt.readBufferSize, tt.offset, err, tt.expectedError) - } - expectedLen := int64(len(tt.expectedData)) - if resultLen != expectedLen { - // We make this just an error so we wall through and print the data below. - return fmt.Errorf("t.Preadv(len: %v, offset: %v) (size) => %v expected %v", tt.readBufferSize, tt.offset, resultLen, expectedLen) - } - if !bytes.Equal(data[:expectedLen], tt.expectedData) { - return fmt.Errorf("t.Preadv(len: %v, offset: %v) (data) => %v expected %v", tt.readBufferSize, tt.offset, data[:expectedLen], tt.expectedData) - } - } - return nil -} - -func TestSeqFile(t *testing.T) { - testSource := &seqTest{} - testSource.Init() - - // Create a file that can be R/W. - ctx := contexttest.Context(t) - m := fs.NewPseudoMountSource(ctx) - contents := map[string]*fs.Inode{ - "foo": NewSeqFileInode(ctx, testSource, m), - } - root := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0777)) - - // How about opening it? - inode := fs.NewInode(ctx, root, m, fs.StableAttr{Type: fs.Directory}) - dirent2, err := root.Lookup(ctx, inode, "foo") - if err != nil { - t.Fatalf("failed to walk to foo for n2: %v", err) - } - n2 := dirent2.Inode.InodeOperations - file2, err := n2.GetFile(ctx, dirent2, fs.FileFlags{Read: true, Write: true}) - if err != nil { - t.Fatalf("GetFile returned error: %v", err) - } - - // Writing? - if _, err := file2.Writev(ctx, usermem.BytesIOSequence([]byte("test"))); err == nil { - t.Fatalf("managed to write to n2: %v", err) - } - - // How about reading? - dirent3, err := root.Lookup(ctx, inode, "foo") - if err != nil { - t.Fatalf("failed to walk to foo: %v", err) - } - n3 := dirent3.Inode.InodeOperations - if n2 != n3 { - t.Error("got n2 != n3, want same") - } - - testSource.update = true - - table := []testTable{ - // Read past the end. - {100, 4, []byte{}, io.EOF}, - {110, 4, []byte{}, io.EOF}, - {200, 4, []byte{}, io.EOF}, - // Read a truncated first line. - {0, 4, testSource.actual[0].Buf[:4], nil}, - // Read the whole first line. - {0, 10, testSource.actual[0].Buf, nil}, - // Read the whole first line + 5 bytes of second line. - {0, 15, flatten(testSource.actual[0].Buf, testSource.actual[1].Buf[:5]), nil}, - // First 4 bytes of the second line. - {10, 4, testSource.actual[1].Buf[:4], nil}, - // Read the two first lines. - {0, 20, flatten(testSource.actual[0].Buf, testSource.actual[1].Buf), nil}, - // Read three lines. - {0, 30, flatten(testSource.actual[0].Buf, testSource.actual[1].Buf, testSource.actual[2].Buf), nil}, - // Read everything, but use a bigger buffer than necessary. - {0, 150, flatten(testSource.actual[0].Buf, testSource.actual[1].Buf, testSource.actual[2].Buf, testSource.actual[3].Buf, testSource.actual[4].Buf, testSource.actual[5].Buf, testSource.actual[6].Buf, testSource.actual[7].Buf, testSource.actual[8].Buf, testSource.actual[9].Buf), nil}, - // Read the last 3 bytes. - {97, 10, testSource.actual[9].Buf[7:], nil}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed with testSource.update = %v : %v", testSource.update, err) - } - - // Disable updates and do it again. - testSource.update = false - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed with testSource.update = %v: %v", testSource.update, err) - } -} - -// Test that we behave correctly when the file is updated. -func TestSeqFileFileUpdated(t *testing.T) { - testSource := &seqTest{} - testSource.Init() - testSource.update = true - - // Create a file that can be R/W. - ctx := contexttest.Context(t) - m := fs.NewPseudoMountSource(ctx) - contents := map[string]*fs.Inode{ - "foo": NewSeqFileInode(ctx, testSource, m), - } - root := ramfs.NewDir(ctx, contents, fs.RootOwner, fs.FilePermsFromMode(0777)) - - // How about opening it? - inode := fs.NewInode(ctx, root, m, fs.StableAttr{Type: fs.Directory}) - dirent2, err := root.Lookup(ctx, inode, "foo") - if err != nil { - t.Fatalf("failed to walk to foo for dirent2: %v", err) - } - - table := []testTable{ - {0, 16, flatten(testSource.actual[0].Buf, testSource.actual[1].Buf[:6]), nil}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed: %v", err) - } - // Delete the first entry. - cut := testSource.actual[0].Buf - testSource.actual = testSource.actual[1:] - - table = []testTable{ - // Try reading buffer 0 with an offset. This will not delete the old data. - {1, 5, cut[1:6], nil}, - // Reset our file by reading at offset 0. - {0, 10, testSource.actual[0].Buf, nil}, - {16, 14, flatten(testSource.actual[1].Buf[6:], testSource.actual[2].Buf), nil}, - // Read the same data a second time. - {16, 14, flatten(testSource.actual[1].Buf[6:], testSource.actual[2].Buf), nil}, - // Read the following two lines. - {30, 20, flatten(testSource.actual[3].Buf, testSource.actual[4].Buf), nil}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed after removing first entry: %v", err) - } - - // Add a new duplicate line in the middle (6666...) - after := testSource.actual[5:] - testSource.actual = testSource.actual[:4] - // Note the list must be sorted. - testSource.actual = append(testSource.actual, after[0]) - testSource.actual = append(testSource.actual, after...) - - table = []testTable{ - {50, 20, flatten(testSource.actual[4].Buf, testSource.actual[5].Buf), nil}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed after adding middle entry: %v", err) - } - // This will be used in a later test. - oldTestData := testSource.actual - - // Delete everything. - testSource.actual = testSource.actual[:0] - table = []testTable{ - {20, 20, []byte{}, io.EOF}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed after removing all entries: %v", err) - } - // Restore some of the data. - testSource.actual = oldTestData[:1] - table = []testTable{ - {6, 20, testSource.actual[0].Buf[6:], nil}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed after adding first entry back: %v", err) - } - - // Re-extend the data - testSource.actual = oldTestData - table = []testTable{ - {30, 20, flatten(testSource.actual[3].Buf, testSource.actual[4].Buf), nil}, - } - if err := runTableTests(ctx, table, dirent2); err != nil { - t.Errorf("runTableTest failed after extending testSource: %v", err) - } -} diff --git a/pkg/sentry/fs/proc/sys_net_test.go b/pkg/sentry/fs/proc/sys_net_test.go deleted file mode 100644 index 6ef5738e7..000000000 --- a/pkg/sentry/fs/proc/sys_net_test.go +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright 2018 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package proc - -import ( - "testing" - - "gvisor.dev/gvisor/pkg/context" - "gvisor.dev/gvisor/pkg/sentry/inet" - "gvisor.dev/gvisor/pkg/usermem" -) - -func TestQuerySendBufferSize(t *testing.T) { - ctx := context.Background() - s := inet.NewTestStack() - s.TCPSendBufSize = inet.TCPBufferSize{100, 200, 300} - tmi := &tcpMemInode{s: s, dir: tcpWMem} - tmf := &tcpMemFile{tcpMemInode: tmi} - - buf := make([]byte, 100) - dst := usermem.BytesIOSequence(buf) - n, err := tmf.Read(ctx, nil, dst, 0) - if err != nil { - t.Fatalf("Read failed: %v", err) - } - - if got, want := string(buf[:n]), "100\t200\t300\n"; got != want { - t.Fatalf("Bad string: got %v, want %v", got, want) - } -} - -func TestQueryRecvBufferSize(t *testing.T) { - ctx := context.Background() - s := inet.NewTestStack() - s.TCPRecvBufSize = inet.TCPBufferSize{100, 200, 300} - tmi := &tcpMemInode{s: s, dir: tcpRMem} - tmf := &tcpMemFile{tcpMemInode: tmi} - - buf := make([]byte, 100) - dst := usermem.BytesIOSequence(buf) - n, err := tmf.Read(ctx, nil, dst, 0) - if err != nil { - t.Fatalf("Read failed: %v", err) - } - - if got, want := string(buf[:n]), "100\t200\t300\n"; got != want { - t.Fatalf("Bad string: got %v, want %v", got, want) - } -} - -var cases = []struct { - str string - initial inet.TCPBufferSize - final inet.TCPBufferSize -}{ - { - str: "", - initial: inet.TCPBufferSize{1, 2, 3}, - final: inet.TCPBufferSize{1, 2, 3}, - }, - { - str: "100\n", - initial: inet.TCPBufferSize{1, 100, 200}, - final: inet.TCPBufferSize{100, 100, 200}, - }, - { - str: "100 200 300\n", - initial: inet.TCPBufferSize{1, 2, 3}, - final: inet.TCPBufferSize{100, 200, 300}, - }, -} - -func TestConfigureSendBufferSize(t *testing.T) { - ctx := context.Background() - s := inet.NewTestStack() - for _, c := range cases { - s.TCPSendBufSize = c.initial - tmi := &tcpMemInode{s: s, dir: tcpWMem} - tmf := &tcpMemFile{tcpMemInode: tmi} - - // Write the values. - src := usermem.BytesIOSequence([]byte(c.str)) - if n, err := tmf.Write(ctx, nil, src, 0); n != int64(len(c.str)) || err != nil { - t.Errorf("Write, case = %q: got (%d, %v), wanted (%d, nil)", c.str, n, err, len(c.str)) - } - - // Read the values from the stack and check them. - if s.TCPSendBufSize != c.final { - t.Errorf("TCPSendBufferSize, case = %q: got %v, wanted %v", c.str, s.TCPSendBufSize, c.final) - } - } -} - -func TestConfigureRecvBufferSize(t *testing.T) { - ctx := context.Background() - s := inet.NewTestStack() - for _, c := range cases { - s.TCPRecvBufSize = c.initial - tmi := &tcpMemInode{s: s, dir: tcpRMem} - tmf := &tcpMemFile{tcpMemInode: tmi} - - // Write the values. - src := usermem.BytesIOSequence([]byte(c.str)) - if n, err := tmf.Write(ctx, nil, src, 0); n != int64(len(c.str)) || err != nil { - t.Errorf("Write, case = %q: got (%d, %v), wanted (%d, nil)", c.str, n, err, len(c.str)) - } - - // Read the values from the stack and check them. - if s.TCPRecvBufSize != c.final { - t.Errorf("TCPRecvBufferSize, case = %q: got %v, wanted %v", c.str, s.TCPRecvBufSize, c.final) - } - } -} - -// TestIPForwarding tests the implementation of -// /proc/sys/net/ipv4/ip_forwarding -func TestIPForwarding(t *testing.T) { - ctx := context.Background() - s := inet.NewTestStack() - - var cases = []struct { - comment string - initial bool - str string - final bool - }{ - { - comment: `Forwarding is disabled; write 1 and enable forwarding`, - initial: false, - str: "1", - final: true, - }, - { - comment: `Forwarding is disabled; write 0 and disable forwarding`, - initial: false, - str: "0", - final: false, - }, - { - comment: `Forwarding is enabled; write 1 and enable forwarding`, - initial: true, - str: "1", - final: true, - }, - { - comment: `Forwarding is enabled; write 0 and disable forwarding`, - initial: true, - str: "0", - final: false, - }, - { - comment: `Forwarding is disabled; write 2404 and enable forwarding`, - initial: false, - str: "2404", - final: true, - }, - { - comment: `Forwarding is enabled; write 2404 and enable forwarding`, - initial: true, - str: "2404", - final: true, - }, - } - for _, c := range cases { - t.Run(c.comment, func(t *testing.T) { - s.IPForwarding = c.initial - ipf := &ipForwarding{stack: s} - file := &ipForwardingFile{ - stack: s, - ipf: ipf, - } - - // Write the values. - src := usermem.BytesIOSequence([]byte(c.str)) - if n, err := file.Write(ctx, nil, src, 0); n != int64(len(c.str)) || err != nil { - t.Errorf("file.Write(ctx, nil, %q, 0) = (%d, %v); want (%d, nil)", c.str, n, err, len(c.str)) - } - - // Read the values from the stack and check them. - if got, want := s.IPForwarding, c.final; got != want { - t.Errorf("s.IPForwarding incorrect; got: %v, want: %v", got, want) - } - - }) - } -} |